Jump to content

[1.15.2] Custom Entity Container/Gui Not Interactable


GnRSlashSP

Recommended Posts

On 6/15/2020 at 5:22 AM, diesieben07 said:

Implement IContainerFactory on your container factory, not ContainerType.IFactory. Then you get the PacketBuffer you wrote to when using NetworkHooks.openGui.

Hi

 

I am doing the same thing here (custom entity inventory) and I got lost when you said this.

I didn't find any mention about (SiegeContainerFactory and SiegeScreenFactory) inside classes at first post

 

My code is working except that client does not have itemstacks syncronized (it is empty).

By the way, these are important parts of my mod

 

Can anybody help me please?

Thank you

†GnR† Slash

 

DeadPlayerContainer:

package com.gnrdevand.inventoryplus.inventory;

import com.gnrdevand.inventoryplus.entities.DeadPlayerEntity;
import com.gnrdevand.inventoryplus.init.ContainerTypes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

import javax.annotation.Nullable;
import java.awt.*;

public class DeadPlayerContainer extends Container {
    private static final String[] ARMOR_SLOT_TEXTURES = new String[]{"item/empty_armor_slot_boots", "item/empty_armor_slot_leggings", "item/empty_armor_slot_chestplate", "item/empty_armor_slot_helmet"};
    private static final EquipmentSlotType[] VALID_EQUIPMENT_SLOTS = new EquipmentSlotType[]{EquipmentSlotType.HEAD, EquipmentSlotType.CHEST, EquipmentSlotType.LEGS, EquipmentSlotType.FEET};
    private final Point firstArmorSlot = new Point(8, 8);
    private final Point firstInvSlot = new Point(44, 9);

    private final Point firstPlayerArmorSlot = new Point(8, 98);
    private final Point firstPlayerInvSlot = new Point(44, 98);

    private final PlayerInventory playerInventory;
    private final DeadPlayerEntity deadPlayerEntity;

    private int ctSlotIndex;
    private int firstArmorSlotIndex;
    private int firstOffHandSlotIndex;
    private int firstMainSlotIndex;
    private int firstMainHandSlotIndex;
    private int firstPlayerArmorSlotIndex;
    private int firstPlayerOffHandPSlotIndex;
    private int firstPlayerMainPSlotIndex;
    private int firstPlayerMainHandSlotIndex;

    public DeadPlayerContainer(int containerId, PlayerInventory playerInv, PacketBuffer buffer) {
        this(containerId, playerInv, (DeadPlayerEntity) playerInv.player.world.getEntityByID(buffer.readInt()));
    }
    public DeadPlayerContainer(int containerIdIn, PlayerInventory playerInventoryIn, DeadPlayerEntity deadPlayerEntityIn) {
        super(ContainerTypes.DEAD_PLAYER_CONTAINER.get(), containerIdIn);

        this.deadPlayerEntity = deadPlayerEntityIn;
        this.playerInventory = playerInventoryIn;

        this.deadPlayerEntity.getMainInventory().openInventory(playerInventoryIn.player);
        this.deadPlayerEntity.getArmorInventory().openInventory(playerInventoryIn.player);
        this.deadPlayerEntity.getOffHandInventory().openInventory(playerInventoryIn.player);

        addContainerSlots();
        addPlayerSlots();
    }

    @Override
    public boolean canInteractWith(PlayerEntity playerIn) {
        return playerIn.getDistanceSq(deadPlayerEntity.posX, deadPlayerEntity.posY, deadPlayerEntity.posZ) <= 64D;
    }

    @Override
    public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
        return super.transferStackInSlot(playerIn, index);
    }

    @Override
    public void onContainerClosed(PlayerEntity playerIn) {
        super.onContainerClosed(playerIn);
        this.deadPlayerEntity.getInventory().getInventories().forEach((s, invEnt) -> {
            invEnt.closeInventory(playerIn);
        });
    }

    private void addContainerSlots() {
        ctSlotIndex = 0;

        // armor slots
        firstArmorSlotIndex = ctSlotIndex;
        for (int i = 0; i < 4; i++) {
            final EquipmentSlotType equipmentslottype = VALID_EQUIPMENT_SLOTS[i];
            addSlot(new Slot( deadPlayerEntity.getArmorInventory(), ctSlotIndex, firstArmorSlot.x, firstArmorSlot.y + 18 * i){
                @Override
                public int getSlotStackLimit() { return 1; }
                @Override
                public boolean isItemValid(ItemStack stack) { return stack.canEquip(equipmentslottype, playerInventory.player); }

                @Nullable
                @OnlyIn(Dist.CLIENT)
                @Override
                public String getSlotTexture() { return DeadPlayerContainer.ARMOR_SLOT_TEXTURES[equipmentslottype.getIndex()]; }
            });
            ctSlotIndex++;
        }
        // off hand slot
        firstOffHandSlotIndex = ctSlotIndex;
        this.addSlot(new Slot(deadPlayerEntity.getOffHandInventory(), ctSlotIndex, firstArmorSlot.x + 18, firstArmorSlot.y + 18 * 3) {
            @Nullable
            @OnlyIn(Dist.CLIENT)
            public String getSlotTexture() {
                return "item/empty_armor_slot_shield";
            }
        });
        ctSlotIndex++;
        // main slots
        firstMainSlotIndex = ctSlotIndex;
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 9; col++) {
                addSlot(new Slot(deadPlayerEntity.getMainInventory(), ctSlotIndex, firstInvSlot.x + col * 18, firstInvSlot.y + row * 18));
                ctSlotIndex++;
            }
        }
        // main hand slots
        firstMainHandSlotIndex = ctSlotIndex;
        for (int i = 0; i < 9; i++) {
            addSlot(new Slot(deadPlayerEntity.getMainInventory(), ctSlotIndex, firstInvSlot.x + i * 18, firstInvSlot.y + 18 * 3));
            ctSlotIndex++;
        }
    }
    private void addPlayerSlots() {
        // armor slots
        firstPlayerArmorSlotIndex = ctSlotIndex;
        for (int i = 0; i < 4; i++) {
            final EquipmentSlotType equipmentslottype = VALID_EQUIPMENT_SLOTS[i];
            addSlot(new Slot( playerInventory, playerInventory.getSizeInventory() - 5 + 1, firstPlayerArmorSlot.x, firstPlayerArmorSlot.y + 18 * i){
                @Override
                public int getSlotStackLimit() { return 1; }
                @Override
                public boolean isItemValid(ItemStack stack) { return stack.canEquip(equipmentslottype, playerInventory.player); }

                @Nullable
                @OnlyIn(Dist.CLIENT)
                @Override
                public String getSlotTexture() { return DeadPlayerContainer.ARMOR_SLOT_TEXTURES[equipmentslottype.getIndex()]; }
            });
            ctSlotIndex++;
        }
        // off hand slot
        firstPlayerOffHandPSlotIndex = ctSlotIndex;
        this.addSlot(new Slot(playerInventory, playerInventory.getSizeInventory() - 1, firstPlayerArmorSlot.x + 18, firstPlayerArmorSlot.y + 18 * 3) {
            @Nullable
            @OnlyIn(Dist.CLIENT)
            public String getSlotTexture() {
                return "item/empty_armor_slot_shield";
            }
        });
        ctSlotIndex++;
        // main slots
        firstPlayerMainPSlotIndex = ctSlotIndex;
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 9; col++) {
                addSlot(new Slot(playerInventory, col + (row + 1) * 9, firstPlayerInvSlot.x + col * 18, firstPlayerInvSlot.y + row * 18));
                ctSlotIndex++;
            }
        }
        // main hand slots
        firstPlayerMainHandSlotIndex = ctSlotIndex;
        for (int i = 0; i < 9; i++) {
            addSlot(new Slot(playerInventory, i, firstPlayerInvSlot.x + i * 18, firstPlayerInvSlot.y + 18 * 3));
        }
    }
    public DeadPlayerEntity getDeadPlayerEntity() { return this.deadPlayerEntity; }
}

ContainerTypes:

package com.gnrdevand.inventoryplus.init;

import com.gnrdevand.inventoryplus.InventoryPlus;
import com.gnrdevand.inventoryplus.inventory.DeadPlayerContainer;
import net.minecraft.inventory.container.ContainerType;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;

public class ContainerTypes {
    public static final DeferredRegister<ContainerType<?>> CONTAINER_TYPES = new DeferredRegister<>(ForgeRegistries.CONTAINERS, InventoryPlus.MODID);
    public static final RegistryObject<ContainerType<DeadPlayerContainer>> DEAD_PLAYER_CONTAINER = CONTAINER_TYPES.register(InventoryPlus.MODID, () -> {
        return IForgeContainerType.create(DeadPlayerContainer::new);
    });
}

 

MainMod:

package com.gnrdevand.inventoryplus;

import com.gnrdevand.inventoryplus.gui.DeadPlayerInventoryScreen;
import com.gnrdevand.inventoryplus.init.ConfigHandler;
import com.gnrdevand.inventoryplus.init.ContainerTypes;
import com.gnrdevand.inventoryplus.network.Networking;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.util.InputMappings;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLPaths;

import java.util.logging.Logger;


@Mod(InventoryPlus.MODID)
public final class InventoryPlus {
    public static final String MODID = "inventoryplus";
    public static final Logger LOGGER = Logger.getLogger(MODID);

    public InventoryPlus() {
        ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ConfigHandler.CLIENT_CONFIG);
        ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ConfigHandler.COMMON_CONFIG);

        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientRegistries);

        ConfigHandler.loadConfig(ConfigHandler.CLIENT_CONFIG, FMLPaths.CONFIGDIR.get().resolve(MODID + "-client.toml"));
        ConfigHandler.loadConfig(ConfigHandler.COMMON_CONFIG, FMLPaths.CONFIGDIR.get().resolve(MODID + "-common.toml"));

        ContainerTypes.CONTAINER_TYPES.register(FMLJavaModLoadingContext.get().getModEventBus());
    }

    private void setup(final FMLCommonSetupEvent event) {
        Networking.registerMessages();
    }

    private void clientRegistries(FMLClientSetupEvent event) {
        ScreenManager.registerFactory(ContainerTypes.DEAD_PLAYER_CONTAINER.get(), DeadPlayerInventoryScreen::new);
    }

}

I did not understand this part of MainMod class:  (ContainerTypes.CONTAINER_TYPES.register(FMLJavaModLoadingContext.get().getModEventBus());)

 

DeadPlayerInventoryScreen:

package com.gnrdevand.inventoryplus.gui;


import com.gnrdevand.gnrsharedlib.gui.controls.ButtonExt;
import com.gnrdevand.inventoryplus.entities.DeadPlayerEntity;
import com.gnrdevand.inventoryplus.inventory.DeadPlayerContainer;
import com.gnrdevand.inventoryplus.lib.Resources;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class DeadPlayerInventoryScreen extends ContainerScreen<DeadPlayerContainer> {
    private final PlayerInventory playerInventory;
    private final DeadPlayerEntity deadPlayerEntity;
    private float mousePosx;
    private float mousePosY;

    public DeadPlayerInventoryScreen(DeadPlayerContainer container, PlayerInventory playerInventoryIn, ITextComponent tileIn) {
        super(container, playerInventoryIn, tileIn);
        this.playerInventory = playerInventoryIn;
        this.deadPlayerEntity = container.getDeadPlayerEntity();
    }

    @Override
    protected void init() {
        xSize = 211;
        ySize = 179;
        super.init();

        String txt = Resources.getMsg("transfer");
        addButton(new ButtonExt(this, guiLeft + xSize - 20 - font.getStringWidth(txt) - 6, guiTop + (18 * 4) + 6, font.getStringWidth(txt) + 20, 20, txt, btnClick -> {

        }));
    }
    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
        GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.minecraft.getTextureManager().bindTexture(Resources.DEAD_PLAYER_GUI);
        int x = (this.width - this.xSize) / 2;
        int y = (this.height - this.ySize) / 2;
        this.blit(x, y, 0, 0, this.xSize, this.ySize);
    }
    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 7, (18 * 4) + 6 + font.FONT_HEIGHT, 4210752);
    }

    @Override
    public void render(int mouseX, int mouseY, float partialTicks) {
        this.mousePosx = mouseX;
        this.mousePosY = mouseY;
        super.render(mouseX, mouseY, partialTicks);
        this.renderHoveredToolTip(mouseX, mouseY);
    }
}

 

DeadPlayerEntity:

package com.gnrdevand.inventoryplus.entities;

import com.gnrdevand.inventoryplus.init.ConfigHandler;
import com.gnrdevand.inventoryplus.init.ModEntities;
import com.gnrdevand.inventoryplus.inventory.DeadPlayerContainer;
import net.minecraft.entity.CreatureEntity;
import net.minecraft.entity.EntitySize;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.Pose;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.DamageSource;
import net.minecraft.util.Hand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;

import javax.annotation.Nullable;
import java.util.function.Consumer;

public class DeadPlayerEntity extends CreatureEntity {
    public static final String name = "dead_player_entity";
    private static final DataParameter<Integer> DATA_BORN_TIME = EntityDataManager.createKey(DeadPlayerEntity.class, DataSerializers.VARINT);
    private static final DataParameter<String> DATA_CUSTOM_NAME = EntityDataManager.createKey(DeadPlayerEntity.class, DataSerializers.STRING);
    private final DeadPlayerEntityInventoryContainerProvider containerProvider;
    private int timeToDie;
    private String customName;
    private InventoryForEntities inventory;

    public enum eDeadPlayerInvTypes {
        ARMOR("armorInventory"),
        MAIN("mainInventory"),
        OFFHAND("offHandInventory");

        private String type;

        eDeadPlayerInvTypes(String type) {
            this.type = type;
        }
        public String getType() { return this.type; }
    }

    public DeadPlayerEntity(EntityType<? extends CreatureEntity> type, World worldIn) {
        super((EntityType<? extends CreatureEntity>) ModEntities.DEAD_PLAYER_ENTITY, worldIn);
        this.timeToDie = 20 * 60 * ConfigHandler.CFG_DEAD_BODY_TIME.get(); // in minutes
        this.setInvulnerable(true);

        inventory = new InventoryForEntities(this);
        inventory.addInventory(eDeadPlayerInvTypes.MAIN.getType(), 9 * 4); // Player Inventory + Player quick inventory
        inventory.addInventory(eDeadPlayerInvTypes.ARMOR.getType(), 4); // Player Armor
        inventory.addInventory(eDeadPlayerInvTypes.OFFHAND.getType(), 1); // Player off hand item
        inventory.setMustDieOnPeacefull(false);
        inventory.setCanDropInventoryOnDeath(true);

        this.containerProvider = new DeadPlayerEntityInventoryContainerProvider(this);
    }
    public InventoryForEntities getInventory() { return this.inventory; }
    public InventoryEntity getArmorInventory() { return this.inventory.getInventory(eDeadPlayerInvTypes.ARMOR.getType()); }
    public InventoryEntity getOffHandInventory() { return this.inventory.getInventory(eDeadPlayerInvTypes.OFFHAND.getType()); }
    public InventoryEntity getMainInventory() { return this.inventory.getInventory(eDeadPlayerInvTypes.MAIN.getType()); }
    public long getTimeToDie() { return this.timeToDie; }
    public void setName(String name) {
        customName = name;
        this.dataManager.set(DATA_CUSTOM_NAME, customName);
    }
    public boolean copyPlayerInventory(PlayerEntity player) {
        boolean hasInv = false;
        for (int i = 0; i < player.inventory.armorInventory.size(); i++) {
            inventory.getInventory(eDeadPlayerInvTypes.ARMOR.getType()).addItem(player.inventory.armorInventory.get(i).copy());
            if (!player.inventory.armorInventory.get(i).isEmpty()) hasInv = true;
        }
        inventory.getInventory(eDeadPlayerInvTypes.OFFHAND.getType()).addItem(player.inventory.offHandInventory.get(0).copy());
        if (!player.inventory.offHandInventory.get(0).isEmpty()) hasInv = true;

        for (int i = 0; i < player.inventory.mainInventory.size(); i++) {
            inventory.getInventory(eDeadPlayerInvTypes.MAIN.getType()).addItem(player.inventory.mainInventory.get(i).copy());
            if (!player.inventory.mainInventory.get(i).isEmpty()) hasInv = true;
        }
        return hasInv;
    }

    @Override
    protected void registerData() {
        super.registerData();
        this.getDataManager().register(DATA_BORN_TIME, 0);
        this.getDataManager().register(DATA_CUSTOM_NAME, "");
    }
    @Override
    public void writeAdditional(CompoundNBT compound) {
        super.writeAdditional(compound);
        compound.putInt("DATA_BORN_TIME", timeToDie);
        compound.putString("DATA_CUSTOM_NAME", customName);
        inventory.getInventories().forEach((name, invEnt) -> {
            compound.put(name, invEnt.writeToNBT());
        });
    }
    @Override
    public void readAdditional(CompoundNBT compound) {
        super.readAdditional(compound);
        timeToDie = compound.getInt("DATA_BORN_TIME");
        customName = compound.getString("DATA_CUSTOM_NAME");
        inventory.getInventories().forEach((name, invEnt) -> {
            invEnt.readFromNBT(compound.getList(name, 10));
        });
    }
    @Override
    public EntitySize getSize(Pose poseIn) { return EntitySize.fixed(1.8F, 0.2F); }
    @Override
    protected boolean isMovementBlocked() { return true; }
    @Override
    public boolean canBeSteered() { return false; }
    @Override
    public boolean canDespawn(double distanceToClosestPlayer) { return false; }
    @Override
    public void livingTick() {
        if (!ConfigHandler.CFG_USE_DEAD_BODY.get() && !world.isRemote) {
            this.setHealth(0);
            this.remove();
            return;
        }
        super.livingTick();

        //if (bornTime > 0) bornTime--;
        if (timeToDie <=0) {
            this.setHealth(0);
            this.onDeath(DamageSource.OUT_OF_WORLD);
            this.remove();
        } else if (!world.isRemote) {
            int seconds = timeToDie / 20;
            this.setCustomName(new StringTextComponent(customName + " > " + String.format("%02d", (int) (seconds / 60)) + ":" + String.format("%02d", (int) (seconds % 60))));
        }
    }

    @Override
    protected boolean processInteract(PlayerEntity player, Hand hand) {
        if (hand == Hand.MAIN_HAND && !player.world.isRemote && player instanceof ServerPlayerEntity) {
            NetworkHooks.openGui((ServerPlayerEntity) player, this.containerProvider, new Consumer<PacketBuffer>() {
                @Override
                public void accept(PacketBuffer buffer) {
                    buffer.writeInt(getEntityId());
                }
            });
            return true;
        }
        return super.processInteract(player, hand);
    }

    @Override
    public void onDeath(DamageSource cause) {
        super.onDeath(cause);

        if (!world.isRemote) {
            inventory.getInventory(eDeadPlayerInvTypes.ARMOR.getType()).dropInventoryItems();
            inventory.getInventory(eDeadPlayerInvTypes.OFFHAND.getType()).dropInventoryItems();
            inventory.getInventory(eDeadPlayerInvTypes.MAIN.getType()).dropInventoryItems();
        }
    }

    @Override
    public ItemStack getItemStackFromSlot(EquipmentSlotType slotIn) {
        if (slotIn == EquipmentSlotType.MAINHAND) {
            return this.inventory.getInventory(eDeadPlayerInvTypes.MAIN.getType()).getStackInSlot(0);
        } else if (slotIn == EquipmentSlotType.OFFHAND) {
            return this.inventory.getInventory(eDeadPlayerInvTypes.OFFHAND.getType()).getStackInSlot(0);
        } else {
            return slotIn.getSlotType() == EquipmentSlotType.Group.ARMOR ? this.inventory.getInventory(eDeadPlayerInvTypes.ARMOR.getType()).getStackInSlot(slotIn.getIndex()) : ItemStack.EMPTY;
        }
    }
}

class DeadPlayerEntityInventoryContainerProvider implements INamedContainerProvider {
    private final DeadPlayerEntity deadPlayerEntity;
    public DeadPlayerEntityInventoryContainerProvider(DeadPlayerEntity deadPlayerEntity) {
        this.deadPlayerEntity = deadPlayerEntity;
    }

    @Nullable
    @Override
    public Container createMenu(int containerId, PlayerInventory playerInv, PlayerEntity player) {
        return new DeadPlayerContainer(containerId, playerInv, this.deadPlayerEntity);
    }

    @Override
    public ITextComponent getDisplayName() {
        return deadPlayerEntity.getDisplayName();
    }
}

 

Edited by GnRSlashSP
Added full Container code (with slots creation)

†GnR† Slash

can one man truly make a difference?

Link to comment
Share on other sites

5 minutes ago, diesieben07 said:

In the future please make your own thread instead of posting in some random thread that you think is mildly related.

Sorry, I posted hede because I am trying to use exact the same code. Next time I'll create new topic

5 minutes ago, diesieben07 said:

Your container does not add any slots. Not sure what you expected as a result other than it having no slots and thus not showing any items.

Ok, all code is now there. Sorry

5 minutes ago, diesieben07 said:

This does nothing.

I know, but I don't know what I have to do inside it yet 

 

†GnR† Slash

can one man truly make a difference?

Link to comment
Share on other sites

Last question:

 

Do you know if there is a repository that contains "entity with inventory" that I can use as a study?

I confess that from forge 1.7.10 to 1.15 is very difficult for me, I can learn fast from examples.

 

Thank you

†GnR† Slash

can one man truly make a difference?

Link to comment
Share on other sites

I was looking at ItemStackHandler and the difference mine is too slight, ItemHandler is missing some features like listeners, clear inventory, isEmpty, MarkDirt. So, this is reasonable if it syncs with client for me automatically.

I changed from "extends Inventory"  to extends "ItemHandler" and now I cant add slots because new slot needs Inventory class.

 

Let me see ... Did I get it right?
If I implement correctly, will the inventory automatically sync without having to create custom network messages or ItemHandler is just a way to writeToNBT automatically?

 

thanks

†GnR† Slash

can one man truly make a difference?

Link to comment
Share on other sites

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.