#3 Toggleable slots alpha introduction. TODO for me later: Try not to duplicate slot name and menu names if possible
Some checks failed
build / build (21) (push) Has been cancelled

This commit is contained in:
Jkibbels 2025-02-16 16:38:08 -05:00
parent 21ba86bbec
commit 79600e942f
16 changed files with 132 additions and 40 deletions

View File

@ -4,7 +4,7 @@ package jesse.keeblarcraft.gui.FactionBlockGUI;
import com.mojang.blaze3d.systems.RenderSystem;
import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.GuiMgr.FactionBlockScreenHandler;
import jesse.keeblarcraft.GuiMgr.Factions.FactionBlockScreenHandler;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.render.GameRenderer;

View File

@ -1,5 +1,6 @@
package jesse.keeblarcraft.gui.Generics;
import jesse.keeblarcraft.Utils.CommonStructures.Pair;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.ClickableWidget;
@ -8,12 +9,15 @@ import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
abstract public class ClickableLayer extends ClickableWidget {
private final Identifier texture;
private final Text layerName;
private final List<ClickableLayer> subLayers = new ArrayList<>();
private final Map<String, Boolean> drawSlots = new HashMap<>(); // layerName is used as menu name for the screen handler
protected abstract void appendClickableNarrations(NarrationMessageBuilder builder);
@ -28,17 +32,29 @@ abstract public class ClickableLayer extends ClickableWidget {
}
protected void ClearSubLayers() {
subLayers.clear();
this.subLayers.clear();
}
public List<ClickableLayer> GetSubLayers() {
return subLayers;
return this.subLayers;
}
public Map<String, Boolean> GetDrawableSlots() {
return this.drawSlots;
}
public void AddDrawableSlotByName(String slotName, boolean toggled) {
this.drawSlots.put(slotName, toggled);
}
public void ClearDrawableSlots() {
for (Map.Entry<String, Boolean> entry : this.drawSlots.entrySet()) {
entry.setValue(false);
}
}
// This will be called every draw frame
public void UpdateSubLayers() {
}
public void UpdateSubLayers() {}
@Override
public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) {

View File

@ -14,7 +14,7 @@ public class NewItemButton extends ClickableLayer {
super(texture, layerName, width, height, startX, startY);
// These values may be temporary
newItemMenu = new NewItemMenu(NEW_ITEM_MENU, Text.of("Add Item"), 32, 24, this.getX() + 20, this.getY() + 20);
newItemMenu = new NewItemMenu(NEW_ITEM_MENU, Text.of("add_item_menu"), 32, 24, this.getX() + 20, this.getY() + 20);
}
@Override

View File

@ -10,17 +10,19 @@ public class NewItemMenu extends ClickableLayer {
private boolean isOpen = false;
public NewItemMenu(Identifier texture, Text layerName, int width, int height, int startX, int startY) {
super(texture, layerName, width, height, startX, startY);
System.out.println("Item menu created at coordinates X Y: " + this.getX() + " " + this.getY());
// System.out.println("Item menu created at coordinates X Y: " + this.getX() + " " + this.getY());
}
public void CloseMenu() {
this.isOpen = false;
this.visible = false;
this.ClearDrawableSlots();
}
public void OpenMenu() {
this.visible = true;
this.isOpen = true;
this.AddDrawableSlotByName("add_item_slot", true);
}
public boolean IsOpen() {
@ -34,7 +36,8 @@ public class NewItemMenu extends ClickableLayer {
// TODO: top right of the image with a 5 pixel buffer
if (this.visible && Helper.WithinBounds((this.getX() + this.getWidth() - 5), this.getY(), 5, 5, x, y)) {
System.out.println("User clicked fake 'X' button");
this.isOpen = false;
// this.isOpen = false;
this.CloseMenu();
}
}

View File

@ -1,9 +1,8 @@
package jesse.keeblarcraft.gui.ShopKeeperGUI;
import jesse.keeblarcraft.GuiMgr.ShopKeeperHandler;
import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperHandler;
import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.ClientHelpers.Helper;
import jesse.keeblarcraft.Utils.CustomSlot;
import jesse.keeblarcraft.gui.Generics.ClickableLayer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
@ -13,6 +12,7 @@ import net.minecraft.util.Identifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ShopKeeperMenu extends HandledScreen<ShopKeeperHandler> {
private static final Identifier MENU_TEXTURE = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/shopkeeper_gui.jpeg");
@ -50,13 +50,15 @@ public class ShopKeeperMenu extends HandledScreen<ShopKeeperHandler> {
// context.drawTexture(NEW_ITEM_MENU, this.x, this.y, 0, 0, 32, 24);
// context.drawTexture(NEW_ITEM_MENU, this.x, this.y, 0, 0, 32, 24, 32, 24);
// this.getScreenHandler().ShowSlot(Text.of("test"));
// this.getScreenHandler().showSlot("new_item", "add_item_slot");
for (ClickableLayer layer : layers) {
layer.renderButton(context, mouseX, mouseY, delta);
ToggleSlots(layer.GetLayerName().getString(), layer.GetDrawableSlots());
for (ClickableLayer subLayer : layer.GetSubLayers()) {
subLayer.renderButton(context, mouseX, mouseY, delta);
ToggleSlots(subLayer.GetLayerName().getString(), subLayer.GetDrawableSlots());
}
// We only notify the parent to update sub layers. It must manage its own sub layers
@ -64,6 +66,18 @@ public class ShopKeeperMenu extends HandledScreen<ShopKeeperHandler> {
}
}
private void ToggleSlots(String menuName, Map<String, Boolean> slotNames) {
for (Map.Entry<String, Boolean> slot : slotNames.entrySet()) {
if (slot.getValue()) {
System.out.println("Attempting to turn slot " + slot.getKey() + " to value " + slot.getValue());
this.getScreenHandler().showSlot(menuName, slot.getKey());
} else {
System.out.println("Attempting to turn slot " + slot.getKey() + " to value " + slot.getValue());
this.getScreenHandler().hideSlot(menuName, slot.getKey());
}
}
}
// Takes an image and adds it to the background draw list and saves coordinates to return to a callback if it is clicked
private void AddNewButton(Identifier iconId, Text layerName, int drawX, int drawY, int imgWidth, int imgHeight) {
layers.add(new NewItemButton(iconId, layerName, imgWidth, imgHeight, drawX, drawY));

View File

@ -1,8 +1,7 @@
package jesse.keeblarcraft.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import jesse.keeblarcraft.GuiMgr.ShopKeeperHandler;
import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperHandler;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.SetTradeOffersS2CPacket;
import net.minecraft.screen.ScreenHandler;

View File

@ -11,7 +11,7 @@ import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerEnteredBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerExitedBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerInBaseCallback;
import jesse.keeblarcraft.FactionMgr.FactionTier.FactionTierEnum;
import jesse.keeblarcraft.GuiMgr.FactionBlockScreenHandler;
import jesse.keeblarcraft.GuiMgr.Factions.FactionBlockScreenHandler;
import jesse.keeblarcraft.Utils.CommonStructures.Position3d;
import jesse.keeblarcraft.world.ImplementedInventory;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;

View File

@ -1,6 +1,6 @@
package jesse.keeblarcraft.Entities;
import jesse.keeblarcraft.GuiMgr.ShopKeeperHandler;
import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperHandler;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.entity.player.PlayerEntity;

View File

@ -1,6 +1,7 @@
package jesse.keeblarcraft.GuiMgr;
package jesse.keeblarcraft.GuiMgr.Factions;
import jesse.keeblarcraft.CustomBlocks.BlockEntities.FactionBlockEntity;
import jesse.keeblarcraft.GuiMgr.ScreenHandlerRegistration;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;

View File

@ -1,5 +1,7 @@
package jesse.keeblarcraft.GuiMgr;
import jesse.keeblarcraft.GuiMgr.Factions.FactionBlockScreenHandler;
import jesse.keeblarcraft.GuiMgr.ShopKeeper.ShopKeeperHandler;
import jesse.keeblarcraft.Keeblarcraft;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType;
import net.minecraft.registry.Registries;

View File

@ -1,5 +1,6 @@
package jesse.keeblarcraft.GuiMgr;
package jesse.keeblarcraft.GuiMgr.ShopKeeper;
import jesse.keeblarcraft.GuiMgr.ScreenHandlerRegistration;
import jesse.keeblarcraft.Utils.CustomSlot;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
@ -18,11 +19,12 @@ import java.util.Map;
public class ShopKeeperHandler extends ScreenHandler {
private Merchant merchant;
private MerchantInventory merchantInventory;
boolean canRefreshTrades = false;
boolean isLeveledMerchant = false;
int levelAmount = 0;
int merchantExperience = 0;
Map<Text, Integer> slotIdByName = new HashMap<>();
private boolean canRefreshTrades = false;
private boolean isLeveledMerchant = false;
private int levelAmount = 0;
private int merchantExperience = 0;
private Map<Text, Integer> slotIdByName = new HashMap<>();
ShopKeeperSlots allSlots = new ShopKeeperSlots();
public ShopKeeperHandler(int syncId, PlayerInventory playerInventory) {
this(syncId, playerInventory, new SimpleMerchant(playerInventory.player));
@ -32,26 +34,29 @@ public class ShopKeeperHandler extends ScreenHandler {
super(ScreenHandlerRegistration.SHOP_KEEPER_HANDLER_SCREEN_HANDLER_TYPE, syncId);
this.merchant = merchant;
this.merchantInventory = new MerchantInventory(merchant);
RegisterSlots();
// Add slots below
// this.addSlot(new Slot(this.merchantInventory, 0, 136, 37));
this.addSlot(new CustomSlot(this.merchantInventory, 0, Text.of("test"), 136, 37), Text.of("test"));
// this.addSlot(new CustomSlot(this.merchantInventory, 0, 136, 37), Text.of("test"));
}
public void HideSlot(Text slotName) {
this.getSlot(Text.of("test")).setEnabled(false);
public void RegisterSlots() {
CustomSlot slotOne = new CustomSlot(this.merchantInventory, 0, 136, 37);
allSlots.AddSlot("add_item_menu", "add_item_slot", slotOne);
this.addSlot(slotOne);
}
public void ShowSlot(Text slotName) {
this.getSlot(Text.of("test")).setEnabled(true);
public void showSlot(String menuName, String slotName) {
allSlots.ShowSlot(menuName, slotName);
}
protected void addSlot(CustomSlot slot, Text name) {
super.addSlot(slot);
slotIdByName.put(name, slot.id);
public void hideSlot(String menuName, String slotName) {
allSlots.HideSlot(menuName, slotName);
}
public CustomSlot getSlot(Text name) {
System.out.println("Printing slot map");
for (Slot slot : super.slots) {
System.out.println("Found slot with id: " + slot.id);

View File

@ -0,0 +1,57 @@
package jesse.keeblarcraft.GuiMgr.ShopKeeper;
import jesse.keeblarcraft.Utils.CustomSlot;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// Until I find the will and way to mixin slots to be able to be removed (i.e: not backed by an Inventory) I am patching
// slots in its own registration class (like ShopKeeperSlots). The time to do the mixin stuff far exceeds what is worth
// it for the time being.
public class ShopKeeperSlots {
private final Map<String, HashMap<String, CustomSlot>> shopKeeperSlots = new HashMap<>();
public ShopKeeperSlots() {}
public void AddSlot(String menuName, String slotName, CustomSlot newSlot) {
if (!shopKeeperSlots.containsKey(slotName)) {
shopKeeperSlots.put(menuName, new HashMap<>());
shopKeeperSlots.get(menuName).put(slotName, newSlot);
} else {
shopKeeperSlots.get(menuName).put(slotName, newSlot);
}
}
public HashMap<String, CustomSlot> GetSlotsByMenu(String menu) {
return this.shopKeeperSlots.get(menu);
}
public void HideSlot(String menuName, String slotName) {
for (Map.Entry<String, HashMap<String, CustomSlot>> entry : shopKeeperSlots.entrySet()) {
if (entry.getKey().equals(menuName)) {
for (Map.Entry<String, CustomSlot> menuSlots : entry.getValue().entrySet()) {
if (menuSlots.getKey().equals(slotName)) {
menuSlots.getValue().setEnabled(false);
}
}
break;
}
}
}
public void ShowSlot(String menuName, String slotName) {
for (Map.Entry<String, HashMap<String, CustomSlot>> entry : shopKeeperSlots.entrySet()) {
// System.out.println("Menu name: " + entry.getKey());
if (entry.getKey().equals(menuName)) {
for (Map.Entry<String, CustomSlot> menuSlots : entry.getValue().entrySet()) {
// System.out.println("Slot name: " + menuSlots.getKey());
if (menuSlots.getKey().equals(slotName)) {
menuSlots.getValue().setEnabled(true);
}
}
break;
}
}
}
}

View File

@ -1,4 +1,4 @@
package jesse.keeblarcraft.GuiMgr;
package jesse.keeblarcraft.GuiMgr.SkillTree;
import jesse.keeblarcraft.Keeblarcraft;
import net.minecraft.entity.player.PlayerEntity;

View File

@ -38,7 +38,7 @@ import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent;
import jesse.keeblarcraft.EventMgr.PlayerJoinListener;
import jesse.keeblarcraft.EventMgr.ServerTickListener;
import jesse.keeblarcraft.GuiMgr.ScreenHandlerRegistration;
import jesse.keeblarcraft.GuiMgr.TreeHandler;
import jesse.keeblarcraft.GuiMgr.SkillTree.TreeHandler;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
import jesse.keeblarcraft.Utils.Setup;

View File

@ -3,6 +3,7 @@ package jesse.keeblarcraft.Utils.CommonStructures;
public class Pair<KEY, VALUE> {
KEY key;
VALUE value;
public Pair(KEY key, VALUE val) {
this.key = key;
this.value = val;

View File

@ -2,15 +2,9 @@ package jesse.keeblarcraft.Utils;
import net.minecraft.inventory.Inventory;
import net.minecraft.screen.slot.Slot;
import net.minecraft.text.Text;
public class CustomSlot extends Slot {
private boolean slotIsEnabled = false;
private Text slotId;
public CustomSlot(Inventory inventory, int index, Text slotName, int x, int y) {
super(inventory, index, x, y);
}
public CustomSlot(Inventory inventory, int index, int x, int y) {
super(inventory, index, x, y);