diff --git a/src/client/java/jesse/keeblarcraft/ClientHelpers/Helper.java b/src/client/java/jesse/keeblarcraft/ClientHelpers/Helper.java new file mode 100644 index 0000000..210ab73 --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/ClientHelpers/Helper.java @@ -0,0 +1,9 @@ +package jesse.keeblarcraft.ClientHelpers; + +public class Helper { + public static boolean WithinBounds(double x, double y, double w, double h, double clickX, double clickY) { +// System.out.println("Mouse click X Y: " + clickX + " " + clickY); +// System.out.println("Rectangle X Y W H: " + x + " " + y + " " + w + " " + h); + return (clickX >= x) && (clickX <= x + w) && (clickY >= y) && (clickY <= y + h); + } +} diff --git a/src/client/java/jesse/keeblarcraft/Entities/ShopKeeperModel.java b/src/client/java/jesse/keeblarcraft/Entities/ShopKeeperModel.java new file mode 100644 index 0000000..388fe0c --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/Entities/ShopKeeperModel.java @@ -0,0 +1,35 @@ +package jesse.keeblarcraft.Entities; + +import net.minecraft.client.model.*; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.model.EntityModelPartNames; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.include.com.google.common.collect.ImmutableList; + +public class ShopKeeperModel extends EntityModel { + private final ModelPart base; + public ShopKeeperModel(ModelPart modelPart) { + this.base = modelPart.getChild(EntityModelPartNames.CUBE); + } + + public static TexturedModelData getTexturedModelData() { + ModelData modelData = new ModelData(); + ModelPartData modelPartData = modelData.getRoot(); + modelPartData.addChild(EntityModelPartNames.CUBE, ModelPartBuilder.create().uv(0, 0).cuboid(-6F, 12F, -6F, 12F, 12F, 12F), + ModelTransform.pivot(0F, 0F, 0F)); + return TexturedModelData.of(modelData, 64, 64); + } + + @Override + public void setAngles(ShopKeeper entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) { + + } + + @Override + public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha) { + ImmutableList.of(this.base).forEach((modelRenderer) -> { + modelRenderer.render(matrices, vertices, light, overlay, red, green, blue, alpha); + }); + } +} diff --git a/src/main/java/jesse/keeblarcraft/GuiMgr/Entities/ShopKeeperRenderer.java b/src/client/java/jesse/keeblarcraft/Entities/ShopKeeperRenderer.java similarity index 87% rename from src/main/java/jesse/keeblarcraft/GuiMgr/Entities/ShopKeeperRenderer.java rename to src/client/java/jesse/keeblarcraft/Entities/ShopKeeperRenderer.java index 8592a8a..346db3c 100644 --- a/src/main/java/jesse/keeblarcraft/GuiMgr/Entities/ShopKeeperRenderer.java +++ b/src/client/java/jesse/keeblarcraft/Entities/ShopKeeperRenderer.java @@ -1,4 +1,4 @@ -package jesse.keeblarcraft.GuiMgr.Entities; +package jesse.keeblarcraft.Entities; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.VillagerEntityRenderer; diff --git a/src/client/java/jesse/keeblarcraft/KeeblarcraftClient.java b/src/client/java/jesse/keeblarcraft/KeeblarcraftClient.java index f3c3ace..a92dbc2 100644 --- a/src/client/java/jesse/keeblarcraft/KeeblarcraftClient.java +++ b/src/client/java/jesse/keeblarcraft/KeeblarcraftClient.java @@ -1,28 +1,27 @@ package jesse.keeblarcraft; import jesse.keeblarcraft.Entities.EntityRegistration; -import jesse.keeblarcraft.GuiMgr.Entities.ShopKeeperRenderer; +import jesse.keeblarcraft.Entities.ShopKeeperModel; import jesse.keeblarcraft.gui.ClientHandlers; import jesse.keeblarcraft.Shortcuts.ShortcutManager; +import jesse.keeblarcraft.Entities.ShopKeeperRenderer; import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; import net.minecraft.client.render.entity.model.EntityModelLayer; import net.minecraft.util.Identifier; public class KeeblarcraftClient implements ClientModInitializer { public static final EntityModelLayer SHOP_KEEPER_LAYER = new EntityModelLayer(new Identifier("textures/entity/villager/villager.png"), "VILLAGE_ENTITY_MODEL_LAYER"); + @Override public void onInitializeClient() { ShortcutManager.RegisterKeybinds(); ClientHandlers.RegisterHandlers(); -// EntityRendererRegistry.INSTANCE.register(EntityRegistration.SHOP_KEEPER_ENTITY_TYPE, (context) -> { -// return new ShopKeeperRenderer(context); -// }); - - // ScreenManager.GetInstance(); - // ScreenManager.AddWidget(TreeWidget.class, 10); + EntityRendererRegistry.register(EntityRegistration.SHOP_KEEPER_ENTITY_TYPE, ShopKeeperRenderer::new); + EntityModelLayerRegistry.registerModelLayer(SHOP_KEEPER_LAYER, ShopKeeperModel::getTexturedModelData); } } diff --git a/src/client/java/jesse/keeblarcraft/Shortcuts/ShortcutManager.java b/src/client/java/jesse/keeblarcraft/Shortcuts/ShortcutManager.java index 218ceb7..2fb17f8 100644 --- a/src/client/java/jesse/keeblarcraft/Shortcuts/ShortcutManager.java +++ b/src/client/java/jesse/keeblarcraft/Shortcuts/ShortcutManager.java @@ -11,8 +11,6 @@ package jesse.keeblarcraft.Shortcuts; import org.lwjgl.glfw.GLFW; -// import jesse.keeblarcraft.Keeblarcraft; -// import jesse.keeblarcraft.gui.ScreenManager; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.MinecraftClient; @@ -25,7 +23,6 @@ public class ShortcutManager { private static KeyBinding skillTreeShortcut; private static KeyBinding globalConfig; private static Boolean toggleTreeGui = true; // Initialized to true for first time pressing keybind to actually display gui - // private static ScreenManager treeGui = null; ///////////////////////////////////////////////////////////////////////////// /// @fn RegisterKeybinds diff --git a/src/client/java/jesse/keeblarcraft/gui/ClientHandlers.java b/src/client/java/jesse/keeblarcraft/gui/ClientHandlers.java index 079ca75..d70189e 100644 --- a/src/client/java/jesse/keeblarcraft/gui/ClientHandlers.java +++ b/src/client/java/jesse/keeblarcraft/gui/ClientHandlers.java @@ -1,7 +1,8 @@ package jesse.keeblarcraft.gui; -import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.GuiMgr.ScreenHandlerRegistration; +import jesse.keeblarcraft.gui.FactionBlockGUI.FactionBlockScreen; +import jesse.keeblarcraft.gui.ShopKeeperGUI.ShopKeeperMenu; import net.minecraft.client.gui.screen.ingame.HandledScreens; public class ClientHandlers { @@ -9,5 +10,6 @@ public class ClientHandlers { System.out.println("Registering tree handler screen"); // HandledScreens.register(Keeblarcraft.TREE_HANDLER, ScreenManager::new); HandledScreens.register(ScreenHandlerRegistration.FACTION_BLOCK_SCREEN_HANDLER, FactionBlockScreen::new); + HandledScreens.register(ScreenHandlerRegistration.SHOP_KEEPER_HANDLER_SCREEN_HANDLER_TYPE, ShopKeeperMenu::new); } } diff --git a/src/client/java/jesse/keeblarcraft/gui/FactionBlockScreen.java b/src/client/java/jesse/keeblarcraft/gui/FactionBlockGUI/FactionBlockScreen.java similarity index 88% rename from src/client/java/jesse/keeblarcraft/gui/FactionBlockScreen.java rename to src/client/java/jesse/keeblarcraft/gui/FactionBlockGUI/FactionBlockScreen.java index bf85663..a54f95f 100644 --- a/src/client/java/jesse/keeblarcraft/gui/FactionBlockScreen.java +++ b/src/client/java/jesse/keeblarcraft/gui/FactionBlockGUI/FactionBlockScreen.java @@ -1,4 +1,4 @@ -package jesse.keeblarcraft.gui; +package jesse.keeblarcraft.gui.FactionBlockGUI; import com.mojang.blaze3d.systems.RenderSystem; @@ -36,10 +36,7 @@ public class FactionBlockScreen extends HandledScreen this.backgroundHeight = 256; this.backgroundWidth = 256; - int x = (width - backgroundWidth) / 2; - int y = (height - backgroundHeight) / 2; - context.drawTexture(TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight); } @Override diff --git a/src/client/java/jesse/keeblarcraft/gui/GenericLayerT.java b/src/client/java/jesse/keeblarcraft/gui/GenericLayerT.java deleted file mode 100644 index ffb8481..0000000 --- a/src/client/java/jesse/keeblarcraft/gui/GenericLayerT.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * GenericLayerT - * - * GenericLayerT is the class that all layers must inherit from in order to be drawn. This allows for the GUI to properly - * draw the layers on which you want your canvas to exist! - * - * -*/ - -package jesse.keeblarcraft.gui; - -import jesse.keeblarcraft.Utils.CommonStructures.Position2d; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.text.Text; - -abstract public class GenericLayerT extends ClickableWidget { - // These are the box bounds of the widget - public int startX; - public int startY; - public int endX; - public int endY; - - public GenericLayerT() { - // default constructor - super(0, 0, 0, 0, Text.of("")); - } - - ///////////////////////////////////////////////////////////////////////////// - /// @fn GenericLayerT - /// - /// @brief Constructor for class. This is setup directly by the screen - /// manager object and it is not recommended to change the x/y - /// positions or you may break the relation of your widget to - /// others on the screen at the same time! - ///////////////////////////////////////////////////////////////////////////// - public GenericLayerT(int x, int y, int width, int height, Text message) { - super(x, y, width, height, message); - } - - ///////////////////////////////////////////////////////////////////////////// - /// @fn DrawLayer - /// - /// @brief Draw on a layer! This is an early implementation of being - /// able to choose the layer you are drawing on and making sure - /// you can customize which layer your context will draw on. - /// This will be called by the overall screen manager so the - /// layer id will be passed in. You will need to handle the layer - /// id yourself. - /// - /// @note It is possible to get passed any layer id and you handle each - /// layer respectively; however, it is possible to draw on the - /// wrong layer if handled wrong. For example, you could be - /// passed layer '3' but this function is called for every layer - /// drawn on screen; so you must handle this to only draw on a - /// specific layer. Be careful! - ///////////////////////////////////////////////////////////////////////////// - public abstract void DrawLayer(DrawContext context, int layer); - - public void UpdateAnchorValues(int x, int y) { - this.startX = x; - this.startY = y; - } - - // Calculated based on center of box values - public Position2d GetScreenCenter() { - return new Position2d((this.endX - this.startX) / 2, (this.endY - this.startY) / 2); - } - - public abstract void renderButton(DrawContext context, int mouseX, int mouseY, float delta); - protected abstract void appendClickableNarrations(NarrationMessageBuilder builder); -} \ No newline at end of file diff --git a/src/client/java/jesse/keeblarcraft/gui/Generics/ClickableLayer.java b/src/client/java/jesse/keeblarcraft/gui/Generics/ClickableLayer.java new file mode 100644 index 0000000..949bace --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/gui/Generics/ClickableLayer.java @@ -0,0 +1,55 @@ +package jesse.keeblarcraft.gui.Generics; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.util.ArrayList; +import java.util.List; + +abstract public class ClickableLayer extends ClickableWidget { + private final Identifier texture; + private final Text layerName; + private final List subLayers = new ArrayList<>(); + + protected abstract void appendClickableNarrations(NarrationMessageBuilder builder); + + public ClickableLayer(Identifier texture, Text layerName, int width, int height, int startX, int startY) { + super(startX, startY, width, height, Text.empty()); + this.texture = texture; + this.layerName = layerName; + } + + protected void AddSubLayer(ClickableLayer newLayer) { + subLayers.add(newLayer); + } + + protected void ClearSubLayers() { + subLayers.clear(); + } + + public List GetSubLayers() { + return subLayers; + } + + // This will be called every draw frame + public void UpdateSubLayers() { + + } + + @Override + public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) { + context.drawTexture(this.GetTexture(), this.getX(), this.getY(), 0, 0, this.getWidth(), this.getHeight(), this.getWidth(), this.getHeight()); + + } + + public Identifier GetTexture() { + return this.texture; + } + + public Text GetLayerName() { + return this.layerName; + } +} diff --git a/src/client/java/jesse/keeblarcraft/gui/ScreenManager.java b/src/client/java/jesse/keeblarcraft/gui/ScreenManager.java deleted file mode 100644 index 26688e3..0000000 --- a/src/client/java/jesse/keeblarcraft/gui/ScreenManager.java +++ /dev/null @@ -1,381 +0,0 @@ -// /* -// * -// * ScreenManager -// * -// * This is the screen manager for the global screen handler of `TreeHandler` type -// * Please note: `TreeHandler` is suited for a more broad range of things; however -// * its initial implementation is for the skill tree. It will be renamed to a more -// * generic name so this class is more obviously re-usable after its implementation -// * is complete AND we verify this class can be made more generic for it. Since this -// * is unknown, it will remain the name it has currently. -// * -// * -// */ - -// package jesse.keeblarcraft.gui; - -// import java.lang.reflect.InvocationTargetException; -// import java.util.ArrayList; -// import java.util.HashMap; -// import java.util.List; -// import java.util.Map.Entry; - -// import jesse.keeblarcraft.Keeblarcraft; -// import jesse.keeblarcraft.GuiMgr.TreeHandler; -// import net.minecraft.client.MinecraftClient; -// import net.minecraft.client.gui.DrawContext; -// import net.minecraft.client.gui.screen.Screen; -// import net.minecraft.client.gui.screen.ingame.HandledScreen; -// import net.minecraft.entity.player.PlayerInventory; -// import net.minecraft.text.Text; - -// // Client side renderer -// public class ScreenManager extends HandledScreen { -// private static ScreenManager static_inst; -// @SuppressWarnings("resource") -// private static PlayerInventory static_inventory = new PlayerInventory(null);// = MinecraftClient.getInstance().player.getInventory(); - -// public static ScreenManager GetInstance() { -// if (static_inst == null) { -// static_inst = new ScreenManager(Keeblarcraft.TREE_HANDLER.create(0, static_inventory), static_inventory, Text.of("Test")); -// } -// return static_inst; -// } - -// private static HashMap>> layerMap = new HashMap>>(); -// private static HashMap> layers = new HashMap>(); // key: layer id; value: list of classes to draw - -// // private TreeWidget treeWidget = null; -// private Screen parent; - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn ScreenManager -// /// -// /// @arg[in] handler is the TreeHandler (ScreenHandler) object -// /// -// /// @arg[in] inventory is the players inventory. Required by HandledScreen -// /// object however is unused currently in this Screen -// /// -// /// @arg[in] title is the title of the screen window -// /// -// /// @brief Class constructor -// ///////////////////////////////////////////////////////////////////////////// -// public ScreenManager(TreeHandler handler, PlayerInventory inventory, Text title) { -// super(handler, inventory, title); -// System.out.println("Called constructor of screen manager!"); - -// // Initialize layers in map -// // for (int i = 0; i < NUMBER_DRAW_LAYERS; i++) { -// // layers.put(i, new ArrayList>()); -// // } -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn AddParent -// /// -// /// @arg[in] parent is the parent screen object -// /// -// /// @brief Add a parent screen to the screen object. This is useful if -// /// you want to return to the previous screen when this one gets -// /// closed by the user -// ///////////////////////////////////////////////////////////////////////////// -// public void AddParent(Screen parent) { -// this.parent = parent; -// } - -// public static void AddWidget(Class widget, int drawLayer) { -// if (layerMap.containsKey(drawLayer)) { -// // Just append the widget to the draw layer -// var layerList = layerMap.get(drawLayer); -// layerList.add(widget); -// } else { -// // Brand new layer! -// layerMap.put(drawLayer, new ArrayList<>(List.of(widget))); -// } -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn init -// /// -// /// @brief Initialize method; called one-time to setup class variables -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public void init() { -// // initialize screen size to the global background picture -// this.width = MinecraftClient.getInstance().getWindow().getScaledWidth(); -// this.height = MinecraftClient.getInstance().getWindow().getScaledHeight(); - -// // Let's go through and initialize all the screen types now in our active memory -// for (Entry>> layerEntry : layerMap.entrySet()) { -// var layerList = layerEntry.getValue(); - -// layers.put(layerEntry.getKey(), new ArrayList<>()); -// var activeLayerList = layers.get(layerEntry.getKey()); -// for (int i = 0; i < layerList.size(); i++) { -// try { -// System.out.println("Attempting to initialize widget with information: LAYER I-VAL W H: " + layerEntry.getKey() + " " + i + " " + this.width + " " + this.height); -// GenericLayerT initializedWidget = layerList.get(i).getDeclaredConstructor(int.class, int.class, int.class, int.class, Text.class).newInstance(0, 0, this.width, this.height, Text.of("")); -// activeLayerList.add(initializedWidget); -// } catch (InstantiationException e) { -// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IntantiationException"); -// e.printStackTrace(); -// } catch (IllegalAccessException e) { -// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IllegalAccessException"); -// e.printStackTrace(); -// } catch (IllegalArgumentException e) { -// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IllegalArgumentException"); -// e.printStackTrace(); -// } catch (InvocationTargetException e) { -// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of InvocationTargetException"); -// e.printStackTrace(); -// } catch (NoSuchMethodException e) { -// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of NoSuchMethodException"); -// e.printStackTrace(); -// } catch (SecurityException e) { -// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of SecurityException"); -// e.printStackTrace(); -// } -// } -// } - - -// // Initialize child widgets with correct screen values so they can draw themselves in the right area on the screen (duh!) -// // treeWidget = new TreeWidget(GLOBAL_SCREEN_START_X + 24, GLOBAL_SCREEN_START_Y + 24, GLOBAL_SCREEN_WIDTH - 24, GLOBAL_SCREEN_HEIGHT - 24); -// // this.addDrawableChild(treeWidget); -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn render -// /// -// /// @arg[in] context is the drawing context of super class -// /// -// /// @arg[in] mouseX is passed to parent class but unused here -// /// -// /// @arg[in] mouseY is passed to parent class but unused here -// /// -// /// @brief Render is called every frame while the screen is open -// /// -// /// @note This is a pure abstract in parent and is required -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public void render(DrawContext context, int mouseX, int mouseY, float delta) { -// super.render(context, mouseX, mouseY, delta); // This takes care of calling drawBackground which calls DrawMainScreen -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn drawForeground -// /// -// /// @arg[in] context is the drawing context of super class -// /// -// /// @arg[in] mouseX is unused -// /// -// /// @arg[in] mouseY is unused -// /// -// /// @brief Draw foreground exists to draw the titles; however we -// /// intentionally override it so the superclass object does not -// /// draw the overlay over the background screen -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public void drawForeground(DrawContext context, int mouseX, int mouseY) { -// // We override this function to intentionally do nothing -// // If in the future we want, we would draw the foreground and TITLES with this! -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn close -// /// -// /// @brief Called when the screen closes -// /// -// /// @note This is a pure abstract in parent and is required -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public void close() { -// this.client.setScreen(parent); // return to previous screen or null -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn mouseDragged -// /// -// /// @arg[in] mouseX is x-axis position of original mouse click -// /// -// /// @arg[in] mouseY is y-axis position of original mouse click -// /// -// /// @arg[in] button is the int value of button pressed for mouse dragging -// /// -// /// @arg[in] deltaX is the change in the X position from the previous -// /// mouse click -// /// -// /// @arg[in] deltaY is the change in the Y position from the previous -// /// mouse click -// /// -// /// @brief The drag event is called on all widgets on the screen so -// /// long as the initial position of the drag is within the -// /// bounds of the widget box itself. Widgets themselves will need -// /// to handle any sub-widgets since the bound check is only -// /// there to verify if the event happened ANYWHERE within a -// /// widget box -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { -// super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); -// // UpdateAnchorValues(); - -// for (Entry> layerEntry : layers.entrySet()) { -// var layerList = layerEntry.getValue(); - -// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { -// var layer = layerList.get(layerListIterator); - -// // Check to make sure scroll is within the context of the widget then deliver information -// if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) { -// layer.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); -// } -// } -// } -// return true; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn mouseScrolled -// /// -// /// @arg[in] mouseX is the initial X position of the cursor on a scroll -// /// -// /// @arg[in] mouseY is the initial Y position of the cursor on a scroll -// /// -// /// @arg[in] amount is a normalized value that indicates scroll direction -// /// -// /// @brief The scroll event is called on all widgets on the screen so -// /// long as the initial position of the scroll is within the -// /// bounds of the widget box itself. Widgets themselves will need -// /// to handle any sub-widgets since the bound check is only -// /// there to verify if the event happened ANYWHERE within a -// /// widget box -// /// -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public boolean mouseScrolled(double mouseX, double mouseY, double amount) { -// super.mouseScrolled(mouseX, mouseY, amount); - -// for (Entry> layerEntry : layers.entrySet()) { -// var layerList = layerEntry.getValue(); - -// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { -// var layer = layerList.get(layerListIterator); - -// // Check to make sure scroll is within the context of the widget then deliver information -// if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) { -// layer.mouseScrolled(mouseX, mouseY, amount); -// } -// } -// } -// return true; // The parent function defines this to be boolean; but I have no idea when I would want to return false from this -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn mouseClicked -// /// -// /// @arg[in] mouseX is the initial X position of the mouse click event -// /// -// /// @arg[in] mouseY is the initial Y position of the mouse click event -// /// -// /// @arg[in] button is the mouse click button (left/right click value) -// /// -// /// @brief The mouse click is called on all widgets on the screen so -// /// long as the initial position of the click is within the -// /// bounds of the widget box itself. Widgets themselves will need -// /// to handle any sub-widgets since the bound check is only -// /// there to verify if the event happened ANYWHERE within a -// /// widget box -// /// -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public boolean mouseClicked(double mouseX, double mouseY, int button) { -// super.mouseClicked(mouseX, mouseY, button); - -// for (Entry> layerEntry : layers.entrySet()) { -// var layerList = layerEntry.getValue(); - -// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { -// var layer = layerList.get(layerListIterator); - -// // Check to make sure scroll is within the context of the widget then deliver information -// if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) { -// layer.mouseClicked(mouseX, mouseY, button); -// } -// } -// } -// return true; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn DrawLayers -// /// -// /// @arg[in] context is the global drawing context for the screen -// /// -// /// @arg[in] delta is passed in from background draw -// /// -// /// @brief This is the primary drawing function so that all the texture -// /// draws can be done in one place in this class. We want as -// /// little distance as possible between redraws when possible! -// /// -// /// @note Currently the foreground is not drawn in the custom screen -// /// manager. This is because the foreground features the general -// /// inventory manager that this screen handler is based on and we -// /// do not want to see those text pop ups. -// ///////////////////////////////////////////////////////////////////////////// -// public void DrawLayers(DrawContext context, float delta) { -// for (Entry> layerEntry : layers.entrySet()) { -// var layerList = layerEntry.getValue(); - -// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { -// var layer = layerList.get(layerListIterator); -// System.out.println("Drawing layer " + layerEntry.getKey() + " for class type " + layer.getClass().toString()); -// layer.DrawLayer(context, layerEntry.getKey()); -// } -// } -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn InBounds -// /// -// /// @arg[in] initX is initial position of X axis -// /// -// /// @arg[in] initY is initial position of Y axis -// /// -// /// @arg[in] endX is the end position of X axis -// /// -// /// @arg[in] endY is the end position of Y axis -// /// -// /// @arg[in] x is the current X value we are comparing in the X axis -// /// -// /// @arg[in] y is the current Y value we are comparing in the Y axis -// /// -// /// @brief Checks if an x,y coordinate position falls within the bounds -// /// of a bounded box -// ///////////////////////////////////////////////////////////////////////////// -// private boolean InBounds(int initX, int initY, int endX, int endY, int x, int y) { -// return (x >= initX && x <= endX) && (y >= initY && y <= endY); -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn drawBackground -// /// -// /// @arg[in] context is the drawing context of super class -// /// -// /// @arg[in] delta is the change in background draw -// /// -// /// @arg[in] mouseX is the mouse x-axis position -// /// -// /// @arg[in] mouseY is the mouse y-axis position -// /// -// /// @brief This function is an abstract parent class and must be -// /// implemented. This is "hijacked" and just being used as our -// /// main drawing method of all the background images. There isn't -// /// a huge difference of drawing our stuff in background vs the -// /// foreground - except possibly foreground is drawn first. -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { -// DrawLayers(context, delta); -// } -// } diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/NewItemButton.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/NewItemButton.java new file mode 100644 index 0000000..330a12e --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/NewItemButton.java @@ -0,0 +1,41 @@ +package jesse.keeblarcraft.gui.ShopKeeperGUI; + +import jesse.keeblarcraft.ClientHelpers.Helper; +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.gui.Generics.ClickableLayer; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public class NewItemButton extends ClickableLayer { + private static final Identifier NEW_ITEM_MENU = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/shopkeeper_item_slot.jpeg"); + private static NewItemMenu newItemMenu; + + public NewItemButton(Identifier texture, Text layerName, int width, int height, int startX, int startY) { + 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); + } + + @Override + public void onClick(double x, double y) { + // Toggle the menu sub layer to be on if it was clicked. @See UpdateSubLayers for when it gets closed + System.out.println("Status of new item menu: " + newItemMenu.IsOpen()); + if (!newItemMenu.IsOpen()) { + System.out.println("Adding new item menu and telling it to open"); + this.AddSubLayer(newItemMenu); + newItemMenu.OpenMenu(); + } + } + + @Override + public void UpdateSubLayers() { + if (!newItemMenu.IsOpen()) { + this.ClearSubLayers(); + } + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) {} +} diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/NewItemMenu.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/NewItemMenu.java new file mode 100644 index 0000000..bc79b13 --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/NewItemMenu.java @@ -0,0 +1,45 @@ +package jesse.keeblarcraft.gui.ShopKeeperGUI; + +import jesse.keeblarcraft.ClientHelpers.Helper; +import jesse.keeblarcraft.gui.Generics.ClickableLayer; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +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()); + } + + public void CloseMenu() { + this.isOpen = false; + this.visible = false; + } + + public void OpenMenu() { + this.visible = true; + this.isOpen = true; + } + + public boolean IsOpen() { + return this.isOpen; + } + + @Override + public void onClick(double x, double y) { + // Check to see if user clicked the 'x' area (mark closed in case) + // TODO: The coordinates for the 'X' button aren't known at the moment. For now just mark + // 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; + } + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } +} diff --git a/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java new file mode 100644 index 0000000..975e411 --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/gui/ShopKeeperGUI/ShopKeeperMenu.java @@ -0,0 +1,108 @@ +package jesse.keeblarcraft.gui.ShopKeeperGUI; + +import jesse.keeblarcraft.GuiMgr.ShopKeeperHandler; +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.ClientHelpers.Helper; +import jesse.keeblarcraft.gui.Generics.ClickableLayer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ShopKeeperMenu extends HandledScreen { + private static final Identifier MENU_TEXTURE = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/shopkeeper_gui.jpeg"); + private static final Identifier ADD_BUTTON = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/shopkeeper_add_icon.jpeg"); + private static final Identifier NEW_ITEM_MENU = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/shopkeeper_item_slot.jpeg"); + private int x = 0; + private int y = 0; + private final List layers = new ArrayList<>(); + + public ShopKeeperMenu(ShopKeeperHandler handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + } + + @Override + protected void init() { + super.init(); + titleY = 1000; //begone from screen + playerInventoryTitleY = 1000; //begone from screen + + // Set the main shop keeping menu variables here + this.backgroundWidth = 256; + this.backgroundHeight = 256; + this.x = (width - backgroundWidth) / 2; + this.y = (height - backgroundHeight) / 2; + + // Add all layers below + AddNewButton(ADD_BUTTON, Text.of("ADD ITEM BUTTON"), x, y, 64, 64); + } + + @Override + protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { + // Draw the menu texture first +// context.drawTexture(MENU_TEXTURE, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); + context.drawTexture(MENU_TEXTURE, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight, this.backgroundWidth, this.backgroundHeight); +// 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); + + for (ClickableLayer layer : layers) { + layer.renderButton(context, mouseX, mouseY, delta); + + for (ClickableLayer subLayer : layer.GetSubLayers()) { + subLayer.renderButton(context, mouseX, mouseY, delta); + } + + // We only notify the parent to update sub layers. It must manage its own sub layers + layer.UpdateSubLayers(); + } + } + + // 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)); + } + + @Override + public void drawForeground(DrawContext context, int mouseX, int mouseY) { + // We override this function to intentionally do nothing + // If in the future we want, we would draw the foreground and TITLES with this! + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + for (ClickableLayer layer : layers) { + // Check main layer first + if (Helper.WithinBounds(layer.getX(), layer.getY(), layer.getWidth(), layer.getHeight(), mouseX, mouseY)) { + layer.mouseClicked(mouseX, mouseY, button); + } + + for (ClickableLayer subLayer : layer.GetSubLayers()) { + + if (subLayer.visible && Helper.WithinBounds(subLayer.getX(), subLayer.getY(), subLayer.getWidth(), subLayer.getHeight(), mouseX, mouseY)) { + subLayer.mouseClicked(mouseX, mouseY, button); + } + } + } + + return true; + } + + // Check if a click point is within the context of a square (square = x, y, w, h) +// public static boolean WithinBounds(double x, double y, double w, double h, double clickX, double clickY) { +//// System.out.println("Mouse click X Y: " + clickX + " " + clickY); +//// System.out.println("Rectangle X Y W H: " + x + " " + y + " " + w + " " + h); +// return (clickX >= x) && (clickX <= x + w) && (clickY >= y) && (clickY <= y + h); +// } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + renderBackground(context, mouseX, mouseY, delta); + super.render(context, mouseX, mouseY, delta); + drawMouseoverTooltip(context, mouseX, mouseY); + } +} diff --git a/src/client/java/jesse/keeblarcraft/gui/widgets/TreeWidget.java b/src/client/java/jesse/keeblarcraft/gui/widgets/TreeWidget.java deleted file mode 100644 index 39e5318..0000000 --- a/src/client/java/jesse/keeblarcraft/gui/widgets/TreeWidget.java +++ /dev/null @@ -1,165 +0,0 @@ -// /* -// * -// * TreeWidget -// * -// * Handles the skill tree widget -// * -// * -// */ - -// package jesse.keeblarcraft.gui.widgets; - -// import jesse.keeblarcraft.Keeblarcraft; -// import jesse.keeblarcraft.Utils.CommonStructures.Position2d; -// import jesse.keeblarcraft.gui.GenericLayerT; -// import net.minecraft.client.gui.DrawContext; -// import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; -// import net.minecraft.text.Text; -// import net.minecraft.util.Identifier; - -// public class TreeWidget extends GenericLayerT { -// private static Identifier BACKGROUND_TEXTURE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_tree_background.png"); -// private static int maxHeight = 320; -// private static int maxLength = 640; -// private int zoomScale = 1; -// // private static Identifier FLIGHT_ATTRIBUTE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_flight.png"); - -// ///TODO: Make this THE root node in the attribute tree! Rename in future -// // private static Identifier EXAMPLE_NODE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_tree_example_node.png"); ///TODO: Make a way to make this programmatic (Proabably extend AbstractNode to carry this var) - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn TreeWidget -// /// -// /// @brief Class constructor for constructing a tree widget. This will -// /// be deprecated in a future version but exists for testing -// ///////////////////////////////////////////////////////////////////////////// -// public TreeWidget() { -// this(0, 0, 0, 0, Text.of("Test")); -// System.out.println("Calling empty tree constructor"); -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn TreeWidget -// /// -// /// @brief Class constructor for constructing a tree widget -// ///////////////////////////////////////////////////////////////////////////// -// public TreeWidget(int x, int y, int width, int height, Text message) { -// super(x, y, width, height, message); - -// this.startX = x; -// this.startY = y; -// this.endX = x + width; -// this.endY = y + height; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn renderButton -// /// -// /// @param[in] context is the drawing pane -// /// -// /// @param[in] x is the X position to draw at -// /// -// /// @param[in] y is the Y position to draw at -// /// -// /// @param[in] delta is unused in this version -// /// -// /// @brief Primary call to draw the GUI for this widget -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public void renderButton(DrawContext context, int x, int y, float delta) { -// context.drawTexture(BACKGROUND_TEXTURE, x, y, 0, 0, maxLength, maxHeight, maxLength, maxHeight); -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn appendClickableNarrations -// /// -// /// @param[in] builder is the narration builder. This is pure virtual in -// /// the parent but is unused in this widget currently -// /// -// /// @brief Handles the narrator -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// protected void appendClickableNarrations(NarrationMessageBuilder builder) { -// return; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn mouseClicked -// /// -// /// @param[in] mouseX is where on the x-axis the mouse was clicked -// /// -// /// @param[in] mouseY is where on the y-axis the mouse was clicked -// /// -// /// @param[in] button is the button clicked with (think of a mouse...) -// /// -// /// @brief Handler for mouse click events -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public boolean mouseClicked(double mouseX, double mouseY, int button) { -// return true; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn mouseDragged -// /// -// /// @param[in] mouseX is where on the x-axis the mouse was dragged -// /// -// /// @param[in] mouseY is where on the y-axis the mouse was dragged -// /// -// /// @param[in] button is the button dragged with (think of a mouse...) -// /// -// /// @brief Handler for mouse drag events. delta's unused currently -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { -// boolean ret = false; -// if (this.isValidClickButton(button)) { -// // Do camera panning magic stuff here -// ret = true; -// } -// return ret; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn mouseDragged -// /// -// /// @param[in] mouseX is where on the x-axis the mouse was dragged -// /// -// /// @param[in] mouseY is where on the y-axis the mouse was dragged -// /// -// /// @param[in] amount represents scroll direction. If the value is negative -// /// we scale out. If positive, we scale in -// /// -// /// @brief Handler for mouse scroll events -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public boolean mouseScrolled(double mouseX, double mouseY, double amount) { -// // Zooming INWARDS on scroll wheel produces 1.0 (which means zoom in) -// // Zooming BACKWARDS on scroll wheel produces -1.0 (which means zoom out) -// // We enforce a max scroll of 10 in either direction here -// if (amount > 0 && zoomScale <= 10) { -// // Zoom in -// zoomScale++; -// } else if (amount < 0 && zoomScale >= -10) { -// // Zoom out -// zoomScale--; -// } -// return true; -// } - -// ///////////////////////////////////////////////////////////////////////////// -// /// @fn DrawLayer -// /// -// /// @param[in] context is the drawing pane -// /// -// /// @param[in] layer is the layer in which this widget is being drawn in -// /// -// /// @brief This calls renderButton and gives it the valid drawing -// /// context to use. This function is called by a ScreenManager -// ///////////////////////////////////////////////////////////////////////////// -// @Override -// public void DrawLayer(DrawContext context, int layer) { -// Position2d pos = GetScreenCenter(); -// this.renderButton(context, pos.x - (maxLength / 2), pos.y - (maxHeight / 2), 0); -// } -// } diff --git a/src/client/java/jesse/keeblarcraft/mixin/ClientPlayNetworkHandlerMixin.java b/src/client/java/jesse/keeblarcraft/mixin/ClientPlayNetworkHandlerMixin.java new file mode 100644 index 0000000..e04d07f --- /dev/null +++ b/src/client/java/jesse/keeblarcraft/mixin/ClientPlayNetworkHandlerMixin.java @@ -0,0 +1,26 @@ +package jesse.keeblarcraft.mixin; + +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import jesse.keeblarcraft.GuiMgr.ShopKeeperHandler; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.network.packet.s2c.play.SetTradeOffersS2CPacket; +import net.minecraft.screen.ScreenHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ClientPlayNetworkHandler.class) +public abstract class ClientPlayNetworkHandlerMixin { + @Inject(at = @At("TAIL"), method = "onSetTradeOffers") + public void onSetTradeOffers(SetTradeOffersS2CPacket packet, CallbackInfo ci, @Local ScreenHandler screenHandler) { + if (packet.getSyncId() == screenHandler.syncId && screenHandler instanceof ShopKeeperHandler shopKeeperHandler) { + shopKeeperHandler.SetOffers(packet.getOffers()); + shopKeeperHandler.SetExperienceLevel(packet.getExperience()); + shopKeeperHandler.SetLevelProgress(packet.getLevelProgress()); + shopKeeperHandler.SetLeveled(packet.isLeveled()); + shopKeeperHandler.SetCanRefreshTrades(packet.isRefreshable()); + } + } +} diff --git a/src/client/java/jesse/keeblarcraft/mixin/ClientPlayerInteractionManagerMixin.java b/src/client/java/jesse/keeblarcraft/mixin/ClientPlayerInteractionManagerMixin.java deleted file mode 100644 index 1fa709f..0000000 --- a/src/client/java/jesse/keeblarcraft/mixin/ClientPlayerInteractionManagerMixin.java +++ /dev/null @@ -1,17 +0,0 @@ -package jesse.keeblarcraft.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.client.network.ClientPlayerInteractionManager; - -@Mixin(ClientPlayerInteractionManager.class) -public abstract class ClientPlayerInteractionManagerMixin { - // This initial basically lets the player highlight the block at 10 blocks away. Does NOT let them break it, that is all handled in the new server mixin - // @Inject(method = "getReachDistance()F", at = @At ("HEAD"), cancellable = true) - // public void getReachDistance(CallbackInfoReturnable cir) { - // cir.setReturnValue(10.0f); - // } -} diff --git a/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java index 11ce764..dd95324 100644 --- a/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java +++ b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/FactionBlockEntity.java @@ -221,7 +221,6 @@ public class FactionBlockEntity extends BlockEntity implements ExtendedScreenHan if (hasSuperBeacon) { AttributeMgr.ApplyAttribute(player.getUuidAsString(), "faction_beacon"); - // ActionResult result = PlayerInBaseCallback.EVENT.invoker().interact(player, world); } } else if (!isPlayerInFactionRadius && playersInRadius.contains(player.getUuidAsString())) { playersInRadius.remove(player.getUuidAsString()); diff --git a/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java b/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java index 26f6890..3bc1d3c 100644 --- a/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java +++ b/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java @@ -15,9 +15,11 @@ import java.util.List; import jesse.keeblarcraft.CustomItems.Items.FactionBeaconItem; import jesse.keeblarcraft.CustomItems.Items.FactionFlightItem; +import jesse.keeblarcraft.Entities.EntityRegistration; import jesse.keeblarcraft.Keeblarcraft; import net.fabricmc.fabric.api.item.v1.FabricItemSettings; import net.minecraft.item.Item; +import net.minecraft.item.SpawnEggItem; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; @@ -68,5 +70,6 @@ public class ItemManager { // The example item provides a demo of how you could make an item in your class RegisterItem("faction_upgrade_flight", new FactionFlightItem(new FabricItemSettings().maxCount(1))); RegisterItem("faction_upgrade_beacon", new FactionBeaconItem(new FabricItemSettings().maxCount(1))); + RegisterItem("shop_keeper_spawn_egg", new SpawnEggItem(EntityRegistration.SHOP_KEEPER_ENTITY_TYPE, 0xc4c4c4, 0xadadad, new FabricItemSettings())); } } diff --git a/src/main/java/jesse/keeblarcraft/Entities/EntityRegistration.java b/src/main/java/jesse/keeblarcraft/Entities/EntityRegistration.java index f81e3ef..b12a7c8 100644 --- a/src/main/java/jesse/keeblarcraft/Entities/EntityRegistration.java +++ b/src/main/java/jesse/keeblarcraft/Entities/EntityRegistration.java @@ -12,7 +12,7 @@ public class EntityRegistration { public static final EntityType SHOP_KEEPER_ENTITY_TYPE = Registry.register( Registries.ENTITY_TYPE, Identifier.of(Keeblarcraft.MOD_ID, "shop_keeper"), - EntityType.Builder.create(ShopKeeper::new, SpawnGroup.MISC).setDimensions(1.0f, 1.0f).build("shop_keeper") + EntityType.Builder.create(ShopKeeper::new, SpawnGroup.CREATURE).setDimensions(0.75f, 2.0f).build("cube") ); public static void RegisterEntities() { diff --git a/src/main/java/jesse/keeblarcraft/Entities/ShopKeeper.java b/src/main/java/jesse/keeblarcraft/Entities/ShopKeeper.java index fbdbe84..c9ae6aa 100644 --- a/src/main/java/jesse/keeblarcraft/Entities/ShopKeeper.java +++ b/src/main/java/jesse/keeblarcraft/Entities/ShopKeeper.java @@ -1,30 +1,79 @@ package jesse.keeblarcraft.Entities; +import jesse.keeblarcraft.GuiMgr.ShopKeeperHandler; import net.minecraft.entity.EntityType; -import net.minecraft.entity.passive.MerchantEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.server.world.ServerWorld; +import net.minecraft.entity.passive.VillagerEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.screen.SimpleNamedScreenHandlerFactory; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; import net.minecraft.village.TradeOffer; +import net.minecraft.village.TradeOfferList; import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; -public class ShopKeeper extends MerchantEntity { - public ShopKeeper(EntityType entityType, World world) { +import java.util.OptionalInt; + +public class ShopKeeper extends VillagerEntity { + public ShopKeeper(EntityType entityType, World world) { super(entityType, world); } + @Override + public ActionResult interactMob(PlayerEntity player, Hand hand) { + BeginTrades(player); + return ActionResult.success(this.getWorld().isClient()); + } + + private void BeginTrades(PlayerEntity player) { + super.setCustomer(player); + this.sendOffers(player, this.getDisplayName(), this.getVillagerData().getLevel()); + } + + @Override + public void sendOffers(PlayerEntity player, Text name, int levelProgress) { + OptionalInt optInt = player.openHandledScreen( + new SimpleNamedScreenHandlerFactory((syncId, playerInventory, playerx) -> + new ShopKeeperHandler(syncId, playerInventory, this), name) + ); + + if (optInt.isPresent()) { + TradeOfferList offers = this.getOffers(); + if (!offers.isEmpty()) { + player.sendTradeOffers(optInt.getAsInt(), offers, levelProgress, this.getExperience(), this.isLeveledMerchant(), this.canRefreshTrades()); + } + } + } + + // Shop Keepers do not breed! + @Override + public boolean canBreed() { + return false; + } + + @Override + protected Text getDefaultName() { + return Text.of("Shop Keeper"); + } + @Override protected void afterUsing(TradeOffer offer) { + System.out.println("After using called"); + } + // Get the offer list upon opening handled screen if valid + @Override + public TradeOfferList getOffers() { + if (this.offers == null) { + this.offers = new TradeOfferList(); + this.fillRecipes(); + } + + return this.offers; } @Override - protected void fillRecipes() { - - } - - @Override - public @Nullable PassiveEntity createChild(ServerWorld world, PassiveEntity entity) { - return null; + public boolean canSummonGolem(long time) { + return false; } } diff --git a/src/main/java/jesse/keeblarcraft/GuiMgr/ScreenHandlerRegistration.java b/src/main/java/jesse/keeblarcraft/GuiMgr/ScreenHandlerRegistration.java index 945e2ee..cf3e61e 100644 --- a/src/main/java/jesse/keeblarcraft/GuiMgr/ScreenHandlerRegistration.java +++ b/src/main/java/jesse/keeblarcraft/GuiMgr/ScreenHandlerRegistration.java @@ -4,6 +4,7 @@ import jesse.keeblarcraft.Keeblarcraft; import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.resource.featuretoggle.FeatureFlags; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.util.Identifier; @@ -12,7 +13,13 @@ public class ScreenHandlerRegistration { Registry.register(Registries.SCREEN_HANDLER, new Identifier(Keeblarcraft.MOD_ID, "faction_block"), new ExtendedScreenHandlerType<>(FactionBlockScreenHandler::new)); + public static final ScreenHandlerType SHOP_KEEPER_HANDLER_SCREEN_HANDLER_TYPE = + Registry.register(Registries.SCREEN_HANDLER, new Identifier(Keeblarcraft.MOD_ID, "shopkeeper"), + new ScreenHandlerType<>(ShopKeeperHandler::new, FeatureFlags.VANILLA_FEATURES)); + + + public static void registerScreenHandlers() { - Keeblarcraft.LOGGER.info("Registering screen handlers for " + Keeblarcraft.MOD_ID); + Keeblarcraft.LOGGER.info("Registering screen handlers for {}", Keeblarcraft.MOD_ID); } } diff --git a/src/main/java/jesse/keeblarcraft/GuiMgr/ShopKeeperHandler.java b/src/main/java/jesse/keeblarcraft/GuiMgr/ShopKeeperHandler.java new file mode 100644 index 0000000..eb67f68 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/GuiMgr/ShopKeeperHandler.java @@ -0,0 +1,62 @@ +package jesse.keeblarcraft.GuiMgr; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.village.Merchant; +import net.minecraft.village.MerchantInventory; +import net.minecraft.village.SimpleMerchant; +import net.minecraft.village.TradeOfferList; + +public class ShopKeeperHandler extends ScreenHandler { + private Merchant merchant; + private MerchantInventory merchantInventory; + boolean canRefreshTrades = false; + boolean isLeveledMerchant = false; + int levelAmount = 0; + int merchantExperience = 0; + + public ShopKeeperHandler(int syncId, PlayerInventory playerInventory) { + this(syncId, playerInventory, new SimpleMerchant(playerInventory.player)); + } + + public ShopKeeperHandler(int syncId, PlayerInventory playerInventory, Merchant merchant) { + super(ScreenHandlerRegistration.SHOP_KEEPER_HANDLER_SCREEN_HANDLER_TYPE, syncId); + this.merchant = merchant; + this.merchantInventory = new MerchantInventory(merchant); + // Add slots below + } + + public void SetOffers(TradeOfferList offers) { + this.merchant.setOffersFromServer(offers); + } + + public void SetExperienceLevel(int xp) { + this.merchantExperience = xp; + } + + public void SetLevelProgress(int level) { + this.levelAmount = level; + } + + public void SetLeveled(boolean leveled) { + this.isLeveledMerchant = leveled; + } + + public void SetCanRefreshTrades(boolean isRefreshable) { + this.canRefreshTrades = isRefreshable; + } + + @Override + public ItemStack quickMove(PlayerEntity player, int slot) { + return null; + } + + // Called every tick + @Override + public boolean canUse(PlayerEntity player) { +// System.out.println("canUse called on Merchant!"); + return true; + } +} diff --git a/src/main/java/jesse/keeblarcraft/Keeblarcraft.java b/src/main/java/jesse/keeblarcraft/Keeblarcraft.java index ad4882f..da8192e 100644 --- a/src/main/java/jesse/keeblarcraft/Keeblarcraft.java +++ b/src/main/java/jesse/keeblarcraft/Keeblarcraft.java @@ -3,12 +3,13 @@ * Keeblarcraft * * This is the primary server side "main" object that is referenced by Fabric. This is where everything is setup for the mod - * and a very important class. Please becareful as you add to it + * and a very important class. Please be careful as you add to it * */ package jesse.keeblarcraft; +import jesse.keeblarcraft.Entities.EntityRegistration; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; @@ -78,9 +79,7 @@ public class Keeblarcraft implements ModInitializer { var player = handler.player; Keeblarcraft.LOGGER.info("Player " + player.getName() + " has logged out. Deleting tree..."); - if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == true) { - AttributeMgr.activeTrees.remove(player.getUuidAsString()); - } + AttributeMgr.activeTrees.remove(player.getUuidAsString()); }); ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, origin, destination) -> { @@ -131,6 +130,7 @@ public class Keeblarcraft implements ModInitializer { BlockEntityRegistration.RegisterBlockEntities(); // World generation + EntityRegistration.RegisterEntities(); // Custom portal generator System.out.println("BUILDING CUSTOM PORTAL"); diff --git a/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java b/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java index a7a617b..06968ae 100644 --- a/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java +++ b/src/main/java/jesse/keeblarcraft/mixin/EntitySpawnMixin.java @@ -2,8 +2,6 @@ package jesse.keeblarcraft.mixin; import net.minecraft.entity.mob.MobEntity; -// import javax.annotation.Nullable; - import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/jesse/keeblarcraft/mixin/PlayerMixin.java b/src/main/java/jesse/keeblarcraft/mixin/PlayerMixin.java index fed0ca7..16c037c 100644 --- a/src/main/java/jesse/keeblarcraft/mixin/PlayerMixin.java +++ b/src/main/java/jesse/keeblarcraft/mixin/PlayerMixin.java @@ -51,6 +51,6 @@ public abstract class PlayerMixin { // 3. Casting '(Object) this' into 'PlayerEntity' gets us to the mixin inject - and NOW we can store the result of this cast into the type we want as a reference // which is the 'PlayerEntity' on the left hand side. Now we can access stuff from that class AS IF WE ARE CODING INSIDE OF THAT CLASS :))) PlayerEntity player = (PlayerEntity) (Object) this; - Keeblarcraft.LOGGER.info("PLAYER MIXIN: " + player.getEntityName()); +// Keeblarcraft.LOGGER.info("PLAYER MIXIN: " + player.getEntityName()); } } diff --git a/src/main/resources/assets/keeblarcraft/lang/en_us.json b/src/main/resources/assets/keeblarcraft/lang/en_us.json index 3cc7ce8..4729a05 100644 --- a/src/main/resources/assets/keeblarcraft/lang/en_us.json +++ b/src/main/resources/assets/keeblarcraft/lang/en_us.json @@ -8,6 +8,8 @@ "itemgroup.keeblarcraft": "Keeblarcraft Modded Items", + "item.keeblarcraft.shop_keeper_spawn_egg": "Shop Keeper Spawn Egg", + "block.keeblarcraft.example_block": "Keeblarcraft example block", "block.keeblarcraft.example_block_ore": "Keeblarcraft example block ore", "block.keeblarcraft.example_statue": "Keeblarcraft example statue", diff --git a/src/main/resources/assets/keeblarcraft/models/item/shop_keeper_spawn_egg.json b/src/main/resources/assets/keeblarcraft/models/item/shop_keeper_spawn_egg.json new file mode 100644 index 0000000..7a2c6da --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/item/shop_keeper_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "item/template_spawn_egg" +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_add_icon.jpeg b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_add_icon.jpeg new file mode 100644 index 0000000..6319a82 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_add_icon.jpeg differ diff --git a/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_checkout_button.jpeg b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_checkout_button.jpeg new file mode 100644 index 0000000..fd4ff52 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_checkout_button.jpeg differ diff --git a/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_gui.jpeg b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_gui.jpeg new file mode 100644 index 0000000..41b5794 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_gui.jpeg differ diff --git a/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_item_slot.jpeg b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_item_slot.jpeg new file mode 100644 index 0000000..8e051c3 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_item_slot.jpeg differ diff --git a/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_scrollbar.jpeg b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_scrollbar.jpeg new file mode 100644 index 0000000..0c46d57 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_scrollbar.jpeg differ diff --git a/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_subtract.png b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_subtract.png new file mode 100644 index 0000000..4d3baae Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/gui/shopkeeper_subtract.png differ diff --git a/src/main/resources/keeblarcraft.mixins.json b/src/main/resources/keeblarcraft.mixins.json index 88ccd00..94f34cb 100644 --- a/src/main/resources/keeblarcraft.mixins.json +++ b/src/main/resources/keeblarcraft.mixins.json @@ -11,7 +11,7 @@ "EntitySpawnMixin" ], "client": [ - "ClientPlayerInteractionManagerMixin" + "ClientPlayNetworkHandlerMixin" ], "injectors": { "defaultRequire": 1