342 lines
9.3 KiB
Java
342 lines
9.3 KiB
Java
package dev.zontreck.libzontreck.chestgui;
|
|
|
|
import dev.zontreck.libzontreck.LibZontreck;
|
|
import dev.zontreck.libzontreck.events.CloseGUIEvent;
|
|
import dev.zontreck.libzontreck.events.OpenGUIEvent;
|
|
import dev.zontreck.libzontreck.items.ModItems;
|
|
import dev.zontreck.libzontreck.menus.ChestGUIMenu;
|
|
import dev.zontreck.libzontreck.networking.ModMessages;
|
|
import dev.zontreck.libzontreck.networking.packets.S2CCloseChestGUI;
|
|
import dev.zontreck.libzontreck.util.ServerUtilities;
|
|
import dev.zontreck.libzontreck.vectors.Vector2;
|
|
import dev.zontreck.libzontreck.vectors.Vector2i;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.world.SimpleMenuProvider;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraftforge.common.MinecraftForge;
|
|
import net.minecraftforge.fml.LogicalSide;
|
|
import net.minecraftforge.items.ItemStackHandler;
|
|
import net.minecraftforge.network.NetworkHooks;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
public class ChestGUI
|
|
{
|
|
private ItemStackHandler container = new ItemStackHandler((9*3));
|
|
private String MenuTitle = "";
|
|
private UUID player;
|
|
public List<ChestGUIButton> buttons = new ArrayList<>();
|
|
private ResourceLocation id;
|
|
private int page =0;
|
|
private boolean hasAdd = false;
|
|
private boolean hasReset = false;
|
|
private boolean hasRemove = false;
|
|
|
|
private Runnable onAdd;
|
|
private Runnable onReset;
|
|
private Runnable onRemove;
|
|
|
|
|
|
public ChestGUI withAdd(Runnable onAdd)
|
|
{
|
|
hasAdd=true;
|
|
this.onAdd=onAdd;
|
|
return this;
|
|
}
|
|
|
|
public ChestGUI withReset(Runnable onReset)
|
|
{
|
|
hasReset = true;
|
|
this.onReset = onReset;
|
|
return this;
|
|
}
|
|
|
|
private ChestGUI withRemove(Runnable onRemove)
|
|
{
|
|
hasRemove = true;
|
|
this.onRemove=onRemove;
|
|
return this;
|
|
}
|
|
public ChestGUI withButton(ChestGUIButton button)
|
|
{
|
|
buttons.add(button);
|
|
//container.setStackInSlot(button.getSlotNum(), button.buildIcon());
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Increment to the next page
|
|
*/
|
|
public void nextPage()
|
|
{
|
|
page++;
|
|
|
|
checkPageButtons();
|
|
}
|
|
|
|
/**
|
|
* Go back a previous page, if possible
|
|
*/
|
|
public void prevPage()
|
|
{
|
|
page--;
|
|
|
|
checkPageButtons();
|
|
}
|
|
|
|
/*
|
|
X X X X X X X X X
|
|
X X X X X X X X X
|
|
< 0 0 - @ + 0 0 >
|
|
*/
|
|
|
|
// LEGEND:
|
|
// X = ChestGUIButton
|
|
// < = Previous Page Button
|
|
// 0 = Empty Slot
|
|
// - = Remove / Subtract
|
|
// @ = Reset / Refresh
|
|
// + = Add
|
|
// > = Next Page
|
|
|
|
/**
|
|
* Sanity checks the page update
|
|
*/
|
|
public void checkPageButtons() {
|
|
int maxPerPage = 2 * 9;
|
|
int maxForPage = maxPerPage * page;
|
|
|
|
int totalButtons = buttons.size();
|
|
int totalPages = (totalButtons - 1) / maxPerPage; // Calculate total pages
|
|
|
|
// Ensure the current page is within bounds
|
|
if (page < 0) {
|
|
page = 0;
|
|
} else if (page > totalPages) {
|
|
page = totalPages;
|
|
}
|
|
|
|
// Perform additional logic if needed for displaying buttons on the GUI
|
|
// ...
|
|
|
|
updateContainerForPage(); // Update the container for the current page
|
|
}
|
|
|
|
/**
|
|
* Update the container with the page's buttons
|
|
*/
|
|
public void updateContainerForPage() {
|
|
int maxPerPage = 2 * 9;
|
|
int startIndex = maxPerPage * page;
|
|
int endIndex = Math.min(startIndex + maxPerPage, buttons.size());
|
|
|
|
// Logic to update the container based on buttons for the current page
|
|
ItemStackHandler pageContainer = new ItemStackHandler((9 * 3)); // Create a new container for the page
|
|
|
|
for (int i = startIndex; i < endIndex; i++) {
|
|
ChestGUIButton button = buttons.get(i);
|
|
|
|
// Calculate position relative to the page
|
|
int relativeIndex = i - startIndex;
|
|
int row = relativeIndex / 9;
|
|
int col = relativeIndex % 9;
|
|
|
|
Vector2i position = new Vector2i(row, col); // Create position for the button
|
|
button.withPosition(position); // Set the button's position
|
|
|
|
int slot = row * 9 + col; // Calculate the slot based on (row, column)
|
|
pageContainer.setStackInSlot(slot, button.buildIcon()); // Add button to the container
|
|
}
|
|
|
|
if(hasMultiPage())
|
|
{
|
|
if(!isFirstPage())
|
|
{
|
|
ItemStack backStack = new ItemStack(ModItems.CHESTGUI_BACK.get(), 1);
|
|
ChestGUIButton prev = new ChestGUIButton(backStack, ()->{
|
|
close();
|
|
prevPage();
|
|
open();
|
|
}, new Vector2i(3, 0));
|
|
|
|
pageContainer.setStackInSlot(prev.getSlotNum(), prev.buildIcon());
|
|
}
|
|
|
|
if(!isLastPage())
|
|
{
|
|
|
|
ItemStack forwardStack = new ItemStack(ModItems.CHESTGUI_FORWARD.get(), 1);
|
|
ChestGUIButton nxt = new ChestGUIButton(forwardStack, ()->{
|
|
close();
|
|
prevPage();
|
|
open();
|
|
}, new Vector2i(3, 8));
|
|
|
|
pageContainer.setStackInSlot(nxt.getSlotNum(), nxt.buildIcon());
|
|
}
|
|
}
|
|
|
|
if(hasRemove)
|
|
{
|
|
ItemStack remStack = new ItemStack(ModItems.CHESTGUI_REM.get(), 1);
|
|
|
|
ChestGUIButton rem = new ChestGUIButton(remStack, ()-> {
|
|
onRemove.run();
|
|
}, new Vector2i(3, 3));
|
|
|
|
pageContainer.setStackInSlot(rem.getSlotNum(), rem.buildIcon());
|
|
}
|
|
|
|
if(hasReset)
|
|
{
|
|
ItemStack resStack = new ItemStack(ModItems.CHESTGUI_RESET.get(), 1);
|
|
|
|
ChestGUIButton rem = new ChestGUIButton(resStack, ()-> {
|
|
onReset.run();
|
|
}, new Vector2i(3, 4));
|
|
|
|
pageContainer.setStackInSlot(rem.getSlotNum(), rem.buildIcon());
|
|
|
|
}
|
|
|
|
if(hasAdd)
|
|
{
|
|
|
|
ItemStack remStack = new ItemStack(ModItems.CHESTGUI_ADD.get(), 1);
|
|
|
|
ChestGUIButton rem = new ChestGUIButton(remStack, ()-> {
|
|
onAdd.run();
|
|
}, new Vector2i(3, 5));
|
|
|
|
pageContainer.setStackInSlot(rem.getSlotNum(), rem.buildIcon());
|
|
}
|
|
|
|
this.container = pageContainer; // Update the container with the new page content
|
|
}
|
|
public boolean isFirstPage() {
|
|
return page == 0;
|
|
}
|
|
|
|
public boolean isLastPage() {
|
|
int maxPerPage = 2 * 9;
|
|
int totalButtons = buttons.size();
|
|
int totalPages = (totalButtons - 1) / maxPerPage;
|
|
|
|
return page >= totalPages;
|
|
}
|
|
|
|
|
|
/**
|
|
* Checks if the number of buttons warrants adding the next/previous buttons to the utility row
|
|
* @return True if the number of buttons exceeds (2*9)
|
|
*/
|
|
public boolean hasMultiPage()
|
|
{
|
|
return (buttons.size() > (2*9));
|
|
}
|
|
|
|
public ChestGUI withTitle(String title)
|
|
{
|
|
MenuTitle = title;
|
|
|
|
return this;
|
|
}
|
|
|
|
public static ChestGUI builder()
|
|
{
|
|
return new ChestGUI();
|
|
}
|
|
|
|
public ChestGUI withPlayer(UUID id)
|
|
{
|
|
player=id;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Open the GUI on the client
|
|
*/
|
|
public void open()
|
|
{
|
|
if(LibZontreck.CURRENT_SIDE == LogicalSide.SERVER)
|
|
{
|
|
MinecraftForge.EVENT_BUS.post(new OpenGUIEvent(id, player, this));
|
|
NetworkHooks.openScreen(ServerUtilities.getPlayerByID(player.toString()), new SimpleMenuProvider(ChestGUIMenu.getServerMenu(this), Component.literal((MenuTitle != "") ? MenuTitle : "No Title")));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send a signal to trigger the GUI to close on the server, then send a signal to the client to also close the interface
|
|
*/
|
|
public void close()
|
|
{
|
|
if(LibZontreck.CURRENT_SIDE == LogicalSide.SERVER)
|
|
{
|
|
MinecraftForge.EVENT_BUS.post(new CloseGUIEvent(this, ServerUtilities.getPlayerByID(player.toString())));
|
|
|
|
ModMessages.sendToPlayer(new S2CCloseChestGUI(), ServerUtilities.getPlayerByID(player.toString()));
|
|
}
|
|
}
|
|
|
|
public boolean isPlayer(UUID ID)
|
|
{
|
|
return player.equals(ID);
|
|
}
|
|
|
|
public ChestGUI withGUIId(ResourceLocation id)
|
|
{
|
|
this.id = id;
|
|
return this;
|
|
}
|
|
|
|
public boolean matches(ResourceLocation id)
|
|
{
|
|
return this.id.equals(id);
|
|
}
|
|
|
|
public void handleButtonClicked(int slot, Vector2 pos, Item item) {
|
|
for(ChestGUIButton button : buttons)
|
|
{
|
|
if(button.getSlotNum() == slot)
|
|
{
|
|
if(button.buildIcon().getItem() == item)
|
|
{
|
|
button.clicked();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean hasSlot(Vector2i slot)
|
|
{
|
|
for(ChestGUIButton btn : buttons)
|
|
{
|
|
if(btn.matchesSlot(slot))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public ChestGUIButton getSlot(Vector2i slot) {
|
|
if(hasSlot(slot))
|
|
{
|
|
for(ChestGUIButton btn : buttons)
|
|
{
|
|
if(btn.matchesSlot(slot))
|
|
{
|
|
return btn;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|