Make robots drop self and show configuration in tooltip.
This commit is contained in:
@@ -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<ITextComponent> tooltip, final ITooltipFlag advanced) {
|
||||
super.addInformation(stack, world, tooltip, advanced);
|
||||
AbstractVirtualMachineItemStackHandlers.addInformation(stack, tooltip);
|
||||
TooltipUtils.addTileEntityInventoryInformation(stack, tooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<ItemStack> 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);
|
||||
|
||||
@@ -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<ITextComponent> 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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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<ItemEntity> spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack) {
|
||||
|
||||
@@ -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<List<ItemStack>> ITEM_STACKS = ThreadLocal.withInitial(ArrayList::new);
|
||||
private static final ThreadLocal<IntList> ITEM_STACKS_SIZES = ThreadLocal.withInitial(IntArrayList::new);
|
||||
|
||||
public static void addInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip) {
|
||||
addInventoryInformation(stack, tooltip, new String[0]);
|
||||
public static void addTileEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip) {
|
||||
addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip);
|
||||
}
|
||||
|
||||
public static void addInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip, final String... itemHandlerTags) {
|
||||
final CompoundNBT itemHandlerNbt = ItemStackUtils.getTileEntityInventoryTag(stack);
|
||||
if (itemHandlerNbt != null) {
|
||||
final List<ItemStack> itemStacks = ITEM_STACKS.get();
|
||||
itemStacks.clear();
|
||||
final IntList itemStackSizes = ITEM_STACKS_SIZES.get();
|
||||
itemStackSizes.clear();
|
||||
public static void addTileEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> tooltip, final String... subInventoryNames) {
|
||||
addInventoryInformation(ItemStackUtils.getTileEntityInventoryTag(stack), tooltip, subInventoryNames);
|
||||
}
|
||||
|
||||
collectItemStacks(itemHandlerNbt, itemStacks, itemStackSizes);
|
||||
public static void addEntityInventoryInformation(final ItemStack stack, final List<ITextComponent> 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<ITextComponent> tooltip, final String... subInventoryNames) {
|
||||
addInventoryInformation(ItemStackUtils.getEntityInventoryTag(stack), tooltip, subInventoryNames);
|
||||
}
|
||||
|
||||
public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List<ITextComponent> tooltip) {
|
||||
addInventoryInformation(inventoryTag, tooltip, getDeviceTypeNames());
|
||||
}
|
||||
|
||||
public static void addInventoryInformation(@Nullable final CompoundNBT inventoryTag, final List<ITextComponent> tooltip, final String... subInventoryNames) {
|
||||
if (inventoryTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ItemStack> 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<DeviceType> 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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ITextComponent> tooltip) {
|
||||
final ForgeRegistry<DeviceType> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user