Finish implementing initial chest-gui interface API

This commit is contained in:
zontreck 2024-01-02 00:28:17 -07:00
parent b034b2b388
commit 848b6f495b
9 changed files with 108 additions and 110 deletions

View file

@ -10,7 +10,6 @@ import java.util.UUID;
import dev.zontreck.ariaslib.util.DelayedExecutorService; import dev.zontreck.ariaslib.util.DelayedExecutorService;
import dev.zontreck.eventsbus.Bus; import dev.zontreck.eventsbus.Bus;
import dev.zontreck.libzontreck.chestgui.ChestGUIRegistry;
import dev.zontreck.libzontreck.currency.Bank; import dev.zontreck.libzontreck.currency.Bank;
import dev.zontreck.libzontreck.currency.CurrencyHelper; import dev.zontreck.libzontreck.currency.CurrencyHelper;
import dev.zontreck.libzontreck.menus.ChestGUIScreen; import dev.zontreck.libzontreck.menus.ChestGUIScreen;
@ -84,7 +83,6 @@ public class LibZontreck {
MinecraftForge.EVENT_BUS.register(new ForgeEventHandlers()); MinecraftForge.EVENT_BUS.register(new ForgeEventHandlers());
MinecraftForge.EVENT_BUS.register(new Commands()); MinecraftForge.EVENT_BUS.register(new Commands());
MinecraftForge.EVENT_BUS.register(new NetworkEvents()); MinecraftForge.EVENT_BUS.register(new NetworkEvents());
MinecraftForge.EVENT_BUS.register(new ChestGUIRegistry());
Bus.Reset(); Bus.Reset();

View file

@ -1,14 +1,20 @@
package dev.zontreck.libzontreck.chestgui; package dev.zontreck.libzontreck.chestgui;
import dev.zontreck.libzontreck.LibZontreck; import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.menus.ChestGUIMenu;
import dev.zontreck.libzontreck.networking.packets.ChestGUIOpenC2S; import dev.zontreck.libzontreck.networking.packets.ChestGUIOpenC2S;
import dev.zontreck.libzontreck.util.ServerUtilities;
import dev.zontreck.libzontreck.vectors.Vector2; import dev.zontreck.libzontreck.vectors.Vector2;
import dev.zontreck.libzontreck.vectors.Vector2i;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.network.NetworkHooks;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -54,7 +60,7 @@ public class ChestGUI
{ {
if(LibZontreck.CURRENT_SIDE == LogicalSide.SERVER) if(LibZontreck.CURRENT_SIDE == LogicalSide.SERVER)
{ {
NetworkHooks.openScreen(ServerUtilities.getPlayerByID(player.toString()), new SimpleMenuProvider(ChestGUIMenu.getServerMenu(this), Component.literal(MenuTitle)));
} }
} }
@ -87,4 +93,31 @@ public class ChestGUI
} }
} }
} }
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;
}
} }

View file

@ -4,10 +4,12 @@ import dev.zontreck.libzontreck.lore.LoreContainer;
import dev.zontreck.libzontreck.lore.LoreEntry; import dev.zontreck.libzontreck.lore.LoreEntry;
import dev.zontreck.libzontreck.util.ChatHelpers; import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.vectors.Vector2; import dev.zontreck.libzontreck.vectors.Vector2;
import dev.zontreck.libzontreck.vectors.Vector2i;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.NbtUtils;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.ItemStackHandler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -24,9 +26,9 @@ public class ChestGUIButton
/** /**
* Position is Row (X), Column (Y) * Position is Row (X), Column (Y)
*/ */
private Vector2 position; private Vector2i position;
public ChestGUIButton(Item icon, String name, Runnable callback, Vector2 position) public ChestGUIButton(Item icon, String name, Runnable callback, Vector2i position)
{ {
this.icon = icon; this.icon = icon;
this.name = name; this.name = name;
@ -35,7 +37,7 @@ public class ChestGUIButton
tooltipInfo = new ArrayList<>(); tooltipInfo = new ArrayList<>();
} }
public ChestGUIButton(ItemStack existing, Runnable callback, Vector2 position) public ChestGUIButton(ItemStack existing, Runnable callback, Vector2i position)
{ {
this.callback = callback; this.callback = callback;
this.position = position; this.position = position;
@ -76,6 +78,15 @@ public class ChestGUIButton
return ret; return ret;
} }
public ItemStackHandler buildIconStack()
{
ItemStack stack = buildIcon();
ItemStackHandler st = new ItemStackHandler(1);
st.setStackInSlot(0, stack);
return st;
}
/** /**
* Adds a line to the Lore (Tooltip) of the button * Adds a line to the Lore (Tooltip) of the button
* @param line The line to add * @param line The line to add
@ -88,6 +99,16 @@ public class ChestGUIButton
return this; return this;
} }
/**
* Check if the slot's row and column match (X,Y)
* @param slot
* @return True if matches
*/
public boolean matchesSlot(Vector2i slot)
{
return position.same(slot);
}
/** /**
* Returns the slot number in the 32 item grid * Returns the slot number in the 32 item grid
* @return Slot number from vector (row, column) * @return Slot number from vector (row, column)

View file

@ -1,34 +0,0 @@
package dev.zontreck.libzontreck.chestgui;
import dev.zontreck.libzontreck.events.GUIButtonClickedEvent;
import dev.zontreck.libzontreck.vectors.Vector2;
import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import java.util.ArrayList;
import java.util.List;
public class ChestGUIRegistry
{
public static List<ChestGUI> ActiveGUIs = new ArrayList<>();
@SubscribeEvent
public void onChestGUIButtonClicked(GUIButtonClickedEvent event)
{
for(ChestGUI gui : ActiveGUIs)
{
if(gui.isPlayer(event.player))
{
if(gui.matches(event.id))
{
// Handle the click now
CompoundTag tag = event.stack.getTag();
Vector2 pos = new Vector2(tag.getCompound("pos"));
int slot = tag.getInt("slot");
gui.handleButtonClicked(slot, pos, event.stack.getItem());
}
}
}
}
}

View file

@ -3,8 +3,14 @@ package dev.zontreck.libzontreck.commands;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import dev.zontreck.libzontreck.chestgui.ChestGUI;
import dev.zontreck.libzontreck.chestgui.ChestGUIButton;
import dev.zontreck.libzontreck.util.heads.CreditsEntry;
import dev.zontreck.libzontreck.util.heads.HeadCache;
import dev.zontreck.libzontreck.vectors.Vector2i;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
public class CreditsCommand { public class CreditsCommand {
@ -18,6 +24,22 @@ public class CreditsCommand {
if(source.getEntity() instanceof Player) if(source.getEntity() instanceof Player)
{ {
// OK. // OK.
ChestGUI gui = ChestGUI.builder().withGUIId(new ResourceLocation("ariasmods", "credits-gui")).withPlayer(source.getEntity().getUUID());
Vector2i pos = new Vector2i();
for(CreditsEntry entry : HeadCache.CREDITS)
{
gui = gui.withButton(new ChestGUIButton(entry.compile(), ()->{}, pos));
pos.y++;
if(pos.y>=9)
{
pos.x++;
pos.y=0;
}
}
gui.open();

View file

@ -3,8 +3,6 @@ package dev.zontreck.libzontreck.events;
import dev.zontreck.ariaslib.terminal.Task; import dev.zontreck.ariaslib.terminal.Task;
import dev.zontreck.ariaslib.util.DelayedExecutorService; import dev.zontreck.ariaslib.util.DelayedExecutorService;
import dev.zontreck.libzontreck.LibZontreck; import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.currency.Account;
import dev.zontreck.libzontreck.currency.Bank;
import dev.zontreck.libzontreck.exceptions.InvalidSideException; import dev.zontreck.libzontreck.exceptions.InvalidSideException;
import dev.zontreck.libzontreck.memory.PlayerContainer; import dev.zontreck.libzontreck.memory.PlayerContainer;
import dev.zontreck.libzontreck.networking.ModMessages; import dev.zontreck.libzontreck.networking.ModMessages;

View file

@ -2,7 +2,9 @@ package dev.zontreck.libzontreck.menus;
import dev.zontreck.libzontreck.chestgui.ChestGUI; import dev.zontreck.libzontreck.chestgui.ChestGUI;
import dev.zontreck.libzontreck.chestgui.ChestGUIButton; import dev.zontreck.libzontreck.chestgui.ChestGUIButton;
import dev.zontreck.libzontreck.dynamicchest.ReadOnlyItemStackHandler;
import dev.zontreck.libzontreck.types.ModMenuTypes; import dev.zontreck.libzontreck.types.ModMenuTypes;
import dev.zontreck.libzontreck.vectors.Vector2i;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
@ -12,22 +14,42 @@ import net.minecraft.world.inventory.MenuConstructor;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.SlotItemHandler;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class ChestGUIMenu extends AbstractContainerMenu public class ChestGUIMenu extends AbstractContainerMenu
{ {
private ChestGUI gui; public final ChestGUI gui;
public ChestGUIMenu(int id, Inventory playerInv, FriendlyByteBuf buf) public ChestGUIMenu(int id, Inventory playerInv, FriendlyByteBuf buf)
{ {
this(id, playerInv, new ItemStackHandler(3*9), BlockPos.ZERO, playerInv.player, null); this(id, playerInv, BlockPos.ZERO, playerInv.player, null);
} }
public ChestGUIMenu(int id, Inventory playerInv, ItemStackHandler inv, BlockPos position, Player player, ChestGUI gui) public ChestGUIMenu(int id, Inventory playerInv, BlockPos position, Player player, ChestGUI gui)
{ {
super(ModMenuTypes.CHEST_GUI_MENU.get(), id); super(ModMenuTypes.CHEST_GUI_MENU.get(), id);
this.gui = gui; this.gui = gui;
if(gui == null)return;
int slotSize = 18;
int startX = 15;
int startY = 15;
for (int row = 0; row < 3; row++)
{
for(int column=0;column<9;column++)
{
Vector2i slot = new Vector2i(row, column);
ChestGUIButton btn = gui.getSlot(slot);
if(gui.hasSlot(slot))
{
addSlot(new SlotItemHandler(new ReadOnlyItemStackHandler(btn.buildIconStack(), btn::clicked), row*9 + column, startX + column * slotSize, startY + row * slotSize));
}
}
}
} }
@Override @Override
@ -40,8 +62,8 @@ public class ChestGUIMenu extends AbstractContainerMenu
return true; return true;
} }
public static MenuConstructor getServerMenu(ItemStackHandler inventory) public static MenuConstructor getServerMenu(ChestGUI gui)
{ {
return (id, playerInv, player) -> new ChestGUIMenu(id, playerInv, inventory, BlockPos.ZERO, player, null); return (id, playerInv, player) -> new ChestGUIMenu(id, playerInv, BlockPos.ZERO, player, gui);
} }
} }

View file

@ -2,7 +2,6 @@ package dev.zontreck.libzontreck.networking;
import dev.zontreck.libzontreck.LibZontreck; import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.events.RegisterPacketsEvent; import dev.zontreck.libzontreck.events.RegisterPacketsEvent;
import dev.zontreck.libzontreck.networking.packets.C2SChestGUIButtonClicked;
import dev.zontreck.libzontreck.networking.packets.ChestGUIOpenC2S; import dev.zontreck.libzontreck.networking.packets.ChestGUIOpenC2S;
import dev.zontreck.libzontreck.networking.packets.IPacket; import dev.zontreck.libzontreck.networking.packets.IPacket;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -52,12 +51,6 @@ public class ModMessages {
.consumerMainThread(ChestGUIOpenC2S::handle) .consumerMainThread(ChestGUIOpenC2S::handle)
.add(); .add();
net.messageBuilder(C2SChestGUIButtonClicked.class, PACKET_ID.getAndIncrement(), NetworkDirection.PLAY_TO_SERVER)
.decoder(C2SChestGUIButtonClicked::new)
.encoder(C2SChestGUIButtonClicked::toBytes)
.consumerMainThread(C2SChestGUIButtonClicked::handle)
.add();
} }

View file

@ -1,55 +0,0 @@
package dev.zontreck.libzontreck.networking.packets;
import dev.zontreck.libzontreck.events.GUIButtonClickedEvent;
import dev.zontreck.libzontreck.vectors.Vector2;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.network.NetworkEvent;
import java.util.UUID;
import java.util.function.Supplier;
public class C2SChestGUIButtonClicked
{
private ItemStack stack;
private ResourceLocation id;
private UUID player;
public C2SChestGUIButtonClicked(ItemStack stack, ResourceLocation id)
{
this.stack = stack;
this.id = id;
player = Minecraft.getInstance().player.getUUID();
}
public C2SChestGUIButtonClicked(FriendlyByteBuf buf)
{
stack = buf.readItem();
id = buf.readResourceLocation();
}
public void toBytes(FriendlyByteBuf buf)
{
buf.writeItem(stack);
buf.writeResourceLocation(id);
}
public boolean handle(Supplier<NetworkEvent.Context> ctx)
{
NetworkEvent.Context context = ctx.get();
context.enqueueWork(()->{
// We're on the server now.
MinecraftForge.EVENT_BUS.post(new GUIButtonClickedEvent(stack, id, player));
});
return true;
}
}