I've been trying to create a mod for forge 1.19.2, but when i try to set an item in to the item slot i can't pick it from the slot because it disappears when i click on it. Is there any way to fix it? Am I setting the item into the slot in a bad way?
(The item is set into the slot in line 152 of CONTAINER SCREEN)
CONTAINER MENU
package com.drakethered.adminio.Screen;
import com.drakethered.adminio.BlockEntities.ATMBlockEntity;
import com.drakethered.adminio.Screen.slots.CreditCardSlot;
import com.drakethered.adminio.Screen.slots.MoneyInputSlot;
import com.drakethered.adminio.Screen.slots.MoneyOutputSlot;
import com.drakethered.adminio.Utils.Adminio_Blocks;
import com.drakethered.adminio.Utils.Adminio_Menu;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
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.ContainerLevelAccess;
import net.minecraft.world.inventory.SimpleContainerData;
import net.minecraft.world.inventory.Slot;
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 ATMMenu extends AbstractContainerMenu{
public final ATMBlockEntity blockEntity;
private final Level level;
public CreditCardSlot ccSlot;
public MoneyOutputSlot[] outputSlots = new MoneyOutputSlot[3];
public ATMMenu(int id, Inventory inv, FriendlyByteBuf extraData) {
this(id, inv, inv.player.level.getBlockEntity(extraData.readBlockPos()), new SimpleContainerData(0));
}
public ATMMenu(int id, Inventory inv, BlockEntity entity, ContainerData data) {
super(Adminio_Menu.ATM_MENU.get(), id);
checkContainerSize(inv, 3);
blockEntity = (ATMBlockEntity) entity;
this.level = inv.player.level;
addPlayerInventory(inv);
addPlayerHotbar(inv);
this.blockEntity.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(handler -> {
this.ccSlot = new CreditCardSlot(handler, 0, 8, 66);
this.addSlot(ccSlot);
this.addSlot(new MoneyInputSlot(handler, 1, 26, 66, () -> ccSlot.hasItem(), () -> {
CompoundTag tag = ccSlot.getItem().getOrCreateTag();
return tag.getString("IBAN");
}));
outputSlots[0] = new MoneyOutputSlot(handler, 2, 80, 66);
outputSlots[1] = new MoneyOutputSlot(handler, 3, 98, 66);
outputSlots[2] = new MoneyOutputSlot(handler, 4, 116, 66);
for (MoneyOutputSlot slot: outputSlots) {
this.addSlot(slot);
}
});
addDataSlots(data);
}
// 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 = 5; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(Player playerIn, int index) {
Slot sourceSlot = slots.get(index);
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 (index < 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 (index < 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:" + index);
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 player) {
return stillValid(ContainerLevelAccess.create(level, blockEntity.getBlockPos()),
player, Adminio_Blocks.ATM.get());
}
private void addPlayerInventory(Inventory playerInventory) {
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, 86 + i * 18));
}
}
}
private void addPlayerHotbar(Inventory playerInventory) {
for (int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 144));
}
}
}
CONTAINER SCREEN
package com.drakethered.adminio.Screen;
import com.drakethered.adminio.Adminio;
import com.drakethered.adminio.Data.BankData;
import com.drakethered.adminio.Screen.slots.MoneyInputSlot;
import com.drakethered.adminio.Utils.Adminio_Items;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.server.ServerLifecycleHooks;
import java.util.HashMap;
import java.util.Iterator;
public class ATMScreen extends AbstractContainerScreen<ATMMenu> {
private static final ResourceLocation TEXTURE = new ResourceLocation(Adminio.MOD_ID, "textures/gui/atm_gui.png");
private int x, y;
private int[] values = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
private boolean fast, init, activated = false;
public ATMScreen(ATMMenu menu, Inventory inventory, Component title) {
super(menu, inventory, title);
}
private void refresh(int index, int delta) {
if(fast) delta = delta * 10;
int notZero = 0;
for (int val : values) {
if (val != 0)
notZero += 1;
}
if (notZero == 3) {
if (values[index] != 0) {
values[index] = values[index] + delta;
if (values[index] > 64)
values[index] = 64;
if (values[index] < 0)
values[index] = 0;
}
} else {
values[index] = values[index] + delta;
if (values[index] > 64)
values[index] = 64;
if (values[index] < 0)
values[index] = 0;
}
}
@Override
public boolean keyPressed(int KeyCode, int ScanCode, int Modifiers) {
if(ScanCode == 42) fast = !fast;
return super.keyPressed(KeyCode, ScanCode, Modifiers);
}
@Override
protected void init() {
super.init();
x = (width - imageWidth) / 2;
y = (height - imageHeight) / 2;
}
@Override
protected void renderBg(PoseStack poseStack, float partialTick, int Mx, int My) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
this.blit(poseStack, x, y, 0, 0, imageWidth, imageHeight);
}
@Override
protected void renderLabels(PoseStack pPoseStack, int Mx, int My) {
this.font.draw(pPoseStack, this.title, (float) this.titleLabelX, (float) this.titleLabelY, 4210752);
}
private int getReq() {
int request = 0;
for (int i = 0; i < values.length; i++) {
request += MoneyInputSlot.weights[i] * values[i];
}
return request;
}
@Override
public void render(PoseStack poseStack, int Mx, int My, float delta) {
renderBackground(poseStack);
super.render(poseStack, Mx, My, delta);
renderTooltip(poseStack, Mx, My);
if(!init) {
for (int i = 0; i < values.length; i++) {
final int index = i;
addRenderableWidget(new Button(7 + x + 18 * i, 17 + y, 18, 8, Component.literal("+"),
(Button button) -> refresh(index, 1)));
addRenderableWidget(new Button(7 + x + 18 * i, 36 + y, 18, 8, Component.literal("-"),
(Button button) -> refresh(index, -1)));
}
init = true;
}
for (int i = 0; i < values.length; i++) {
this.font.draw(poseStack, Component.literal(String.format("%d", values[i])), 8 + x + 18 * i, 26 + y,
0xffffff);
}
if(this.menu.ccSlot.hasItem()) {
CompoundTag tag = this.menu.ccSlot.getItem().getOrCreateTag();
this.font.draw(poseStack, Component.literal(String.format("Amount: %d",
BankData.gen(ServerLifecycleHooks.getCurrentServer()).getAmount(tag.getString("IBAN"))
)), 8 + x, 46 + y,
0xffffff);
activated = !(getReq() > BankData.gen(ServerLifecycleHooks.getCurrentServer()).getAmount(tag.getString("IBAN")));
if(activated) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
this.blit(poseStack, x + 48, y + 69, 177, 0, 26, 8);
}
}
}
@Override
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
if(activated && (((pMouseX >= (x + 48)) && (pMouseX <= (x + 48 + 26))) && ((pMouseY >= (y + 69)) && (pMouseY <= (y + 69 + 8))))) {
int amount = getReq();
HashMap<String, Integer> sizes = new HashMap<>();
for (int i = 0; i < values.length; i++) {
if(values[i] != 0) sizes.put(Adminio_Items.items_id[i], values[i]);
}
CompoundTag tag = this.menu.ccSlot.getItem().getOrCreateTag();
BankData.gen(ServerLifecycleHooks.getCurrentServer()).modify(tag.getString("IBAN"), -1 * amount);
Iterator<String> iter = sizes.keySet().iterator();
int i = 0;
while (iter.hasNext()) {
String key = iter.next();
final int index = i;
this.menu.blockEntity.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(handler -> {
handler.insertItem(index + 2, new ItemStack(Adminio_Items.registries.get(key).get(), sizes.get(key)), true);
});
i += 1;
}
values = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0};
}
return super.mouseClicked(pMouseX, pMouseY, pButton);
}
}
OUTPUT SLOT
package com.drakethered.adminio.Screen.slots;
import javax.annotation.Nonnull;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.SlotItemHandler;
public class MoneyOutputSlot extends SlotItemHandler {
public MoneyOutputSlot(IItemHandler handler, int index, int x, int y) {
super(handler, index, x, y);
}
@Override
public boolean mayPlace(@Nonnull ItemStack stack) {
return false;
}
}
BLOCK ENTITY
package com.drakethered.adminio.BlockEntities;
import com.drakethered.adminio.Utils.Adminio_BlockEntities;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.drakethered.adminio.Screen.ATMMenu;
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.MenuProvider;
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.level.block.entity.BlockEntity;
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;
public class ATMBlockEntity extends BlockEntity implements MenuProvider {
protected final ContainerData data;
private final ItemStackHandler itemHandler = new ItemStackHandler(5) {
};
private LazyOptional<IItemHandler> lazyItemHandler = LazyOptional.empty();
public ATMBlockEntity(BlockPos pos, BlockState state) {
super(Adminio_BlockEntities.ATM_TILE.get(), pos, state);
this.data = new ContainerData() {
@Override
public int get(int index) {
return 0;
}
@Override
public void set(int index, int value) {
return;
}
@Override
public int getCount() {
return 0;
}
};
}
@Override
public @NotNull Component getDisplayName() {
return Component.translatable("menu.adminio.atm_menu");
}
@Override
public AbstractContainerMenu createMenu(int containerId, @NotNull Inventory inventory, @NotNull Player player) {
return new ATMMenu(containerId, inventory, this, this.data);
}
@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);
}
public void setSlot(int slot, @NotNull ItemStack stack) {
itemHandler.setStackInSlot(slot, stack);
}
@Override
public void onLoad() {
super.onLoad();
lazyItemHandler = LazyOptional.of(() -> itemHandler);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyItemHandler.invalidate();
}
@Override
protected void saveAdditional(CompoundTag nbt) {
nbt.put("inventory", itemHandler.serializeNBT());
super.saveAdditional(nbt);
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
itemHandler.deserializeNBT(nbt.getCompound("inventory"));
}
}