I am creating a mod that adds new armor sets and changes how armor sets are crafted. When the player interacts with the block it fails to open the gui, but I get no error or stacktrace. All of my registration classes are being called correctly. LightArmorBenchScreen's constructor, render, and renderbg methods are not being called at all.
Here is the code:
package net.leeveygames.celestial.blocks.custom;
import net.leeveygames.celestial.Celestial;
import net.leeveygames.celestial.blocks.entity.CelestialBlockEntities;
import net.leeveygames.celestial.blocks.entity.LightArmorBenchBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LightArmorBenchBlock extends BaseEntityBlock {
public static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 12, 16);
public LightArmorBenchBlock(Properties pProperties) {
super(pProperties);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
return SHAPE;
}
@Override
public RenderShape getRenderShape(BlockState pState) {
return RenderShape.MODEL;
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (pState.getBlock() != pNewState.getBlock()) {
BlockEntity blockEntity = pLevel.getBlockEntity(pPos);
if (blockEntity instanceof LightArmorBenchBlockEntity) {
((LightArmorBenchBlockEntity) blockEntity).drops();
}
}
super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
}
@NotNull
@Override
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
if(pLevel.isClientSide())
return InteractionResult.SUCCESS;
BlockEntity be = pLevel.getBlockEntity(pPos);
if (be instanceof LightArmorBenchBlockEntity blockEntity) {
ServerPlayer player = (ServerPlayer)pPlayer;
Celestial.LOGGER.info("Opening Screen.");
NetworkHooks.openScreen(player, blockEntity, pPos);
}
return InteractionResult.CONSUME;
}
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
return new LightArmorBenchBlockEntity(pPos, pState);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType) {
if(pLevel.isClientSide()) {
return null;
}
return createTickerHelper(pBlockEntityType, CelestialBlockEntities.LIGHT_ARMOR_BENCH_BLOCK_ENTITY.get(),
(pLevel1, pPos, pState1, pBlockEntity) -> pBlockEntity.tick(pLevel1, pPos, pState1));
}
}
package net.leeveygames.celestial.screen;
import net.leeveygames.celestial.Celestial;
import net.leeveygames.celestial.blocks.CelestialBlocks;
import net.leeveygames.celestial.blocks.entity.LightArmorBenchBlockEntity;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.items.SlotItemHandler;
public class LightArmorBenchMenu extends AbstractContainerMenu {
public final LightArmorBenchBlockEntity blockEntity;
private final Level level;
public LightArmorBenchMenu(int pContainerId, Inventory inv, FriendlyByteBuf extraData) {
this(pContainerId, inv, inv.player.level().getBlockEntity(extraData.readBlockPos()));
Celestial.LOGGER.info("Creating Light Armor Bench Menu. Client");
}
public LightArmorBenchMenu(int pContainerId, Inventory inv, BlockEntity entity) {
super(CelestialMenuTypes.LIGHT_ARMOR_BENCH_MENU.get(), pContainerId);
Celestial.LOGGER.info("Creating Light Armor Bench Menu. Server");
checkContainerSize(inv, 2);
blockEntity = ((LightArmorBenchBlockEntity) entity);
this.level = inv.player.level();
addPlayerInventory(inv);
addPlayerHotbar(inv);
createLightArmorBenchSlots(blockEntity);
}
private void createLightArmorBenchSlots(LightArmorBenchBlockEntity blockEntity) {
Celestial.LOGGER.info("Creating Light Armor Bench Slots.");
this.blockEntity.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(iItemHandler -> {
this.addSlot(new SlotItemHandler(iItemHandler, 0, 11, 15));
this.addSlot(new SlotItemHandler(iItemHandler, 1, 82, 33));
this.addSlot(new SlotItemHandler(iItemHandler, 2, 133, 33));
});
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 2; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int pIndex) {
Slot sourceSlot = slots.get(pIndex);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + pIndex);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
@Override
public boolean stillValid(Player pPlayer) {
return stillValid(ContainerLevelAccess.create(level, blockEntity.getBlockPos()),
pPlayer, CelestialBlocks.LIGHT_ARMOR_BENCH.get());
}
private void addPlayerInventory(Inventory playerInventory) {
Celestial.LOGGER.info("Creating Player Inventory.");
for (int i = 0; i < 3; ++i) {
for (int l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18));
}
}
}
private void addPlayerHotbar(Inventory playerInventory) {
Celestial.LOGGER.info("Creating Player Hotbar.");
for (int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}
}
}
package net.leeveygames.celestial.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.leeveygames.celestial.Celestial;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
public class LightArmorBenchScreen extends AbstractContainerScreen<LightArmorBenchMenu> {
private static final ResourceLocation TEXTURE =
new ResourceLocation(Celestial.MOD_ID, "textures/gui/LightArmorBenchGUI.png");
public LightArmorBenchScreen(LightArmorBenchMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
super(pMenu, pPlayerInventory, pTitle);
Celestial.LOGGER.info("Creating Light Armor Bench Screen.");
this.imageWidth = 176;
this.imageHeight = 166;
}
@Override
protected void init() {
Celestial.LOGGER.info("Screen init.");
super.init();
}
@Override
protected void renderBg(GuiGraphics guiGraphics, float pPartialTick, int pMouseX, int pMouseY) {
Celestial.LOGGER.info("Render Background Method.");
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
guiGraphics.blit(TEXTURE, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight);
}
@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) {
Celestial.LOGGER.info("Render Method.");
renderBackground(guiGraphics);
super.render(guiGraphics, mouseX, mouseY, delta);
renderTooltip(guiGraphics, mouseX, mouseY);
}
}
package net.leeveygames.celestial.blocks.entity;
import net.leeveygames.celestial.screen.LightArmorBenchMenu;
import net.minecraft.client.gui.screens.inventory.FurnaceScreen;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Container;
import net.minecraft.world.Containers;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.inventory.FurnaceMenu;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LightArmorBenchBlockEntity extends BlockEntity implements MenuProvider {
private final ItemStackHandler itemHandler = new ItemStackHandler(3) {
@Override
protected void onContentsChanged(int slot) {
super.onContentsChanged(slot);
LightArmorBenchBlockEntity.this.setChanged();
}
};
private static final int INPUT_SLOT = 0;
private static final int OUTPUT_SLOT = 1;
private LazyOptional<IItemHandler> lazyItemHandler = LazyOptional.empty();
public LightArmorBenchBlockEntity(BlockPos pPos, BlockState pBlockState) {
super(CelestialBlockEntities.LIGHT_ARMOR_BENCH_BLOCK_ENTITY.get(), pPos, pBlockState);
}
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
if(cap == ForgeCapabilities.ITEM_HANDLER) {
return lazyItemHandler.cast();
}
return super.getCapability(cap, side);
}
@Override
public void onLoad() {
super.onLoad();
lazyItemHandler = LazyOptional.of(() -> itemHandler);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyItemHandler.invalidate();
}
public void drops() {
SimpleContainer inventory = new SimpleContainer(itemHandler.getSlots());
for(int i = 0; i < itemHandler.getSlots(); i++) {
inventory.setItem(i, itemHandler.getStackInSlot(i));
}
Containers.dropContents(this.level, this.worldPosition, inventory);
}
@Override
public Component getDisplayName() {
return Component.translatable("block.celestial.light_armor_bench");
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int pContainerId, Inventory pPlayerInventory, Player pPlayer) {
return new LightArmorBenchMenu(pContainerId, pPlayerInventory, this);
}
@Override
protected void saveAdditional(CompoundTag pTag) {
pTag.put("inventory", itemHandler.serializeNBT());
super.saveAdditional(pTag);
}
@Override
public void load(CompoundTag pTag) {
super.load(pTag);
itemHandler.deserializeNBT(pTag.getCompound("inventory"));
}
public void tick(Level pLevel, BlockPos pPos, BlockState pState) {
}
}
Here is the console output:
https://pastebin.com/krgExnYT