package de.ellpeck.naturesaura.items; import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.multiblock.IMultiblock; import de.ellpeck.naturesaura.blocks.multi.Multiblock; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; import java.util.ArrayList; import java.util.List; public class ItemMultiblockMaker extends ItemImpl { private static List multiblocks; public ItemMultiblockMaker() { super("multiblock_maker"); } @Override public InteractionResultHolder use(Level levelIn, Player playerIn, InteractionHand handIn) { var stack = playerIn.getItemInHand(handIn); if (!levelIn.isClientSide && playerIn.isCreative()) { var curr = getMultiblockId(stack); var next = (curr + 1) % multiblocks().size(); stack.getOrCreateTag().putInt("multiblock", next); } return new InteractionResultHolder<>(InteractionResult.SUCCESS, stack); } @Override public InteractionResult useOn(UseOnContext context) { var player = context.getPlayer(); if (player.isCreative()) { var multi = getMultiblock(player.getItemInHand(context.getHand())); if (multi == null) return InteractionResult.PASS; if (!context.getLevel().isClientSide) multi.forEach(context.getClickedPos().above(), (char) 0, (blockPos, matcher) -> { context.getLevel().setBlockAndUpdate(blockPos, matcher.defaultState()); return true; }); return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public Component getName(ItemStack stack) { var name = (MutableComponent) super.getName(stack); var multi = getMultiblock(stack); return multi == null ? name : name.append(" (" + multi.getName() + ")"); } private static List multiblocks() { if (multiblocks == null) { // some weird mixins call getName way too early, before multiblocks are initialized if (NaturesAuraAPI.MULTIBLOCKS.isEmpty()) return null; multiblocks = new ArrayList<>(); multiblocks.addAll(NaturesAuraAPI.MULTIBLOCKS.values()); } return multiblocks; } private static int getMultiblockId(ItemStack stack) { if (!stack.hasTag()) return -1; return stack.getTag().getInt("multiblock"); } private static IMultiblock getMultiblock(ItemStack stack) { var multiblocks = multiblocks(); if (multiblocks == null) return null; var id = getMultiblockId(stack); if (id < 0 || id >= multiblocks.size()) return null; return multiblocks.get(id); } }