Jump to content

Recommended Posts

Posted (edited)

 

Hi,

I am creating a custom entity that has two inventory slots, much like a vanilla MC horse. I was told in a previous post:

 

On 7/25/2019 at 10:02 AM, diesieben07 said:

Do not use IInventory. Use IItemHandler as a capability on your entity.

 

I have attempted using ItemStackHandler, which implements IItemHandler, but am experiencing difficulty accessing the contents of my inventory.

Here is a small rundown of the issue:

Suppose I enter my world and equip my entity with a saddle and diamond horse armor. The first slot (slot #0) holds the saddle and the second slot (slot #1) holds the armor. When I save and quit my world, this is written to my log:

[09:48:16.477] [Server thread/INFO] [minecraft/MinecraftServer]: Stopping server
[09:48:16.478] [Server thread/INFO] [minecraft/MinecraftServer]: Saving players
[09:48:16.478] [Server thread/INFO] [minecraft/MinecraftServer]: Saving worlds
[09:48:16.478] [Server thread/INFO] [minecraft/MinecraftServer]: Saving chunks for level 'New World'/minecraft:overworld
[09:48:16.485] [Server thread/INFO] [co.em.wh.WhenPigsFly/]: Wrote inventory: 
[09:48:16.485] [Server thread/INFO] [co.em.wh.WhenPigsFly/]: [0]: minecraft:saddle
[09:48:16.485] [Server thread/INFO] [co.em.wh.WhenPigsFly/]: [1]: minecraft:diamond_horse_armor

When I reenter this same world, this is written to my log:

[09:49:33.820] [Server thread/INFO] [minecraft/MinecraftServer]: Preparing start region for dimension minecraft:overworld
[09:49:34.129] [Client thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 0%
[09:49:34.247] [Server thread/INFO] [co.em.wh.WhenPigsFly/]: Found inventory: 
[09:49:34.247] [Server thread/INFO] [co.em.wh.WhenPigsFly/]: [0]: minecraft:saddle
[09:49:34.247] [Server thread/INFO] [co.em.wh.WhenPigsFly/]: [1]: minecraft:diamond_horse_armor
[09:49:34.563] [Client thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 91%
[09:49:34.831] [Client thread/INFO] [minecraft/LoggingChunkStatusListener]: Preparing spawn area: 93%

Surely, I thought, my inventory is being written and read correctly, but alas,

!chest.getStackInSlot(0).isEmpty();
!getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElseThrow(NullPointerException::new).getStackInSlot(0).isEmpty();

always return false, indicating that my entity is not saddled. When I call

WhenPigsFly.LOGGER.info(chest.getStackInSlot(0).getItem().getRegistryName());

I get minecraft:air. Can anyone enlighten me on what I could be doing wrong?

 

I have attached my entity's code below:

public abstract class AbstractRideableEntity extends AnimalEntity {
    private static List<Item> saddleItems = SaddleItems.getSaddleItems();
    private static List<Item> armorItems = ArmorItems.getArmorItems();
    private ItemStackHandler chest;

    // Constructor
    protected AbstractRideableEntity(EntityType<? extends AbstractRideableEntity> type, World world) {
        super(type, world);
        chest = new ItemStackHandler(2){
            @Override
            public boolean isItemValid(int slot, @Nonnull ItemStack itemStack) {
                if (slot == 0) {
                    return saddleItems.contains(itemStack.getItem());
                } else if (slot == 1) {
                    return armorItems.contains(itemStack.getItem());
                } else {
                    throw new Error("Unsupported slot");
                }
            }
            @Override
            public int getSlotLimit(int slot) {
                return 1;
            }
        };
    }

    // Attributes
    protected void registerAttributes() {
        super.registerAttributes();
        getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(53.0D);
        getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue((double) 0.225F);
    }

    // Read chest from NBT
    @Override
    public void readAdditional(CompoundNBT compound) {
        super.readAdditional(compound);
        if (compound.contains("Chest")){
            chest.deserializeNBT(compound.getCompound("Chest"));
        }
        WhenPigsFly.LOGGER.info("Found inventory: ");
        WhenPigsFly.LOGGER.info("[0]: " + chest.getStackInSlot(0).getItem().getRegistryName());
        WhenPigsFly.LOGGER.info("[1]: " + chest.getStackInSlot(1).getItem().getRegistryName());
    }

    // Write chest to NBT
    @Override
    public void writeAdditional(CompoundNBT compound) {
        super.writeAdditional(compound);
        compound.put("Chest", chest.serializeNBT());
        WhenPigsFly.LOGGER.info("Wrote inventory: ");
        WhenPigsFly.LOGGER.info("[0]: " + chest.getStackInSlot(0).getItem().getRegistryName());
        WhenPigsFly.LOGGER.info("[1]: " + chest.getStackInSlot(1).getItem().getRegistryName());
    }

    // Get capability
    @Override
    @Nonnull
    public <T> LazyOptional<T> getCapability(@Nullable Capability<T> capability, @Nullable Direction facing) {
        if (isAlive() && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
            return LazyOptional.of(() -> chest).cast();
        return super.getCapability(capability, facing);
    }

    public boolean isSaddled() {
        WhenPigsFly.LOGGER.info("Saddled: " + chest.getStackInSlot(0).getItem().getRegistryName());
        return !chest.getStackInSlot(0).isEmpty();
    }

    public boolean isArmored() {
        WhenPigsFly.LOGGER.info("Armored: " + !chest.getStackInSlot(1).isEmpty());
        return !chest.getStackInSlot(0).isEmpty();
    }

    private void equipSaddle(ItemStack saddle) {
        if (saddleItems.contains(saddle.getItem())) {
            chest.insertItem(0, saddle, false);
        } else {
            throw new Error("Attempted to saddle pig with unsupported item.");
        }
    }

    private void equipArmor(ItemStack armor) {
        if (armorItems.contains(armor.getItem())) {
            chest.insertItem(1, armor, false);
        } else {
            throw new Error("Attempted to armor pig with unsupported item.");
        }
    }

    public Item getArmor() {
        if (isArmored()) {
            return getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElseThrow(NullPointerException::new).getStackInSlot(1).getItem();
        } else {
            return null;
        }
    }

    private void openGUI(PlayerEntity playerEntity) {
        int id = getEntityId();
        if (!world.isRemote) {
            WhenPigsFly.LOGGER.info("Attempting to open container...");
            NetworkHooks.openGui((ServerPlayerEntity) playerEntity, new INamedContainerProvider() {
                @Override
                @Nonnull
                public ITextComponent getDisplayName() {
                    return new StringTextComponent(Integer.toString(id));
                }

                @Override
                public Container createMenu(int i, @Nonnull PlayerInventory playerInventory, @Nonnull PlayerEntity playerEntity) {
                    WhenPigsFly.LOGGER.info("Creating menu...");
                    return new MyContainer(i, playerInventory, id);
                }
            }, buf -> buf.writeInt(id));
        } else {
            WhenPigsFly.LOGGER.info("Cannot open GUI; world is remote.");
        }
    }

    public boolean canBeLeashedTo(PlayerEntity player) {
        return super.canBeLeashedTo(player) && getCreatureAttribute() != CreatureAttribute.UNDEAD;
    }

    public boolean canBePushed() {
        return !isBeingRidden();
    }

    public boolean processInteract(PlayerEntity player, @Nonnull Hand hand) {
        // Get held item
        ItemStack itemstack = player.getHeldItem(hand);

        // Do nothing
        if (!itemstack.isEmpty() && itemstack.getItem() instanceof SpawnEggItem || !isChild() && isBeingRidden()) {
            WhenPigsFly.LOGGER.info("Nothing happened.");
            return super.processInteract(player, hand);
        }
        // Open GUI
        if (!isChild() && player.isSneaking()) {
            WhenPigsFly.LOGGER.info("Opened GUI.");
            openGUI(player);
            return true;
        }
        // Apply entity-item interaction
        if (!itemstack.isEmpty() && itemstack.interactWithEntity(player, this, hand)) {
            WhenPigsFly.LOGGER.info("Some other interaction");
            return true;
        }
        // Equip saddle
        if (!itemstack.isEmpty() && !isChild() && !isSaddled() && saddleItems.contains(itemstack.getItem())) {
            WhenPigsFly.LOGGER.info("Equipped saddle.");
            equipSaddle(itemstack);
            if (!player.isCreative()) {
                itemstack.shrink(1);
            }
            return true;
        }
        // Equip armor
        if (!itemstack.isEmpty() && !isChild() && !isArmored() && armorItems.contains(itemstack.getItem())) {
            WhenPigsFly.LOGGER.info("Equipped armor.");
            equipArmor(itemstack);
            if (!player.isCreative()) {
                itemstack.shrink(1);
            }
            return true;
        }
        // Attempt to age up child entity
        if (isChild()) {
            WhenPigsFly.LOGGER.info("Interacted with child entity.");
            return super.processInteract(player, hand);
        }
        // Start riding on the pig
        else {
            WhenPigsFly.LOGGER.info("Mounted entity.");
            mountTo(player);
            return false;
        }
    }

    private void mountTo(PlayerEntity player) {
        if (!world.isRemote) {
            player.rotationYaw = rotationYaw;
            player.rotationPitch = rotationPitch;
            player.startRiding(this);
        }

    }

    // No babby
    public AgeableEntity createChild(@Nullable AgeableEntity entity) {
        return null;
    }
}

 

Edited by eafooe
clarification

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.