This repository has been archived on 2024-10-31. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
LibZontreck/src/main/java/dev/zontreck/libzontreck/chestgui/ChestGUI.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;
}
}