diff --git a/src/main/java/jesse/keeblarcraft/Armor/MetalJacketArmor.java b/src/main/java/jesse/keeblarcraft/Armor/MetalJacketArmor.java new file mode 100644 index 0000000..d6a12e0 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/Armor/MetalJacketArmor.java @@ -0,0 +1,81 @@ +package jesse.keeblarcraft.Armor; + +import jesse.keeblarcraft.Keeblarcraft; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ArmorMaterial; +import net.minecraft.item.Items; +import net.minecraft.recipe.Ingredient; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; + +public class MetalJacketArmor implements ArmorMaterial { + // All references to this class must refer to this + public static final MetalJacketArmor INSTANCE = new MetalJacketArmor(); + + int defaultArmorModifier = 3; + + /// FUNCTIONS BELOW + + public MetalJacketArmor() { + System.out.println("Constructor for armor called"); + } + + @Override + public int getDurability(ArmorItem.Type type) { + System.out.println("durability for armor called"); + // Replace this multiplier by a constant value for the durability of the armor. + // For reference, diamond uses 33 for all armor pieces, whilst leather uses 5. + return switch (type) { + case ArmorItem.Type.BOOTS -> Integer.MAX_VALUE; + case ArmorItem.Type.LEGGINGS -> Integer.MAX_VALUE; + case ArmorItem.Type.CHESTPLATE -> Integer.MAX_VALUE; + case ArmorItem.Type.HELMET -> Integer.MAX_VALUE; + }; + } + + @Override + public int getProtection(ArmorItem.Type type) { + System.out.println("Protection called"); + // Protection values for all the slots. + // For reference, diamond uses 3 for boots, 6 for leggings, 8 for chestplate, and 3 for helmet, + // whilst leather uses 1, 2, 3 and 1 respectively. + return switch (type) { + case ArmorItem.Type.BOOTS -> defaultArmorModifier; + case ArmorItem.Type.HELMET -> defaultArmorModifier; + case ArmorItem.Type.LEGGINGS -> defaultArmorModifier; + case ArmorItem.Type.CHESTPLATE -> defaultArmorModifier; + }; + } + + @Override + public int getEnchantability() { + return Integer.MAX_VALUE; + } + + @Override + public SoundEvent getEquipSound() { + // Example for Iron Armor + return SoundEvents.ITEM_ARMOR_EQUIP_IRON; + } + + @Override + public Ingredient getRepairIngredient() { + return Ingredient.ofItems(Items.BEDROCK); // prayfully impossible repair or just not worth it + } + + @Override + public String getName() { + return Keeblarcraft.MOD_ID + ":" + "metaljacket"; + } + + @Override + public float getToughness() { + // Toughness is the actual "resistance" the armor provides to HIGH damage attacks + return (float) defaultArmorModifier; + } + + @Override + public float getKnockbackResistance() { + return 0; + } +} \ No newline at end of file diff --git a/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeMgr.java b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeMgr.java new file mode 100644 index 0000000..908e2e8 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeMgr.java @@ -0,0 +1,73 @@ +/* + * + * AttributeMgr + * + * Central point for the attribute skill system in the mod + * + * +*/ + +package jesse.keeblarcraft.AttributeMgr; + +import java.util.HashMap; +import java.util.List; + +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode; +import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeFlight; +import jesse.keeblarcraft.ConfigMgr.ConfigManager; +import jesse.keeblarcraft.Utils.ChatUtil; + +public class AttributeMgr { + ConfigManager config; + + public static final HashMap attributes = new HashMap(); + + @SuppressWarnings("deprecation") + public static void RegisterAttributeClass(Class classObj) { + AbstractNode test; + ChatUtil.LoggerColored("Registring attribute called", ChatUtil.CONSOLE_COLOR.CYAN, Keeblarcraft.LOGGER); + try { + test = classObj.newInstance(); + if (attributes.containsKey(test.GetNodeTitle())) { + Keeblarcraft.LOGGER.warn("Could not register attribute with duplicate name '" + test.GetNodeTitle() + "'"); + } else { + ChatUtil.LoggerColored("REGISTERING ATTRIBUTE " + test.GetNodeTitle(), ChatUtil.CONSOLE_COLOR.YELLOW, Keeblarcraft.LOGGER); + attributes.put(test.GetNodeTitle(), test); + } + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public static String ApplyAttribute(String uuid, String attributeName) { + String msg = ""; + if (attributes.containsKey(attributeName)) { + AttributeTree playerTree = new AttributeTree(uuid); + AbstractNode node = attributes.get(attributeName); + + /////////// + // debug testing + String isNull = (node == null ? "NULL" : "NOT NULL"); + System.out.println("Node is " + isNull); + if (isNull.equals("NOT NULL")) { System.out.println("Node name: " + node.GetNodeTitle()); } + // end debug testing + /////////// + + playerTree.AddNewNode(node, 1, null, null); ///TODO: Make handling in AttributeTree of NULL parents list to be defaulted to ROOT + msg = "Applied attribute '" + attributeName + "' successfully"; + } else { + msg = "Could not apply attribute, attribute name does not exist!"; + } + return msg; + } + + public static void RegisterAttributes() { + // Manually register all attribute node classes here + /// TODO: Find a better way to do this more dynamically in the future + + RegisterAttributeClass(AttributeFlight.class); + } +} diff --git a/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AbstractNode.java b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AbstractNode.java new file mode 100644 index 0000000..37a9f47 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AbstractNode.java @@ -0,0 +1,44 @@ +/* + * + * AbstractNode + * + * This is the general definition of everything that is allowed inside a node and is called by our system + * + * +*/ + +package jesse.keeblarcraft.AttributeMgr.AttributeNodes; + +import java.util.HashMap; +import java.util.List; + +abstract public class AbstractNode { + + ///////////////////////////////////////////////////////////////////////////// + /// @fn GetNodeTitle + /// + /// @brief The title of your node/skill! + ///////////////////////////////////////////////////////////////////////////// + public abstract String GetNodeTitle(); + + ///////////////////////////////////////////////////////////////////////////// + /// @fn GetNodeDescription + /// + /// @brief This will become the hover-over text display of a skill in + /// the skill tree + ///////////////////////////////////////////////////////////////////////////// + public abstract String GetNodeDescription(); + + ///////////////////////////////////////////////////////////////////////////// + /// @fn GetDetails + /// + /// @brief This is the general details that may be displayed inside the + /// GUI when the skill tree becomes available to a player. The + /// object is suggested to be treated as such: + /// + /// KEY (String) -> The title of an effect/attribute + /// VAL (List) -> Treated as a list of description + /// attributes. 1 string per description + ///////////////////////////////////////////////////////////////////////////// + public abstract HashMap> GetDetails(); +} diff --git a/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AttributeFlight.java b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AttributeFlight.java new file mode 100644 index 0000000..d4ab443 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AttributeFlight.java @@ -0,0 +1,36 @@ +package jesse.keeblarcraft.AttributeMgr.AttributeNodes; + +import java.util.HashMap; +import java.util.List; + +import jesse.keeblarcraft.AttributeMgr.AttributeMgr; + +public class AttributeFlight extends AbstractNode { + + public AttributeFlight() { + // AttributeMgr.RegisterAttributeClass(getClass()); + } + + @Override + public String GetNodeTitle() { + return "attribute_low_health_flight"; + } + + @Override + public String GetNodeDescription() { + return "Gives player flight with low health"; + } + + @Override + public HashMap> GetDetails() { + HashMap> ret = new HashMap>(); + + // Filling out description item stuff here + ret.put("Flight", List.of ( + "Gives a player natural flight if they have less than or equal to two hearts remaining" + )); + + return ret; + } + +} diff --git a/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AttributeMetalJacket.java b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AttributeMetalJacket.java new file mode 100644 index 0000000..d86d871 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeNodes/AttributeMetalJacket.java @@ -0,0 +1,52 @@ +package jesse.keeblarcraft.AttributeMgr.AttributeNodes; + +import java.util.HashMap; +import java.util.List; + +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.Armor.MetalJacketArmor; +import jesse.keeblarcraft.CustomItems.ItemManager; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.Item; + +public final class AttributeMetalJacket extends AbstractNode { + // This is the custom armor set that players will receive if no armor is on & attribute is equipped + public final Item jacketHelm = new ArmorItem(MetalJacketArmor.INSTANCE, ArmorItem.Type.HELMET, new Item.Settings()); + public final Item jacketChest = new ArmorItem(MetalJacketArmor.INSTANCE, ArmorItem.Type.CHESTPLATE, new Item.Settings()); + public final Item jacketLegs = new ArmorItem(MetalJacketArmor.INSTANCE, ArmorItem.Type.LEGGINGS, new Item.Settings()); + public final Item jacketBoots = new ArmorItem(MetalJacketArmor.INSTANCE, ArmorItem.Type.BOOTS, new Item.Settings()); + + public AttributeMetalJacket() { + // Finally register items with game + Keeblarcraft.LOGGER.debug("Registering metaljackets"); + ItemManager.RegisterItem("metaljacket_helmet", jacketHelm); + ItemManager.RegisterItem("metaljacket_chestplate", jacketChest); + ItemManager.RegisterItem("metaljacket_leggings", jacketLegs); + ItemManager.RegisterItem("metaljacket_boots", jacketBoots); + } + + @Override + public String GetNodeTitle() { + return "MetalJacket"; + } + + // Short description of node on hover-event in GUI + @Override + public String GetNodeDescription() { + return "MetalJacket affects armor value modifiers or gives player base armor when none is worn"; + } + + // Detailed description of node on click-event in GUI + @Override + public HashMap> GetDetails() { + HashMap> ret = new HashMap>(); + + // Filling out description item stuff here + ret.put("durability", List.of ( + "Gives player a base armor set with 3 protection and resistance", + "If armor is being worn, this attribute multiplies each pieces armor value by 120% (rounding up to nearest integer)" + )); + + return ret; + } +} diff --git a/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeTree.java b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeTree.java new file mode 100644 index 0000000..ade0da2 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/AttributeMgr/AttributeTree.java @@ -0,0 +1,218 @@ +/* + * + * AttributeTree + * + * Handles a players individual attribute tree + * + * +*/ + +package jesse.keeblarcraft.AttributeMgr; + +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; + +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode; +import jesse.keeblarcraft.ConfigMgr.ConfigManager; +import jesse.keeblarcraft.Utils.ChatUtil; +import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR; +import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION; + +public class AttributeTree { + + PlayerTree playerAttributeTree = new PlayerTree(); + ConfigManager config = new ConfigManager(); + private AbstractNode root = new RootNode(); + + private class TreeNode { + + public TreeNode(AbstractNode node, Integer maxLevel, List parents, List children) { + thisNode = node; + parentNodes = parents; + childrenNodes = children; + maxNodeLevel = maxLevel; + currentNodeLevel = 1; + } + + AbstractNode thisNode; + Integer currentNodeLevel; + Integer maxNodeLevel; + + // Store the names of the parent and children nodes; this lets a node have any number of parents and children + // NOTE TO DEVELOPERS: Be aware! The more nodes the harrier the tree will look in the GUI!!! Always test your + // code before just adding stuff willy-nilly! + List parentNodes; + List childrenNodes; + } + + // Separate structure as this is written to the config file + private class PlayerTree { + String uuid; + // Key = name of AbstractNode + // Val = The attribute itself + HashMap tree = new HashMap(); + } + + private class RootNode extends AbstractNode { + @Override + public String GetNodeTitle() { + return "root"; + } + + @Override + public String GetNodeDescription() { + return "This is the players tree root! All attributes extend from here"; + } + + @Override + public HashMap> GetDetails() { + HashMap> ret = new HashMap>(); + + ret.put("First Attribute", List.of("This is your skill tree", "All attributes grow from this root! Unlocking nodes requires all nodes connected to that previously to be unlocked first")); + + return ret; + } + } + + // Add a new node to the tree arbitrarily + // Root can never be a child node + // parents can never be empty or null (null or empty would imply you are adding root) + // + // developer warning: you must personally verify your nodes are in the tree. anywhere is fine, and the tree + // is very dynamic (which is why self verification is required). When the tree is drawn in the GUI, it starts from + // the root node. As long as your node is attached to this node anywhere in the indirected graph; then your attribute + // will be drawn in the gui + public Boolean AddNewNode(AbstractNode newNode, Integer maxNodeLevel, List parents, List children) { + Boolean ret = false; + TreeNode nodeReference = playerAttributeTree.tree.get(newNode.GetNodeTitle()); + + System.out.println("Is node reference null? -> " + (nodeReference == null ? "YES":"NO")); + System.out.println("Is root reference null? -> " + (root == null ? "YES":"NO")); + System.out.println("Is parents null? -> " + (parents == null ? "YES":"NO")); + + // Some special handling is required on checking child list in case it is null + Boolean validChildren = true; + if (children != null) { + validChildren = !children.contains(root.GetNodeTitle()); + } + + if (nodeReference == null && validChildren) { + // Since these values can be left as null, we want to guarentee they are at least initialized here + maxNodeLevel = (maxNodeLevel == null ? 1 : maxNodeLevel); + parents = (parents == null ? new ArrayList() : parents); + children = (children == null ? new ArrayList() : children); + + System.out.println("Parent size: " + parents.size()); + if (parents.size() == 0) { + System.out.println("Root node title: " + root.GetNodeTitle()); + parents.add(root.GetNodeTitle()); // No disconnected nodes allowed! All parentless nodes are adopted by root by default + } + System.out.println("Parents size: " + parents.size()); + + // Node implementation here + playerAttributeTree.tree.put(newNode.GetNodeTitle(), new TreeNode(newNode, maxNodeLevel, parents, children)); + + long pSize = playerAttributeTree.tree.get(newNode.GetNodeTitle()).parentNodes.size(); + System.out.println("parent size is " + pSize); + } else { + // Some fancy error handling for console log + if (nodeReference != null) { + Keeblarcraft.LOGGER.error("Attribute with name " + newNode.GetNodeTitle() + " was already found within the tree! Rename your node to add it"); + } else { + Keeblarcraft.LOGGER.error("The attribute you attempted to add (name: " + newNode.GetNodeTitle() + "), has root in the children"); + } + ret = false; + } + + FlashConfig(); + return ret; + } + + public void ChangeNodeLevel(String nodeName, Integer newLevel) { + TreeNode nodeReference = playerAttributeTree.tree.get(nodeName); + + if (nodeReference != null) { + if (newLevel <= nodeReference.maxNodeLevel) { + nodeReference.currentNodeLevel = newLevel; + } + } + + FlashConfig(); + } + + public void DeleteNode(String nodeName) { + // Do not delete root! + if (nodeName != root.GetNodeTitle()) { + playerAttributeTree.tree.remove(nodeName); + } + + FlashConfig(); + } + + public HashMap> GetNodeDetails(String nodeName) { + HashMap> ret = null; + + TreeNode nodeReference = playerAttributeTree.tree.get(nodeName); + + if (nodeReference != null) { + ret = nodeReference.thisNode.GetDetails(); + } + + return ret; + } + + // Returns the player's attribute tree + public PlayerTree GetPlayerTree() { + return playerAttributeTree; + } + + public AttributeTree(String uuid) { + // DEVELOPER NOTE: + // If you are testing this part of the code, please be reminded that anonymous testing starts a new + // player instance everytime you launch. This means the UUID CAN CHANGE when you launch the + // game! This is not an issue with proper registered accounts in production + Boolean existingFile = false; + try { + playerAttributeTree = config.GetJsonObjectFromFile("attributes/" + uuid + ".json", PlayerTree.class); + existingFile = true; + } catch (Exception e) { + // Do nothing. This means the file does not exist + } + + // In the event the above code failed out, this means a new file has to be created for the player's uuid + if (!existingFile) + { + System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE)); + try { + playerAttributeTree.uuid = uuid; + FlashConfig(); + } catch (Exception e) { + System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED)); + } + } else { + System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE)); + } + + // It's possible the above code will return a blank class if a file doesn't exist. This will make + // a new file with this players uuid + if ("".equals(playerAttributeTree.uuid)) { + System.out.println(ChatUtil.ColoredString("Assigning new config file for this uuid. No previous existing", CONSOLE_COLOR.BLUE)); + playerAttributeTree.uuid = uuid; + } + + // If the tree is empty or missing root, add it! + if (playerAttributeTree.tree.size() == 0 || playerAttributeTree.tree.containsKey(root.GetNodeTitle()) == false) { + playerAttributeTree.tree.put(root.GetNodeTitle(), new TreeNode(root, 1, null, null)); + } + } + + public void FlashConfig() { + try { + config.WriteToJsonFile("attributes/" + playerAttributeTree.uuid + ".json", playerAttributeTree); + } catch (FILE_WRITE_EXCEPTION e) { + System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED)); + } + } +} diff --git a/src/main/java/jesse/keeblarcraft/BankMgr/BankManager.java b/src/main/java/jesse/keeblarcraft/BankMgr/BankManager.java index 01e6e06..ccf6a31 100644 --- a/src/main/java/jesse/keeblarcraft/BankMgr/BankManager.java +++ b/src/main/java/jesse/keeblarcraft/BankMgr/BankManager.java @@ -165,7 +165,7 @@ public class BankManager { if (config.GetFile("bank/" + GetUuidByName(server, otherParty) + ".json").size() < 1) { BankManagerFile newBankInfo = new BankManagerFile(); BankManagerMetaData newBank = new BankManagerMetaData(0, "Account Created", 0, "Server", 0); - newBankInfo.bank.put(GetUuidByName(server, otherParty).toString(), newBank); + newBankInfo.bank.put(GetUuidByName(server, otherParty).toString(), newBank); try { config.WriteToJsonFile("bank/" + newBankInfo.uuid + ".json", newBankInfo); } catch (FILE_WRITE_EXCEPTION e) { @@ -193,7 +193,7 @@ public class BankManager { } catch (FILE_WRITE_EXCEPTION e) { System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED)); } - + } else { System.out.println(ChatUtil.ColoredString("Player Not Found: " + otherParty, CONSOLE_COLOR.RED)); return; diff --git a/src/main/java/jesse/keeblarcraft/Commands/AttributeCommands.java b/src/main/java/jesse/keeblarcraft/Commands/AttributeCommands.java new file mode 100644 index 0000000..a64b57c --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/Commands/AttributeCommands.java @@ -0,0 +1,109 @@ +/* + * + * AttributeCommands + * + * This class handles all the possible in-game commands for the attribute system + * + * +*/ + +package jesse.keeblarcraft.Commands; + +import java.util.Map.Entry; + +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; + +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.AttributeMgr.AttributeMgr; +import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.minecraft.command.argument.EntityArgumentType; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; + +public class AttributeCommands { + public void RegisterCommands() { + + // Command Root: "/attributes apply " + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("attributes") + .then(CommandManager.literal("apply") + .then(CommandManager.argument("username", EntityArgumentType.player())) + .then(CommandManager.argument("attributeName", StringArgumentType.string())) + .executes(context -> ApplyAttribute( + EntityArgumentType.getPlayer(context, "username"), + StringArgumentType.getString(context, "attributeName"), + context + )))); + }); + + // Command Root: "/attributes remove " + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("attributes") + .then(CommandManager.literal("delete") + .then(CommandManager.argument("username", EntityArgumentType.player())) + .then(CommandManager.argument("attributeName", StringArgumentType.greedyString())) + .executes(context -> DeleteAttribute( + EntityArgumentType.getPlayer(context, "username"), + StringArgumentType.getString(context, "attributeName"), + context + )))); + }); + + // Command Root: "/attribute-test " + /// TODO: Remove this in final version. This is purely debug + // CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + // dispatcher.register(CommandManager.literal("attribute-test") + // .then(CommandManager.argument("value", StringArgumentType.greedyString()) + // .executes(context -> ApplyAttribute(StringArgumentType.getString(context, "value"), context)))); + // }); + + // Command Root: "/list-attributes" + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + dispatcher.register(CommandManager.literal("list-attributes") + .executes(context -> ListAttributes(context))); + }); + } + + public int ApplyAttribute(ServerPlayerEntity targetPlayer, String attributeName, CommandContext context) { + int ret = -1; + + System.out.println("Applying attribute"); + if (context.getSource().isExecutedByPlayer()) { + System.out.println("Executed by player"); + // String result = AttributeMgr.ApplyAttribute(targetPlayer.getUuidAsString(), attributeName); + String result = AttributeMgr.ApplyAttribute(context.getSource().getPlayer().getUuidAsString(), attributeName); + Keeblarcraft.LOGGER.info("[ApplyAttribute] -> " + result); + context.getSource().getPlayer().sendMessage(Text.of(result)); + ret = 0; + } + + return ret; + } + + public int DeleteAttribute(ServerPlayerEntity username, String attributeName, CommandContext context) { + int ret = -1; + + + + return ret; + } + + public int ListAttributes(CommandContext context) { + int ret = -1; + + if (context.getSource().isExecutedByPlayer()) { + ServerPlayerEntity player = context.getSource().getPlayer(); + + for (Entry entry : AttributeMgr.attributes.entrySet()) { + Keeblarcraft.LOGGER.debug("ATTR-LIST: " + entry.getKey() + " LINKS " + entry.getValue().GetNodeTitle()); + player.sendMessage(Text.of(entry.getKey())); + } + } + + return ret; + } +} diff --git a/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java b/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java index 39736c4..0605bdd 100644 --- a/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java +++ b/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java @@ -21,12 +21,14 @@ public class CustomCommandManager { ShortcutCommands shortcuts = new ShortcutCommands(); NoteCommands noteCommands = new NoteCommands(); BankCommands bankCommands = new BankCommands(); + AttributeCommands attributeCommands = new AttributeCommands(); // REGISTER COMMANDS BELOW System.out.println(ChatUtil.ColoredString("REGISTERING CUSTOM COMMAND EXTENSIONS BELOW", CONSOLE_COLOR.BLUE)); shortcuts.RegisterShortcutCommands(); noteCommands.RegisterNoteCommands(); bankCommands.RegisterCommands(); - + attributeCommands.RegisterCommands(); + } } diff --git a/src/main/java/jesse/keeblarcraft/Commands/ShortcutCommands.java b/src/main/java/jesse/keeblarcraft/Commands/ShortcutCommands.java index 0b73ebe..692a744 100644 --- a/src/main/java/jesse/keeblarcraft/Commands/ShortcutCommands.java +++ b/src/main/java/jesse/keeblarcraft/Commands/ShortcutCommands.java @@ -4,6 +4,8 @@ * * A class that simplifies some of the current vanilla commands with shortcut commands in the game. You may remember an old plugin * called "Essentials" (Or EssentialsEx in a later version) -> This file is re-creating a portion of that plugin but in mod-format + * + * */ package jesse.keeblarcraft.Commands; @@ -21,7 +23,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; public class ShortcutCommands { - + float DEFAULT_FLIGHT_SPEED = 0.05f; // Minecraft operates on a 0.0 -> 1.0 scale; with each .01 making a difference in speed. 0.05 is creative flight speed float SPEED_SCALAR = 20.0f; // For clamping speed down to half of its max output (So 0.5 will be max speed on a system that goes up in 0.05'ths) @@ -34,7 +36,7 @@ public class ShortcutCommands { .executes(context -> GamemodeShortcut(IntegerArgumentType.getInteger(context, "value"), context)))); }); - // Fly command ///TODO: Is this just being condensed into the FlightSpeedShortcut fn? + // Fly command CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { dispatcher.register(CommandManager.literal("fly") .executes(context -> { FlightShortcut(context); diff --git a/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java b/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java index dd8110a..029c609 100644 --- a/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java +++ b/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java @@ -12,7 +12,6 @@ package jesse.keeblarcraft.ConfigMgr; import java.io.FileWriter; -import java.io.FileReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -21,27 +20,19 @@ import com.google.common.base.Charsets; import com.google.common.io.Files; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; import com.google.gson.JsonIOException; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import java.util.List; import org.apache.commons.io.FileUtils; -import org.spongepowered.asm.mixin.injection.struct.InjectorGroupInfo.Map; import java.util.ArrayList; import jesse.keeblarcraft.Utils.ChatUtil; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR; -// Import all custom exceptions import jesse.keeblarcraft.Utils.CustomExceptions.*; -//minecraft server instance -import net.minecraft.server.MinecraftServer; - public class ConfigManager { // Pedantic empty constructor diff --git a/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockManager.java b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockManager.java new file mode 100644 index 0000000..7c83f31 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockManager.java @@ -0,0 +1,67 @@ +package jesse.keeblarcraft.CustomBlocks; + +import java.util.ArrayList; +import java.util.List; + +import jesse.keeblarcraft.Keeblarcraft; +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.item.BlockItem; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.util.Identifier; + +public class BlockManager { + + /// The block list. DO NOT ADD TO THE LIST YOURSELF. USE + /// THE RegisterBlock(...) FUNCTION OTHERWISE YOUR BLOCK WILL + /// NOT BE REGISTERED PROPERLY AND MAY BREAK THE GAME + public static final List blockList = new ArrayList(); + + ///////////////////////////////////////////////////////////////////////////// + /// @fn RegisterBlock + /// + /// @arg[in] name is the block name. IMPORTANT: Name must adhere to rules: + /// 1. The name provided here must match these names: + /// * This blocks models/block name + /// * This blocks textures/block name + /// 2 Name must be lowercase & no special characters besides '_' + /// + /// @arg[in] block is the block to be added to the block list + /// + /// @brief This is the call to register your block to the game! Please + /// do not forget to update the models/block json file, the + /// textures/block png name, and finally the lang/en_us.json file + ///////////////////////////////////////////////////////////////////////////// + public static void RegisterBlock(String name, Block block) { + + // This call registers the block as an item in inventories + Registry.register(Registries.ITEM, new Identifier(Keeblarcraft.MOD_ID, name), new BlockItem(block, new FabricItemSettings())); + + // This call registers the block as placed + Block newBlock = Registry.register(Registries.BLOCK, new Identifier(Keeblarcraft.MOD_ID, name), block); + + // Add the block to the block list + blockList.add(newBlock); + } + + ///////////////////////////////////////////////////////////////////////////// + /// @fn RegisterBlocks + /// + /// @brief This function is only meant to be called by the main mod + /// execution path and should only be called once. This is a + /// glorified print statement - but also serves to add the + /// example block in the game + ///////////////////////////////////////////////////////////////////////////// + public static void RegisterBlocks() { + Keeblarcraft.LOGGER.info("Registering modded blocks for " + Keeblarcraft.MOD_ID); + + // Register example block to the mod + Block exampleBlock = new Block(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).sounds(BlockSoundGroup.AMETHYST_BLOCK)); + RegisterBlock("example_block", exampleBlock); + } + +} diff --git a/src/main/java/jesse/keeblarcraft/CustomItems/CustomItemGroups.java b/src/main/java/jesse/keeblarcraft/CustomItems/CustomItemGroups.java new file mode 100644 index 0000000..5b71ea8 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/CustomItems/CustomItemGroups.java @@ -0,0 +1,41 @@ +package jesse.keeblarcraft.CustomItems; + +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.CustomBlocks.BlockManager; +import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public class CustomItemGroups { + + // This is the custom mod group for the mod + public static final ItemGroup MOD_GROUP = Registry.register(Registries.ITEM_GROUP, + new Identifier(Keeblarcraft.MOD_ID, "keeblarcraft"), + FabricItemGroup.builder().displayName(Text.translatable("itemgroup.keeblarcraft")) + .icon(() -> new ItemStack(Items.ANVIL)).entries((displayContext, entries) -> { + // We iterate through all the modded items and add them to the custom item group here + for (int i = 0; i < ItemManager.itemList.size(); i++) { + entries.add(ItemManager.itemList.get(i)); + } + + // We iterate through all the modded blocks and add them to the custom block group here + for (int i = 0; i < BlockManager.blockList.size(); i++) { + entries.add(BlockManager.blockList.get(i)); + } + }).build()); + + ///////////////////////////////////////////////////////////////////////////// + /// @fn RegisterGroups + /// + /// @brief Glorified print statement that the class has initialized + /// basically - meaning that all item groups have registered + ///////////////////////////////////////////////////////////////////////////// + public static void RegisterGroups() { + Keeblarcraft.LOGGER.info("Registering item groups for " + Keeblarcraft.MOD_ID); + } +} diff --git a/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java b/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java new file mode 100644 index 0000000..e687f57 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/CustomItems/ItemManager.java @@ -0,0 +1,70 @@ +/* + * + * ItemManager + * + * This is the general purpose item manager for the mod. All items will be registered through + * this class in order to make custom items a lot cleaner to make! + * + * +*/ + +package jesse.keeblarcraft.CustomItems; + +import java.util.ArrayList; +import java.util.List; + +import jesse.keeblarcraft.Keeblarcraft; +import net.fabricmc.fabric.api.item.v1.FabricItemSettings; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +public class ItemManager { + + /// The item list. DO NOT ADD TO THE LIST YOURSELF. USE + /// THE RegisterItem(...) FUNCTION OTHERWISE YOUR ITEM WILL + /// NOT BE REGISTERED PROPERLY AND MAY BREAK THE GAME + public static final List itemList = new ArrayList(); + + + ///////////////////////////////////////////////////////////////////////////// + /// @fn RegisterItem + /// + /// @arg[in] name is the item name. IMPORTANT: Name must adhere to rules: + /// 1. The name provided here must match these names: + /// * This items models/item name + /// * This items textures/item name + /// 2 Name must be lowercase & no special characters besides '_' + /// + /// @arg[in] item is the item to be added to the item list + /// + /// @brief This is the call to register your item to the game! Please + /// do not forget to update the models/item json file, the + /// textures/item png name, and finally the lang/en_us.json file + ///////////////////////////////////////////////////////////////////////////// + public static void RegisterItem(String name, Item item) { + Item newItem = Registry.register(Registries.ITEM, new Identifier(Keeblarcraft.MOD_ID, name), item); + itemList.add(newItem); + } + + ///////////////////////////////////////////////////////////////////////////// + /// @fn RegisterAllItems + /// + /// @brief This function is only meant to be called by the main mod + /// execution path and should only be called once. This is a + /// glorified print statement - but also serves to add the + /// example item in the game + ///////////////////////////////////////////////////////////////////////////// + public static void RegisterAllItems() { + Keeblarcraft.LOGGER.info("Registering mod items for " + Keeblarcraft.MOD_ID); + + // Call the item group register function first + CustomItemGroups.RegisterGroups(); + + // The example item provides a demo of how you could make an item in your class + // Item exampleItem = new Item(new FabricItemSettings()); + // RegisterItem("metaljacket_helmet", exampleItem); + } + +} diff --git a/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java b/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java index 12ca41e..6c7b307 100644 --- a/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java +++ b/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java @@ -7,7 +7,6 @@ package jesse.keeblarcraft.JsonClassObjects; -import java.math.BigInteger; import java.util.HashMap; import java.util.Map.Entry; diff --git a/src/main/java/jesse/keeblarcraft/Keeblarcraft.java b/src/main/java/jesse/keeblarcraft/Keeblarcraft.java index f981ba6..b7446b5 100644 --- a/src/main/java/jesse/keeblarcraft/Keeblarcraft.java +++ b/src/main/java/jesse/keeblarcraft/Keeblarcraft.java @@ -15,7 +15,11 @@ import net.fabricmc.api.ModInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import jesse.keeblarcraft.AttributeMgr.AttributeMgr; import jesse.keeblarcraft.Commands.CustomCommandManager; +import jesse.keeblarcraft.CustomBlocks.BlockManager; +import jesse.keeblarcraft.CustomItems.CustomItemGroups; +import jesse.keeblarcraft.CustomItems.ItemManager; import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION; import jesse.keeblarcraft.Utils.ChatUtil; import jesse.keeblarcraft.Utils.Setup; @@ -28,6 +32,7 @@ public class Keeblarcraft implements ModInitializer { // This logger is used to write text to the console and the log file. // It is considered best practice to use your mod id as the logger's name. // That way, it's clear which mod wrote info, warnings, and errors. + public static String MOD_ID = "keeblarcraft"; public static final Logger LOGGER = LoggerFactory.getLogger("keeblarcraft"); CustomCommandManager cmdMgr = new CustomCommandManager(); @@ -50,6 +55,18 @@ public class Keeblarcraft implements ModInitializer { LOGGER.info("\033[34m Running command registration \033[0m"); cmdMgr.RegisterCustomCommands(); + // Register attributes + AttributeMgr.RegisterAttributes(); + + + /// THE BELOW ITEMS MUST BE DONE LAST IN THE STEPS + // Register items + ItemManager.RegisterAllItems(); + + // Register blocks + BlockManager.RegisterBlocks(); + + } catch (SETUP_FAILED_EXCEPTION e) { System.out.println(ChatUtil.ColoredString("ERROR. Setup failed to initialize environment. Mod likely does not have read/write permissions inside area. Mod will now close out.", CONSOLE_COLOR.RED)); e.printStackTrace(); diff --git a/src/main/java/jesse/keeblarcraft/ServerTickListener.java b/src/main/java/jesse/keeblarcraft/Utils/ServerTickListener.java similarity index 95% rename from src/main/java/jesse/keeblarcraft/ServerTickListener.java rename to src/main/java/jesse/keeblarcraft/Utils/ServerTickListener.java index b31258a..4637cb3 100644 --- a/src/main/java/jesse/keeblarcraft/ServerTickListener.java +++ b/src/main/java/jesse/keeblarcraft/Utils/ServerTickListener.java @@ -1,4 +1,4 @@ -package jesse.keeblarcraft; +package jesse.keeblarcraft.Utils; import jesse.CommonServerUtils; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; diff --git a/src/main/java/jesse/keeblarcraft/Utils/Setup.java b/src/main/java/jesse/keeblarcraft/Utils/Setup.java index a824252..1981fc2 100644 --- a/src/main/java/jesse/keeblarcraft/Utils/Setup.java +++ b/src/main/java/jesse/keeblarcraft/Utils/Setup.java @@ -12,17 +12,11 @@ package jesse.keeblarcraft.Utils; import java.util.List; -import org.apache.commons.io.FileUtils; -import org.spongepowered.include.com.google.common.io.Files; -import java.util.List; import java.util.ArrayList; -import jesse.keeblarcraft.Keeblarcraft; -import jesse.keeblarcraft.ServerTickListener; import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR; import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION; -import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_DELETE_EXCEPTION; import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION; // Singleton class is designed to help the mod set itself up and create all the important things. It does two things: @@ -62,14 +56,16 @@ public final class Setup { add("commands"); // Expect 1 file per command that's configurable! add("events"); // Expect 1 file per event that is configurable! add("bank"); + add("attributes"); }}; // These will be top-level config files above the directories this mod creates private static final List FILE_LIST = new ArrayList() {{ - add("story/story.json"); // Big config file, determines when players can do certain things at different story levels - add("factions/factions.json"); // General configuration file for factions stuff - add("events/1events.json"); // General configuration file for story events! + add("story/general_story_config.json"); // Big config file, determines when players can do certain things at different story levels + add("factions/general_factions_config.json"); // General configuration file for factions stuff + add("events/general_event_config.json"); // General configuration file for story events! add("general.json"); // The super general configuration file! (May be removed) + add("attributes/general_attribute_config.json"); }}; // RunChecks() @@ -166,7 +162,7 @@ public final class Setup { System.out.println(ChatUtil.ColoredString("servertick failed to inilize.", CONSOLE_COLOR.RED)); throw new SETUP_FAILED_EXCEPTION(); } - + System.out.println(ChatUtil.ColoredString("DID SETUP COMPLETE SUCCESSFULLY? ", CONSOLE_COLOR.YELLOW) + (ret ? ChatUtil.ColoredString("YES", CONSOLE_COLOR.YELLOW) : ChatUtil.ColoredString("NO", CONSOLE_COLOR.YELLOW))); return ret; diff --git a/src/main/resources/assets/keeblarcraft/blockstates/example_block.json b/src/main/resources/assets/keeblarcraft/blockstates/example_block.json new file mode 100644 index 0000000..5fe6687 --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/blockstates/example_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "keeblarcraft:block/example_block" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/lang/en_us.json b/src/main/resources/assets/keeblarcraft/lang/en_us.json new file mode 100644 index 0000000..23ed88c --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/lang/en_us.json @@ -0,0 +1,10 @@ +{ + "item.keeblarcraft.metaljacket_helmet": "MetalJacket Helmet", + "item.keeblarcraft.metaljacket_chestplate": "MetalJacket Chestplate", + "item.keeblarcraft.metaljacket_leggings": "MetalJacket Leggings", + "item.keeblarcraft.metaljacket_boots": "MetalJacket Booties", + + "itemgroup.keeblarcraft": "Keeblarcraft Modded Items", + + "block.keeblarcraft.example_block": "Keeblarcraft example block" +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/models/block/example_block.json b/src/main/resources/assets/keeblarcraft/models/block/example_block.json new file mode 100644 index 0000000..05cacac --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/block/example_block.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "keeblarcraft:block/example_block" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/models/item/example_block.json b/src/main/resources/assets/keeblarcraft/models/item/example_block.json new file mode 100644 index 0000000..3b9b562 --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/item/example_block.json @@ -0,0 +1,3 @@ +{ + "parent": "keeblarcraft:block/example_block" +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/models/item/metaljacket_boots.json b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_boots.json new file mode 100644 index 0000000..6ce6192 --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "keeblarcraft:item/metaljacket_boots" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/models/item/metaljacket_chestplate.json b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_chestplate.json new file mode 100644 index 0000000..2950213 --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "keeblarcraft:item/metaljacket_chestplate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/models/item/metaljacket_helmet.json b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_helmet.json new file mode 100644 index 0000000..7301828 --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "keeblarcraft:item/metaljacket_helmet" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/models/item/metaljacket_leggings.json b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_leggings.json new file mode 100644 index 0000000..6e82a01 --- /dev/null +++ b/src/main/resources/assets/keeblarcraft/models/item/metaljacket_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "keeblarcraft:item/metaljacket_leggings" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/keeblarcraft/textures/block/example_block.png b/src/main/resources/assets/keeblarcraft/textures/block/example_block.png new file mode 100644 index 0000000..0a7db9b Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/block/example_block.png differ diff --git a/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_boots.png b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_boots.png new file mode 100644 index 0000000..b6092f2 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_boots.png differ diff --git a/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_chestplate.png b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_chestplate.png new file mode 100644 index 0000000..996534b Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_chestplate.png differ diff --git a/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_helmet.png b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_helmet.png new file mode 100644 index 0000000..e0c6582 Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_helmet.png differ diff --git a/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_leggings.png b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_leggings.png new file mode 100644 index 0000000..4d37c8d Binary files /dev/null and b/src/main/resources/assets/keeblarcraft/textures/item/metaljacket_leggings.png differ diff --git a/src/main/resources/assets/keeblarcraft/textures/models/armor/metaljacket_layer_1.png b/src/main/resources/assets/keeblarcraft/textures/models/armor/metaljacket_layer_1.png new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/assets/keeblarcraft/textures/models/armor/metaljacket_layer_2.png b/src/main/resources/assets/keeblarcraft/textures/models/armor/metaljacket_layer_2.png new file mode 100644 index 0000000..e69de29