aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java')
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java559
1 files changed, 559 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java
new file mode 100644
index 0000000000..c8b4e6bfca
--- /dev/null
+++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEBuffer.java
@@ -0,0 +1,559 @@
+package gregtech.api.metatileentity.implementations;
+
+import static gregtech.api.enums.GTValues.V;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_DOWN;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_DOWN_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_LEFT;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_LEFT_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_RIGHT;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_RIGHT_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_UP;
+import static gregtech.api.enums.Textures.BlockIcons.ARROW_UP_GLOW;
+import static gregtech.api.enums.Textures.BlockIcons.MACHINE_CASINGS;
+import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_PIPE_OUT;
+import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import java.util.stream.IntStream;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import com.gtnewhorizons.modularui.api.drawable.UITexture;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.api.widget.Widget;
+import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.SlotGroup;
+
+import gregtech.api.gui.modularui.GTUIInfos;
+import gregtech.api.gui.modularui.GTUITextures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.modularui.IAddUIWidgets;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GTUtility;
+import gregtech.api.util.GT_TooltipDataCache;
+
+public abstract class MTEBuffer extends MTETieredMachineBlock implements IAddUIWidgets {
+
+ private static final int OUTPUT_INDEX = 0;
+ private static final int ARROW_RIGHT_INDEX = 1;
+ private static final int ARROW_DOWN_INDEX = 2;
+ private static final int ARROW_LEFT_INDEX = 3;
+ private static final int ARROW_UP_INDEX = 4;
+ private static final int FRONT_INDEX = 5;
+
+ private static final String EMIT_ENERGY_TOOLTIP = "GT5U.machines.emit_energy.tooltip";
+ private static final String EMIT_REDSTONE_IF_FULL_TOOLTIP = "GT5U.machines.emit_redstone_if_full.tooltip";
+ private static final String INVERT_REDSTONE_TOOLTIP = "GT5U.machines.invert_redstone.tooltip";
+ private static final String STOCKING_MODE_TOOLTIP = "GT5U.machines.buffer_stocking_mode.tooltip";
+ private static final String SORTING_MODE_TOOLTIP = "GT5U.machines.sorting_mode.tooltip";
+ private static final int BUTTON_SIZE = 18;
+
+ public int mMaxStackSize = 64;
+ public static int MAX = 8;
+ public boolean bOutput = false, bRedstoneIfFull = false, bInvert = false, bStockingMode = false,
+ bSortStacks = false;
+ public int mSuccess = 0, mTargetStackSize = 0;
+ private int uiButtonCount = 0;
+
+ public MTEBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) {
+ super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription);
+ }
+
+ public MTEBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) {
+ super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription);
+ }
+
+ public MTEBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aInvSlotCount, aDescription, aTextures);
+ }
+
+ public MTEBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) {
+ super(aName, aTier, aInvSlotCount, aDescription, aTextures);
+ }
+
+ @Override
+ public ITexture[][][] getTextureSet(ITexture[] aTextures) {
+ ITexture[][][] rTextures = new ITexture[ForgeDirection.VALID_DIRECTIONS.length][17][];
+ ITexture tIcon = getOverlayIcon();
+ ITexture tOut = TextureFactory.of(OVERLAY_PIPE_OUT);
+ ITexture tUp = TextureFactory.of(
+ TextureFactory.of(ARROW_UP),
+ TextureFactory.builder()
+ .addIcon(ARROW_UP_GLOW)
+ .glow()
+ .build());
+ ITexture tDown = TextureFactory.of(
+ TextureFactory.of(ARROW_DOWN),
+ TextureFactory.builder()
+ .addIcon(ARROW_DOWN_GLOW)
+ .glow()
+ .build());
+ ITexture tLeft = TextureFactory.of(
+ TextureFactory.of(ARROW_LEFT),
+ TextureFactory.builder()
+ .addIcon(ARROW_LEFT_GLOW)
+ .glow()
+ .build());
+ ITexture tRight = TextureFactory.of(
+ TextureFactory.of(ARROW_RIGHT),
+ TextureFactory.builder()
+ .addIcon(ARROW_RIGHT_GLOW)
+ .glow()
+ .build());
+ for (int i = 0; i < rTextures[0].length; i++) {
+ rTextures[OUTPUT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tOut };
+ rTextures[ARROW_RIGHT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tRight, tIcon };
+ rTextures[ARROW_DOWN_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tDown, tIcon };
+ rTextures[ARROW_LEFT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tLeft, tIcon };
+ rTextures[ARROW_UP_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tUp, tIcon };
+ rTextures[FRONT_INDEX][i] = new ITexture[] { MACHINE_CASINGS[mTier][i], tIcon };
+ }
+ return rTextures;
+ }
+
+ @Override
+ public ITexture[] getTexture(IGregTechTileEntity baseMetaTileEntity, ForgeDirection sideDirection,
+ ForgeDirection facingDirection, int colorIndex, boolean active, boolean redstoneLevel) {
+ colorIndex = colorIndex + 1;
+ if (sideDirection == facingDirection) return mTextures[FRONT_INDEX][colorIndex];
+ if (sideDirection.getOpposite() == facingDirection) return mTextures[OUTPUT_INDEX][colorIndex];
+ switch (facingDirection) {
+ case DOWN -> {
+ return mTextures[ARROW_UP_INDEX][colorIndex]; // ARROW_UP
+ }
+ case UP -> {
+ return mTextures[ARROW_DOWN_INDEX][colorIndex]; // ARROW_DOWN
+ }
+ case NORTH -> {
+ switch (sideDirection) {
+ case DOWN, UP -> {
+ return mTextures[ARROW_DOWN_INDEX][colorIndex]; // ARROW_DOWN
+ }
+ case WEST -> {
+ return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT
+ }
+ case EAST -> {
+ return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT
+ }
+ default -> {}
+ }
+ }
+ case SOUTH -> {
+ switch (sideDirection) {
+ case DOWN, UP -> {
+ return mTextures[ARROW_UP_INDEX][colorIndex]; // ARROW_UP
+ }
+ case WEST -> {
+ return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT
+ }
+ case EAST -> {
+ return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT
+ }
+ default -> {}
+ }
+ }
+ case WEST -> {
+ switch (sideDirection) {
+ case UP, SOUTH -> {
+ return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT
+ }
+ case DOWN, NORTH -> {
+ return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT
+ }
+ default -> {}
+ }
+ }
+ case EAST -> {
+ switch (sideDirection) {
+ case UP, SOUTH -> {
+ return mTextures[ARROW_LEFT_INDEX][colorIndex]; // ARROW_LEFT
+ }
+ case DOWN, NORTH -> {
+ return mTextures[ARROW_RIGHT_INDEX][colorIndex]; // ARROW_RIGHT
+ }
+ default -> {}
+ }
+ }
+ default -> {}
+ }
+ return mTextures[FRONT_INDEX][colorIndex];
+ }
+
+ @Override
+ public boolean isSimpleMachine() {
+ return false;
+ }
+
+ @Override
+ public boolean isValidSlot(int aIndex) {
+ return aIndex < mInventory.length - 1;
+ }
+
+ @Override
+ public boolean isFacingValid(ForgeDirection facing) {
+ return true;
+ }
+
+ @Override
+ public boolean isEnetInput() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnetOutput() {
+ return true;
+ }
+
+ @Override
+ public boolean isInputFacing(ForgeDirection side) {
+ return !isOutputFacing(side);
+ }
+
+ @Override
+ public boolean isOutputFacing(ForgeDirection side) {
+ return getBaseMetaTileEntity().getBackFacing() == side;
+ }
+
+ @Override
+ public boolean isTeleporterCompatible() {
+ return false;
+ }
+
+ @Override
+ public long getMinimumStoredEU() {
+ return 512L;
+ }
+
+ @Override
+ public long maxEUStore() {
+ return 512L + V[mTier] * 50L;
+ }
+
+ @Override
+ public long maxEUInput() {
+ return V[mTier];
+ }
+
+ @Override
+ public long maxEUOutput() {
+ // Return full value if we're an item and don't exist in the world for tooltip purposes
+ return getBaseMetaTileEntity().getWorld() == null || bOutput ? V[mTier] : 0L;
+ }
+
+ @Override
+ public long maxAmperesIn() {
+ return 2;
+ }
+
+ @Override
+ public long maxAmperesOut() {
+ return 2;
+ }
+
+ @Override
+ public boolean isAccessAllowed(EntityPlayer aPlayer) {
+ return true;
+ }
+
+ public abstract ITexture getOverlayIcon();
+
+ @Override
+ public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) {
+ GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer);
+ return true;
+ }
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ aNBT.setBoolean("bInvert", bInvert);
+ aNBT.setBoolean("bOutput", bOutput);
+ aNBT.setBoolean("bRedstoneIfFull", bRedstoneIfFull);
+ aNBT.setBoolean("bStockingMode", bStockingMode);
+ aNBT.setInteger("mTargetStackSize", mTargetStackSize);
+ aNBT.setBoolean("bSortStacks", bSortStacks);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ bInvert = aNBT.getBoolean("bInvert");
+ bOutput = aNBT.getBoolean("bOutput");
+ bRedstoneIfFull = aNBT.getBoolean("bRedstoneIfFull");
+ bSortStacks = aNBT.getBoolean("bSortStacks");
+ bStockingMode = aNBT.getBoolean("bStockingMode");
+ mTargetStackSize = aNBT.getInteger("mTargetStackSize");
+ }
+
+ @Override
+ public void setItemNBT(NBTTagCompound aNBT) {
+ super.setItemNBT(aNBT);
+ if (mTargetStackSize > 0) aNBT.setInteger("mTargetStackSize", mTargetStackSize);
+ }
+
+ @Override
+ public void onScrewdriverRightClick(ForgeDirection side, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (side == getBaseMetaTileEntity().getBackFacing()) {
+
+ mTargetStackSize = (byte) ((mTargetStackSize + (aPlayer.isSneaking() ? -1 : 1)) % 65);
+ if (mTargetStackSize < 0) {
+ mTargetStackSize = mMaxStackSize;
+ }
+ if (mTargetStackSize == 0) {
+ GTUtility.sendChatToPlayer(aPlayer, GTUtility.trans("098", "Do not regulate Item Stack Size"));
+ } else {
+ GTUtility.sendChatToPlayer(
+ aPlayer,
+ GTUtility.trans("099", "Regulate Item Stack Size to: ") + mTargetStackSize);
+ }
+ }
+ }
+
+ @Override
+ public boolean onWrenchRightClick(ForgeDirection side, ForgeDirection wrenchingSide, EntityPlayer entityPlayer,
+ float aX, float aY, float aZ) {
+ wrenchingSide = wrenchingSide.getOpposite();
+ if (getBaseMetaTileEntity().isValidFacing(wrenchingSide)) {
+ getBaseMetaTileEntity().setFrontFacing(wrenchingSide);
+ return true;
+ }
+ return false;
+ }
+
+ protected void handleRedstoneOutput(IGregTechTileEntity aBaseMetaTileEntity) {
+ int redstoneOutput = getRedstoneOutput();
+ Arrays.stream(ForgeDirection.VALID_DIRECTIONS)
+ .forEach(side -> aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) redstoneOutput));
+ }
+
+ protected int getRedstoneOutput() {
+ return (!bRedstoneIfFull || (bInvert ^ hasEmptySlots())) ? 0 : 15;
+ }
+
+ private boolean hasEmptySlots() {
+ return IntStream.range(0, mInventory.length)
+ .anyMatch(i -> isValidSlot(i) && mInventory[i] == null);
+ }
+
+ @Override
+ public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) {
+ if (aBaseMetaTileEntity.isAllowedToWork() && aBaseMetaTileEntity.isServerSide()
+ && (aBaseMetaTileEntity.hasWorkJustBeenEnabled() || aBaseMetaTileEntity.hasInventoryBeenModified()
+ || aTimer % 200 == 0
+ || mSuccess > 0)) {
+ mSuccess--;
+ updateSlots();
+ moveItems(aBaseMetaTileEntity, aTimer);
+ handleRedstoneOutput(aBaseMetaTileEntity);
+ }
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
+ aBaseMetaTileEntity.setInternalOutputRedstoneSignal(side, (byte) 0);
+ }
+
+ protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) {
+ moveItems(aBaseMetaTileEntity, aTimer, 1);
+ }
+
+ protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long ignoredTimer, int stacks) {
+ int tCost;
+ if (bStockingMode) tCost = GTUtility.moveMultipleItemStacks(
+ aBaseMetaTileEntity,
+ aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getBackFacing()),
+ aBaseMetaTileEntity.getBackFacing(),
+ aBaseMetaTileEntity.getFrontFacing(),
+ null,
+ false,
+ mTargetStackSize == 0 ? 64 : (byte) mTargetStackSize,
+ mTargetStackSize == 0 ? 1 : (byte) mTargetStackSize,
+ (byte) 64,
+ (byte) 1,
+ stacks);
+ else tCost = GTUtility.moveMultipleItemStacks(
+ aBaseMetaTileEntity,
+ aBaseMetaTileEntity.getTileEntityAtSide(aBaseMetaTileEntity.getBackFacing()),
+ aBaseMetaTileEntity.getBackFacing(),
+ aBaseMetaTileEntity.getFrontFacing(),
+ null,
+ false,
+ (byte) 64,
+ (byte) 1,
+ mTargetStackSize == 0 ? 64 : (byte) mTargetStackSize,
+ mTargetStackSize == 0 ? 1 : (byte) mTargetStackSize,
+ stacks);
+
+ if (tCost > 0 || aBaseMetaTileEntity.hasInventoryBeenModified()) {
+ mSuccess = 50;
+ }
+ }
+
+ @Override
+ public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return true;
+ }
+
+ @Override
+ public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side,
+ ItemStack aStack) {
+ return side != aBaseMetaTileEntity.getBackFacing();
+ }
+
+ @Override
+ public boolean allowGeneralRedstoneOutput() {
+ return true;
+ }
+
+ public void updateSlots() {
+ for (int i = 0; i < mInventory.length; i++)
+ if (mInventory[i] != null && mInventory[i].stackSize <= 0) mInventory[i] = null;
+ if (bSortStacks) fillStacksIntoFirstSlots();
+ }
+
+ protected void fillStacksIntoFirstSlots() {
+ HashMap<GTUtility.ItemId, Integer> slots = new HashMap<>(mInventory.length);
+ HashMap<GTUtility.ItemId, ItemStack> stacks = new HashMap<>(mInventory.length);
+ List<GTUtility.ItemId> order = new ArrayList<>(mInventory.length);
+ List<Integer> validSlots = new ArrayList<>(mInventory.length);
+ for (int i = 0; i < mInventory.length - 1; i++) {
+ if (!isValidSlot(i)) continue;
+ validSlots.add(i);
+ ItemStack s = mInventory[i];
+ if (s == null) continue;
+ GTUtility.ItemId sID = GTUtility.ItemId.createNoCopy(s);
+ slots.merge(sID, s.stackSize, Integer::sum);
+ if (!stacks.containsKey(sID)) stacks.put(sID, s);
+ order.add(sID);
+ mInventory[i] = null;
+ }
+ int slotindex = 0;
+ for (GTUtility.ItemId sID : order) {
+ int toSet = slots.get(sID);
+ if (toSet == 0) continue;
+ int slot = validSlots.get(slotindex);
+ slotindex++;
+ mInventory[slot] = stacks.get(sID)
+ .copy();
+ toSet = Math.min(toSet, mInventory[slot].getMaxStackSize());
+ mInventory[slot].stackSize = toSet;
+ slots.merge(sID, toSet, (a, b) -> a - b);
+ }
+ }
+
+ @Override
+ public boolean onSolderingToolRightClick(ForgeDirection side, ForgeDirection wrenchingSide,
+ EntityPlayer entityPlayer, float aX, float aY, float aZ) {
+ if (entityPlayer.isSneaking()) {
+ // I was so proud of all this but I literally just copied code from OutputBus
+ bSortStacks = !bSortStacks;
+ GTUtility.sendChatToPlayer(
+ entityPlayer,
+ GTUtility.trans("200", "Sort mode: ")
+ + (bSortStacks ? GTUtility.trans("088", "Enabled") : GTUtility.trans("087", "Disabled")));
+ return true;
+ }
+ return super.onSolderingToolRightClick(side, wrenchingSide, entityPlayer, aX, aY, aZ);
+ }
+
+ protected void addEmitEnergyButton(ModularWindow.Builder builder) {
+ builder.widget(
+ createToggleButton(
+ () -> bOutput,
+ val -> bOutput = val,
+ GTUITextures.OVERLAY_BUTTON_EMIT_ENERGY,
+ this::getEmitEnergyButtonTooltip));
+ }
+
+ private GT_TooltipDataCache.TooltipData getEmitEnergyButtonTooltip() {
+ return mTooltipCache.getData(
+ EMIT_ENERGY_TOOLTIP,
+ EnumChatFormatting.GREEN + GTUtility.formatNumbers(V[mTier])
+ + " ("
+ + GTUtility.getColoredTierNameFromTier(mTier)
+ + EnumChatFormatting.GREEN
+ + ")"
+ + EnumChatFormatting.GRAY,
+ maxAmperesOut());
+ }
+
+ protected void addEmitRedstoneIfFullButton(ModularWindow.Builder builder) {
+ builder.widget(
+ createToggleButton(
+ () -> bRedstoneIfFull,
+ val -> bRedstoneIfFull = val,
+ GTUITextures.OVERLAY_BUTTON_EMIT_REDSTONE,
+ this::getEmitRedstoneIfFullButtonTooltip).setUpdateTooltipEveryTick(true));
+ }
+
+ private GT_TooltipDataCache.TooltipData getEmitRedstoneIfFullButtonTooltip() {
+ return mTooltipCache.getUncachedTooltipData(
+ EMIT_REDSTONE_IF_FULL_TOOLTIP,
+ StatCollector.translateToLocal(hasEmptySlots() ? "gui.yes" : "gui.no"),
+ getRedstoneOutput());
+ }
+
+ protected void addInvertRedstoneButton(ModularWindow.Builder builder) {
+ builder.widget(
+ createToggleButton(
+ () -> bInvert,
+ val -> bInvert = val,
+ GTUITextures.OVERLAY_BUTTON_INVERT_REDSTONE,
+ () -> mTooltipCache.getData(INVERT_REDSTONE_TOOLTIP)));
+ }
+
+ protected void addStockingModeButton(ModularWindow.Builder builder) {
+ builder.widget(
+ createToggleButton(
+ () -> bStockingMode,
+ val -> bStockingMode = val,
+ GTUITextures.OVERLAY_BUTTON_STOCKING_MODE,
+ () -> mTooltipCache.getData(STOCKING_MODE_TOOLTIP)));
+ }
+
+ protected void addSortStacksButton(ModularWindow.Builder builder) {
+ builder.widget(
+ createToggleButton(
+ () -> bSortStacks,
+ val -> bSortStacks = val,
+ GTUITextures.OVERLAY_BUTTON_SORTING_MODE,
+ () -> mTooltipCache.getData(SORTING_MODE_TOOLTIP)));
+ }
+
+ @Override
+ public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) {
+ buildContext.addCloseListener(() -> uiButtonCount = 0);
+ addEmitEnergyButton(builder);
+ }
+
+ protected Widget createToggleButton(Supplier<Boolean> getter, Consumer<Boolean> setter, UITexture picture,
+ Supplier<GT_TooltipDataCache.TooltipData> tooltipDataSupplier) {
+ return new CycleButtonWidget().setToggle(getter, setter)
+ .setStaticTexture(picture)
+ .setVariableBackground(GTUITextures.BUTTON_STANDARD_TOGGLE)
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(7 + (uiButtonCount++ * BUTTON_SIZE), 62)
+ .setSize(BUTTON_SIZE, BUTTON_SIZE)
+ .setGTTooltip(tooltipDataSupplier);
+ }
+
+ protected void addInventorySlots(ModularWindow.Builder builder) {
+ builder.widget(
+ SlotGroup.ofItemHandler(inventoryHandler, 9)
+ .endAtSlot(26)
+ .build()
+ .setPos(7, 4));
+ }
+}