From 2e8cca3b0eda69caaa7df08a1c960dc866b74ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 15 Jan 2021 15:46:19 +0100 Subject: [PATCH] Make robots drop self and show configuration in tooltip. --- .../cil/oc2/common/block/ComputerBlock.java | 4 +- .../li/cil/oc2/common/entity/RobotEntity.java | 52 +++++++++--- .../li/cil/oc2/common/item/RobotItem.java | 21 ++++- .../common/tileentity/ComputerTileEntity.java | 3 +- .../cil/oc2/common/util/ItemStackUtils.java | 38 ++++++--- .../li/cil/oc2/common/util/TooltipUtils.java | 79 +++++++++++++------ ...stractVirtualMachineItemStackHandlers.java | 25 +----- 7 files changed, 145 insertions(+), 77 deletions(-) diff --git a/src/main/java/li/cil/oc2/common/block/ComputerBlock.java b/src/main/java/li/cil/oc2/common/block/ComputerBlock.java index 2eb700c0..501f3183 100644 --- a/src/main/java/li/cil/oc2/common/block/ComputerBlock.java +++ b/src/main/java/li/cil/oc2/common/block/ComputerBlock.java @@ -8,8 +8,8 @@ import li.cil.oc2.common.integration.Wrenches; import li.cil.oc2.common.item.Items; import li.cil.oc2.common.tileentity.ComputerTileEntity; import li.cil.oc2.common.tileentity.TileEntities; +import li.cil.oc2.common.util.TooltipUtils; import li.cil.oc2.common.util.VoxelShapeUtils; -import li.cil.oc2.common.vm.AbstractVirtualMachineItemStackHandlers; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.HorizontalBlock; @@ -76,7 +76,7 @@ public final class ComputerBlock extends HorizontalBlock { @Override public void addInformation(final ItemStack stack, @Nullable final IBlockReader world, final List tooltip, final ITooltipFlag advanced) { super.addInformation(stack, world, tooltip, advanced); - AbstractVirtualMachineItemStackHandlers.addInformation(stack, tooltip); + TooltipUtils.addTileEntityInventoryInformation(stack, tooltip); } @Override diff --git a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java index 9f2612e9..262f755f 100644 --- a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java +++ b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java @@ -15,9 +15,11 @@ import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import li.cil.oc2.common.container.RobotContainer; import li.cil.oc2.common.entity.robot.*; import li.cil.oc2.common.integration.Wrenches; +import li.cil.oc2.common.item.Items; import li.cil.oc2.common.network.Network; import li.cil.oc2.common.network.message.*; import li.cil.oc2.common.serialization.NBTSerialization; +import li.cil.oc2.common.util.ItemStackUtils; import li.cil.oc2.common.util.NBTTagIds; import li.cil.oc2.common.util.NBTUtils; import li.cil.oc2.common.util.WorldUtils; @@ -154,6 +156,19 @@ public final class RobotEntity extends Entity { state.stop(); } + public void dropSelf() { + if (!isAlive()) { + return; + } + + final ItemStack stack = new ItemStack(Items.ROBOT_ITEM.get()); + exportToItemStack(stack); + entityDropItem(stack); + + remove(); + WorldUtils.playSound(world, getPosition(), SoundType.METAL, SoundType::getBreakSound); + } + @Override public void tick() { final World world = getEntityWorld(); @@ -199,10 +214,11 @@ public final class RobotEntity extends Entity { final TileEntity tileEntity = blockState.hasTileEntity() ? world.getTileEntity(mutablePosition) : null; final LootContext.Builder builder = new LootContext.Builder((ServerWorld) world) .withRandom(world.rand) - .withParameter(LootParameters.field_237457_g_, Vector3d.copyCentered(mutablePosition)) + .withParameter(LootParameters.THIS_ENTITY, this) + .withParameter(LootParameters.field_237457_g_, getPositionVec()) .withParameter(LootParameters.TOOL, ItemStack.EMPTY) - .withNullableParameter(LootParameters.BLOCK_ENTITY, tileEntity) - .withNullableParameter(LootParameters.THIS_ENTITY, this); + .withParameter(LootParameters.BLOCK_STATE, blockState) + .withNullableParameter(LootParameters.BLOCK_ENTITY, tileEntity); final List drops = blockState.getDrops(builder); world.setBlockState(mutablePosition, Blocks.AIR.getDefaultState(), 3); for (final ItemStack drop : drops) { @@ -213,22 +229,13 @@ public final class RobotEntity extends Entity { } } - private CubeCoordinateIterator getBlockPosIterator() { - final AxisAlignedBB bounds = getBoundingBox(); - return new CubeCoordinateIterator( - MathHelper.floor(bounds.minX), MathHelper.floor(bounds.minY), MathHelper.floor(bounds.minZ), - MathHelper.floor(bounds.maxX), MathHelper.floor(bounds.maxY), MathHelper.floor(bounds.maxZ) - ); - } - @Override public ActionResultType processInitialInteract(final PlayerEntity player, final Hand hand) { final ItemStack stack = player.getHeldItem(hand); if (Wrenches.isWrench(stack)) { if (!world.isRemote() && player instanceof ServerPlayerEntity) { if (player.isSneaking()) { - remove(); - WorldUtils.playSound(world, getPosition(), SoundType.METAL, SoundType::getBreakSound); + dropSelf(); } else { openContainerScreen(player); } @@ -285,6 +292,17 @@ public final class RobotEntity extends Entity { return false; } + public void exportToItemStack(final ItemStack stack) { + items.serialize(ItemStackUtils.getOrCreateEntityInventoryTag(stack)); + } + + public void importFromItemStack(final ItemStack stack) { + final CompoundNBT inventoryTag = ItemStackUtils.getEntityInventoryTag(stack); + if (inventoryTag != null) { + items.deserialize(inventoryTag); + } + } + /////////////////////////////////////////////////////////////////// @Override @@ -393,6 +411,14 @@ public final class RobotEntity extends Entity { }, b -> b.writeVarInt(getEntityId())); } + private CubeCoordinateIterator getBlockPosIterator() { + final AxisAlignedBB bounds = getBoundingBox(); + return new CubeCoordinateIterator( + MathHelper.floor(bounds.minX), MathHelper.floor(bounds.minY), MathHelper.floor(bounds.minZ), + MathHelper.floor(bounds.maxX), MathHelper.floor(bounds.maxY), MathHelper.floor(bounds.maxZ) + ); + } + private static float lerpClamped(final float from, final float to, final float delta) { if (from < to) { return Math.min(from + delta, to); diff --git a/src/main/java/li/cil/oc2/common/item/RobotItem.java b/src/main/java/li/cil/oc2/common/item/RobotItem.java index c948e8f4..36430167 100644 --- a/src/main/java/li/cil/oc2/common/item/RobotItem.java +++ b/src/main/java/li/cil/oc2/common/item/RobotItem.java @@ -3,23 +3,36 @@ package li.cil.oc2.common.item; import li.cil.oc2.common.entity.Entities; import li.cil.oc2.common.entity.RobotEntity; import li.cil.oc2.common.entity.robot.RobotActions; +import li.cil.oc2.common.util.TooltipUtils; import li.cil.oc2.common.util.WorldUtils; import net.minecraft.block.SoundType; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.stats.Stats; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.ITextComponent; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.util.List; public final class RobotItem extends Item { public RobotItem(final Properties properties) { super(properties); } + @Override + public void addInformation(final ItemStack stack, @Nullable final World world, final List tooltip, final ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + TooltipUtils.addEntityInventoryInformation(stack, tooltip); + } + @Override public ActionResultType onItemUse(final ItemUseContext context) { final World world = context.getWorld(); @@ -39,11 +52,13 @@ public final class RobotItem extends Item { return super.onItemUse(context); } - RobotActions.initializeData(robot); - if (!world.isRemote()) { - WorldUtils.playSound(world, new BlockPos(position), SoundType.METAL, SoundType::getPlaceSound); + RobotActions.initializeData(robot); + robot.importFromItemStack(context.getItem()); + world.addEntity(robot); + WorldUtils.playSound(world, new BlockPos(position), SoundType.METAL, SoundType::getPlaceSound); + if (!context.getPlayer().isCreative()) { context.getItem().shrink(1); } diff --git a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java index 575a4457..db8de2d1 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/ComputerTileEntity.java @@ -20,6 +20,7 @@ import li.cil.oc2.common.network.message.ComputerRunStateMessage; import li.cil.oc2.common.network.message.ComputerTerminalOutputMessage; import li.cil.oc2.common.serialization.NBTSerialization; import li.cil.oc2.common.util.HorizontalBlockUtils; +import li.cil.oc2.common.util.ItemStackUtils; import li.cil.oc2.common.util.NBTTagIds; import li.cil.oc2.common.vm.*; import net.minecraft.block.BlockState; @@ -219,7 +220,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic } public void exportToItemStack(final ItemStack stack) { - items.exportToItemStack(stack); + items.serialize(ItemStackUtils.getOrCreateTileEntityInventoryTag(stack)); } /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java b/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java index 09d4cd44..3ed85ca7 100644 --- a/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java +++ b/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java @@ -13,8 +13,8 @@ import javax.annotation.Nullable; import java.util.Optional; import java.util.Random; -import static li.cil.oc2.common.Constants.INVENTORY_TAG_NAME; import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM; +import static li.cil.oc2.common.Constants.INVENTORY_TAG_NAME; public final class ItemStackUtils { private static final String MOD_TAG_NAME = API.MOD_ID; @@ -36,6 +36,22 @@ public final class ItemStackUtils { return stack.getOrCreateChildTag(MOD_TAG_NAME); } + @Nullable + public static CompoundNBT getInventoryTag(@Nullable final CompoundNBT tag) { + return tag != null && tag.contains(INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND) + ? tag.getCompound(INVENTORY_TAG_NAME) : null; + } + + public static CompoundNBT getOrCreateInventoryTag(final CompoundNBT tag) { + if (tag.contains(INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) { + return tag.getCompound(INVENTORY_TAG_NAME); + } + + final CompoundNBT inventoryTag = new CompoundNBT(); + tag.put(INVENTORY_TAG_NAME, inventoryTag); + return inventoryTag; + } + @Nullable public static CompoundNBT getTileEntityTag(final ItemStack stack) { return stack.getChildTag(BLOCK_ENTITY_TAG_NAME_IN_ITEM); @@ -47,22 +63,22 @@ public final class ItemStackUtils { @Nullable public static CompoundNBT getTileEntityInventoryTag(final ItemStack stack) { - final CompoundNBT tag = getTileEntityTag(stack); - return tag != null && tag.contains(INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND) - ? tag.getCompound(INVENTORY_TAG_NAME) : null; + return getInventoryTag(getTileEntityTag(stack)); } @Nullable public static CompoundNBT getOrCreateTileEntityInventoryTag(final ItemStack stack) { - final CompoundNBT tag = getOrCreateTileEntityTag(stack); - if (tag.contains(INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) { - return tag.getCompound(INVENTORY_TAG_NAME); - } + return getOrCreateInventoryTag(getOrCreateTileEntityTag(stack)); + } - final CompoundNBT inventoryNbt = new CompoundNBT(); - tag.put(INVENTORY_TAG_NAME, inventoryNbt); + @Nullable + public static CompoundNBT getEntityInventoryTag(final ItemStack stack) { + return getInventoryTag(getModDataTag(stack)); + } - return inventoryNbt; + @Nullable + public static CompoundNBT getOrCreateEntityInventoryTag(final ItemStack stack) { + return getOrCreateInventoryTag(getOrCreateModDataTag(stack)); } public static Optional spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack) { diff --git a/src/main/java/li/cil/oc2/common/util/TooltipUtils.java b/src/main/java/li/cil/oc2/common/util/TooltipUtils.java index 7a44eea7..23cbb156 100644 --- a/src/main/java/li/cil/oc2/common/util/TooltipUtils.java +++ b/src/main/java/li/cil/oc2/common/util/TooltipUtils.java @@ -2,6 +2,7 @@ package li.cil.oc2.common.util; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import li.cil.oc2.api.bus.device.DeviceType; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; @@ -9,7 +10,10 @@ import net.minecraft.util.text.Color; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.RegistryManager; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; @@ -17,36 +21,63 @@ public final class TooltipUtils { private static final ThreadLocal> ITEM_STACKS = ThreadLocal.withInitial(ArrayList::new); private static final ThreadLocal ITEM_STACKS_SIZES = ThreadLocal.withInitial(IntArrayList::new); - public static void addInventoryInformation(final ItemStack stack, final List tooltip) { - addInventoryInformation(stack, tooltip, new String[0]); + public static void addTileEntityInventoryInformation(final ItemStack stack, final List tooltip) { + addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip); } - public static void addInventoryInformation(final ItemStack stack, final List tooltip, final String... itemHandlerTags) { - final CompoundNBT itemHandlerNbt = ItemStackUtils.getTileEntityInventoryTag(stack); - if (itemHandlerNbt != null) { - final List itemStacks = ITEM_STACKS.get(); - itemStacks.clear(); - final IntList itemStackSizes = ITEM_STACKS_SIZES.get(); - itemStackSizes.clear(); + public static void addTileEntityInventoryInformation(final ItemStack stack, final List tooltip, final String... subInventoryNames) { + addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip, subInventoryNames); + } - collectItemStacks(itemHandlerNbt, itemStacks, itemStackSizes); + public static void addEntityInventoryInformation(final ItemStack stack, final List tooltip) { + addInventoryInformation(ItemStackUtils.getEntityInventoryTag(stack), tooltip); + } - for (final String itemHandlerTagName : itemHandlerTags) { - if (itemHandlerNbt.contains(itemHandlerTagName, NBTTagIds.TAG_COMPOUND)) { - collectItemStacks(itemHandlerNbt.getCompound(itemHandlerTagName), itemStacks, itemStackSizes); - } + public static void addEntityInventoryInformation(final ItemStack stack, final List tooltip, final String... subInventoryNames) { + addInventoryInformation(ItemStackUtils.getEntityInventoryTag(stack), tooltip, subInventoryNames); + } + + public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List tooltip) { + addInventoryInformation(inventoryTag, tooltip, getDeviceTypeNames()); + } + + public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List tooltip, final String... subInventoryNames) { + if (inventoryTag == null) { + return; + } + + final List itemStacks = ITEM_STACKS.get(); + itemStacks.clear(); + final IntList itemStackSizes = ITEM_STACKS_SIZES.get(); + itemStackSizes.clear(); + + collectItemStacks(inventoryTag, itemStacks, itemStackSizes); + + for (final String subInventoryName : subInventoryNames) { + if (inventoryTag.contains(subInventoryName, NBTTagIds.TAG_COMPOUND)) { + collectItemStacks(inventoryTag.getCompound(subInventoryName), itemStacks, itemStackSizes); } + } - for (int i = 0; i < itemStacks.size(); i++) { - final ItemStack itemStack = itemStacks.get(i); - tooltip.add(new StringTextComponent("") - .append(itemStack.getDisplayName()) - .modifyStyle(style -> style.setColor(Color.fromTextFormatting(TextFormatting.GRAY))) - .append(new StringTextComponent(" x") - .appendString(String.valueOf(itemStackSizes.getInt(i))) - .modifyStyle(style -> style.setColor(Color.fromTextFormatting(TextFormatting.DARK_GRAY)))) - ); - } + for (int i = 0; i < itemStacks.size(); i++) { + final ItemStack itemStack = itemStacks.get(i); + tooltip.add(new StringTextComponent("") + .append(itemStack.getDisplayName()) + .modifyStyle(style -> style.setColor(Color.fromTextFormatting(TextFormatting.GRAY))) + .append(new StringTextComponent(" x") + .appendString(String.valueOf(itemStackSizes.getInt(i))) + .modifyStyle(style -> style.setColor(Color.fromTextFormatting(TextFormatting.DARK_GRAY)))) + ); + } + } + + private static String[] getDeviceTypeNames() { + final ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(DeviceType.REGISTRY); + if (registry != null) { + return registry.getValues().stream().map(deviceType -> + deviceType.getRegistryName().toString()).toArray(String[]::new); + } else { + return new String[0]; } } diff --git a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java index 18a8524b..10bfc1e2 100644 --- a/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java +++ b/src/main/java/li/cil/oc2/common/vm/AbstractVirtualMachineItemStackHandlers.java @@ -8,17 +8,12 @@ import li.cil.oc2.common.bus.AbstractDeviceBusElement; import li.cil.oc2.common.bus.device.util.ItemDeviceInfo; import li.cil.oc2.common.container.DeviceItemStackHandler; import li.cil.oc2.common.container.TypedDeviceItemStackHandler; -import li.cil.oc2.common.util.ItemStackUtils; -import li.cil.oc2.common.util.TooltipUtils; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.text.ITextComponent; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.wrapper.CombinedInvWrapper; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.RegistryManager; import java.util.*; import java.util.function.Function; @@ -46,17 +41,6 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual /////////////////////////////////////////////////////////////////// - public static void addInformation(final ItemStack stack, final List tooltip) { - final ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(DeviceType.REGISTRY); - if (registry != null) { - TooltipUtils.addInventoryInformation(stack, tooltip, - registry.getValues().stream().map(deviceType -> - deviceType.getRegistryName().toString()).toArray(String[]::new)); - } - } - - /////////////////////////////////////////////////////////////////// - public final DeviceBusElement busElement = new BusElement(); // NB: linked hash map such that order of parameters in constructor is retained. @@ -128,19 +112,14 @@ public abstract class AbstractVirtualMachineItemStackHandlers implements Virtual } } - public void exportToItemStack(final ItemStack stack) { - final CompoundNBT tag = ItemStackUtils.getOrCreateTileEntityInventoryTag(stack); - + public void serialize(final CompoundNBT tag) { itemHandlers.forEach((deviceType, handler) -> tag.put(deviceType.getRegistryName().toString(), handler.serializeNBT())); } public CompoundNBT serialize() { final CompoundNBT tag = new CompoundNBT(); - - itemHandlers.forEach((deviceType, handler) -> - tag.put(deviceType.getRegistryName().toString(), handler.serializeNBT())); - + serialize(tag); return tag; }