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();
}
}