#3 Added GUI support for start of shop system. Still premature, but it's finally starting to get there
Some checks are pending
build / build (21) (push) Waiting to run

This commit is contained in:
Jkibbels 2025-02-15 00:12:42 -05:00
parent 64236d94b6
commit 4e080ad392
34 changed files with 478 additions and 678 deletions

View File

@ -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);
}
}

View File

@ -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<ShopKeeper> {
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);
});
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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<FactionBlockScreenHandler>
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

View File

@ -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);
}

View File

@ -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<ClickableLayer> 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<ClickableLayer> 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;
}
}

View File

@ -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<TreeHandler> {
// 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<Integer, ArrayList<Class<? extends GenericLayerT>>> layerMap = new HashMap<Integer, ArrayList<Class<? extends GenericLayerT>>>();
// private static HashMap<Integer, ArrayList<GenericLayerT>> layers = new HashMap<Integer, ArrayList<GenericLayerT>>(); // 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<Class<? extends GenericLayerT>>());
// // }
// }
// /////////////////////////////////////////////////////////////////////////////
// /// @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<? extends GenericLayerT> 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<Integer, ArrayList<Class<? extends GenericLayerT>>> 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<Integer, ArrayList<GenericLayerT>> 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<Integer, ArrayList<GenericLayerT>> 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<Integer, ArrayList<GenericLayerT>> 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<Integer, ArrayList<GenericLayerT>> 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);
// }
// }

View File

@ -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) {}
}

View File

@ -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) {
}
}

View File

@ -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<ShopKeeperHandler> {
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<ClickableLayer> 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);
}
}

View File

@ -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<T>
// /////////////////////////////////////////////////////////////////////////////
// @Override
// public void DrawLayer(DrawContext context, int layer) {
// Position2d pos = GetScreenCenter();
// this.renderButton(context, pos.x - (maxLength / 2), pos.y - (maxHeight / 2), 0);
// }
// }

View File

@ -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());
}
}
}

View File

@ -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<Float> cir) {
// cir.setReturnValue(10.0f);
// }
}

View File

@ -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());

View File

@ -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()));
}
}

View File

@ -12,7 +12,7 @@ public class EntityRegistration {
public static final EntityType<ShopKeeper> 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() {

View File

@ -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<? extends MerchantEntity> entityType, World world) {
import java.util.OptionalInt;
public class ShopKeeper extends VillagerEntity {
public ShopKeeper(EntityType<? extends VillagerEntity> 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;
}
}

View File

@ -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<ShopKeeperHandler> 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);
}
}

View File

@ -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;
}
}

View File

@ -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());
}
});
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");

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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",

View File

@ -0,0 +1,3 @@
{
"parent": "item/template_spawn_egg"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

View File

@ -11,7 +11,7 @@
"EntitySpawnMixin"
],
"client": [
"ClientPlayerInteractionManagerMixin"
"ClientPlayNetworkHandlerMixin"
],
"injectors": {
"defaultRequire": 1