diff --git a/README.md b/README.md index 2da271dba..c4634d53e 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,43 @@ ## 👋 Welcome to the CustomNPC+ Repository. -![](images/logo.png) +![](images/logo_banner.png) > CustomNPC+ is a [Minecraft](https://minecraft.net/) mod that allows you to add custom NPCs to your world. It is developed for creative and storytelling players who want to make their Minecraft worlds more in-depth and unique. CustomNPC+ is only a branch version of the **1.7.10** Forge version of the original (down below) and has no plans to add or update any other version. This is not an official version of CustomNPC. -**CurseForge**: [Download](https://www.curseforge.com/minecraft/mc-mods/customnpc-plus) +---------------- -[![Discord Badge](https://img.shields.io/badge/KAMKEEL_Discord-7289DA?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/pQqRTvFeJ5) -[![Download CustomNPC+](https://img.shields.io/badge/CustomNPC+-0081CB?style=for-the-badge&logo=material-ui&logoColor=white)](https://www.curseforge.com/minecraft/mc-mods/customnpc-plus) -[![Download CustomNPC+](https://img.shields.io/badge/MorePlayerModels+-0081CB?style=for-the-badge&logo=material-ui&logoColor=white)](https://www.curseforge.com/minecraft/mc-mods/moreplayermodels-plus) + + Support Me + +[![Download CustomNPC+](https://img.shields.io/badge/CustomNPC+-0081CB?style=for-the-badge&logo=material-ui&logoColor=white)](https://modrinth.com/mod/customnpc-plus) +[![Download MPM+](https://img.shields.io/badge/MorePlayerModels+-0081CB?style=for-the-badge&logo=material-ui&logoColor=white)](https://www.curseforge.com/minecraft/mc-mods/moreplayermodels-plus) [![Download PluginMod](https://img.shields.io/badge/Plugin_Mod-0081CB?style=for-the-badge&logo=material-ui&logoColor=white)](https://github.com/KAMKEEL/Plugin-Mod) - Support Me +---------------- ### ❗ Notice -I am not the original creator of CustomNPC. The original creator is @[Noppes](https://github.com/Noppes). I have been permitted to update the 1.7.10 and post my results on GitHub. The original mod that is updated to the latest versions of Minecraft can be found on these links: [CurseForge](https://www.curseforge.com/minecraft/mc-mods/custom-npcs), [kodevelopment](http://www.kodevelopment.nl/minecraft/customnpcs) +I am not the original creator of CustomNPC. The original creator is @[Noppes](https://github.com/Noppes). I have been permitted to update and develop my own branch version for 1.7.10. The original mod that is updated to the latest versions of Minecraft can be found on these links: [CurseForge](https://www.curseforge.com/minecraft/mc-mods/custom-npcs), [kodevelopment](http://www.kodevelopment.nl/minecraft/customnpcs) + +### ⬇️ Downloads + +- **Modrinth**: [Download](https://modrinth.com/mod/customnpc-plus) +- **CurseForge**: [Download](https://www.curseforge.com/minecraft/mc-mods/customnpc-plus) ### 🔹 Installation This mod is an ***update*** to CustomNPC and not an add-on. Do not install CustomNPC with CustomNPC-Plus. CustomNPC-Plus does not remove any functional features from the original mod. It expands upon CustomNPC with original features and backported features from newer versions. Simply drag CustomNPC-Plus into any client/server mods folder to utilize. Please **backup** before using as this could still have unforeseen errors. Report any bugs if found, thank you and enjoy. ### ❓ Features: - Flying NPC (Smart Pathfinding) -- 1.8 Skin Support (64x64) (3D Bodywear) +- 1.8 Skin Support (64x64) (Alex/Steve64) - Full URL64 Selector (Downloads FULL Size Images for Custom Mob Skins) -- Alex Model (64x64) - Additional Parts: [Wings, Fins, Capes, Horns, Tail] - Hide Body Parts [Arms, Legs, Head, Body] - Custom Overlays -- Updated Cloner GUI (with more Tabs!) +- Animation Maker +- Enhanced Cloner GUI (More Tabs, Filters, Tags) - Markov Name Generator -- Backported GUI Features - Dark Mode GUI (Link Below) - 1.12 Scripting Features (Details below) -- Script Logging (See Config) #### Scripting: - CustomNPC+ Api: [API](https://github.com/KAMKEEL/CustomNPC-Plus-API) @@ -41,7 +46,9 @@ This mod is an ***update*** to CustomNPC and not an add-on. Do not install Custo - Player Overlays - Script Timers - Global Scripts +- Script Logging - GUI Overlays +- Event Scripting (We never remove script functionality, only add on existing functions) ## 🔰 Skin Model Feature: diff --git a/build.gradle b/build.gradle index 4efad6687..85ad4cf23 100644 --- a/build.gradle +++ b/build.gradle @@ -34,7 +34,7 @@ configurations { apply plugin: 'forge' -version = "1.8-beta" +version = "1.8.1" group= "com.kamkeel.customnpc-plus" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "CustomNPC-Plus" @@ -113,7 +113,7 @@ def refMapForYourConfig = 'customnpcs.refmap.json' def relativePathToMixinAP = 'tools/mixin-0.8-SNAPSHOT.jar' if(!embedMixin){ - version += "+nomixin" + version += "-nomixin" } repositories { diff --git a/images/Discord.png b/images/Discord.png new file mode 100644 index 000000000..a17aa7cc7 Binary files /dev/null and b/images/Discord.png differ diff --git a/images/Kofi.png b/images/Kofi.png new file mode 100644 index 000000000..6ef737004 Binary files /dev/null and b/images/Kofi.png differ diff --git a/images/logo_banner.png b/images/logo_banner.png new file mode 100644 index 000000000..c3a0de7e2 Binary files /dev/null and b/images/logo_banner.png differ diff --git a/images/logo.png b/images/logo_old.png similarity index 100% rename from images/logo.png rename to images/logo_old.png diff --git a/src/main/java/kamkeel/AnimationCommand.java b/src/main/java/kamkeel/AnimationCommand.java index 2326fe809..ef6e6edec 100644 --- a/src/main/java/kamkeel/AnimationCommand.java +++ b/src/main/java/kamkeel/AnimationCommand.java @@ -30,7 +30,7 @@ public class AnimationCommand extends CommandKamkeelBase { @Override public String getUsage() { - return " "; + return " "; } @Override @@ -41,27 +41,53 @@ public class AnimationCommand extends CommandKamkeelBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { String playername = args[0]; - String animationName = args[1]; data = PlayerDataController.instance.getPlayersData(sender, playername); if (data.isEmpty()) { throw new CommandException("Unknown player: " + playername); } - - selectedAnimation = AnimationController.getInstance().getAnimationFromName(animationName); + processSubCommand(sender, args[1], Arrays.copyOfRange(args, 2, args.length)); + data.get(0).animationData.updateClient(); + data.get(0).savePlayerDataOnFile(); + } + + @SubCommand(desc = "enable animation") + public void on(ICommandSender sender, String[] args) throws CommandException { + data.get(0).animationData.setEnabled(true); + sendMessage(sender, String.format("Animations enabled for Player %s", data.get(0).player.getCommandSenderName())); + + } + + @SubCommand( + desc = "Set animation", + usage = "" + ) + public void set(ICommandSender sender, String[] args) throws CommandException { + if(args.length != 1){ + throw new CommandException("Please include the animation name:" + " set "); + } + String animationName = args[0]; + selectedAnimation = AnimationController.getInstance().getAnimationFromName(animationName); if (selectedAnimation == null) { throw new CommandException("Unknown animation: " + animationName); } - - processSubCommand(sender, args[2], Arrays.copyOfRange(args, 3, args.length)); - } - @SubCommand( - desc = "play animation", - usage = " play" - ) - public void play(ICommandSender sender, String[] args) throws CommandException { + data.get(0).animationData.setAnimation(selectedAnimation); + sendMessage(sender, String.format("Animation %s set for Player %s", selectedAnimation.getName(), data.get(0).player.getCommandSenderName())); + } + + @SubCommand(desc = "disable animation") + public void off(ICommandSender sender, String[] args) throws CommandException { + data.get(0).animationData.setEnabled(false); + sendMessage(sender, String.format("Animations disabled for Player %s", data.get(0).player.getCommandSenderName())); + } + + @SubCommand(desc = "play animation") + public void clear(ICommandSender sender, String[] args) throws CommandException { + data.get(0).animationData.setEnabled(false); + data.get(0).animationData.setAnimation(null); + sendMessage(sender, String.format("Animations cleared for Player %s", data.get(0).player.getCommandSenderName())); } } diff --git a/src/main/java/noppes/npcs/CustomNpcs.java b/src/main/java/noppes/npcs/CustomNpcs.java index 7eaa5d533..4037a99d9 100644 --- a/src/main/java/noppes/npcs/CustomNpcs.java +++ b/src/main/java/noppes/npcs/CustomNpcs.java @@ -35,7 +35,7 @@ import java.util.ArrayList; import java.util.Set; import java.util.UUID; -@Mod(modid = "customnpcs", name = "CustomNpcs", version = "1.8-beta") +@Mod(modid = "customnpcs", name = "CustomNpcs", version = "1.8.1") public class CustomNpcs { @SidedProxy(clientSide = "noppes.npcs.client.ClientProxy", serverSide = "noppes.npcs.CommonProxy") diff --git a/src/main/java/noppes/npcs/DataAdvanced.java b/src/main/java/noppes/npcs/DataAdvanced.java index 82f6b572d..0685ca947 100644 --- a/src/main/java/noppes/npcs/DataAdvanced.java +++ b/src/main/java/noppes/npcs/DataAdvanced.java @@ -83,11 +83,13 @@ public class DataAdvanced { compound.setString("SoulStonePlayerName", soulStonePlayerName); compound.setInteger("MinFactionPointsToSoulStone", minFactionPointsToSoulStone); - NBTTagList nbtTagList = new NBTTagList(); - for (UUID uuid : tagUUIDs) { - nbtTagList.appendTag(new NBTTagString(uuid.toString())); + if(tagUUIDs.size() > 0){ + NBTTagList nbtTagList = new NBTTagList(); + for (UUID uuid : tagUUIDs) { + nbtTagList.appendTag(new NBTTagString(uuid.toString())); + } + compound.setTag("TagUUIDs", nbtTagList); } - compound.setTag("TagUUIDs", nbtTagList); return compound; } @@ -124,9 +126,11 @@ public class DataAdvanced { soulStonePlayerName = compound.getString("SoulStonePlayerName"); minFactionPointsToSoulStone = compound.getInteger("MinFactionPointsToSoulStone"); - NBTTagList nbtTagList = compound.getTagList("TagUUIDs",8); - for (int i = 0; i < nbtTagList.tagCount(); i++) { - tagUUIDs.add(UUID.fromString(nbtTagList.getStringTagAt(i))); + if(compound.hasKey("TagUUIDs")){ + NBTTagList nbtTagList = compound.getTagList("TagUUIDs",8); + for (int i = 0; i < nbtTagList.tagCount(); i++) { + tagUUIDs.add(UUID.fromString(nbtTagList.getStringTagAt(i))); + } } } diff --git a/src/main/java/noppes/npcs/PacketHandlerServer.java b/src/main/java/noppes/npcs/PacketHandlerServer.java index b52f9a4c6..13376a8f1 100644 --- a/src/main/java/noppes/npcs/PacketHandlerServer.java +++ b/src/main/java/noppes/npcs/PacketHandlerServer.java @@ -985,12 +985,17 @@ public class PacketHandlerServer{ } else if(type == EnumPacketServer.CloneList){ NBTTagList list = new NBTTagList(); - - for(String name : ServerCloneController.Instance.getClones(buffer.readInt())) + int tab = buffer.readInt(); + for(String name : ServerCloneController.Instance.getClones(tab)) list.appendTag(new NBTTagString(name)); + NBTTagList listDate = new NBTTagList(); + for(String name : ServerCloneController.Instance.getClonesDate(tab)) + listDate.appendTag(new NBTTagString(name)); + NBTTagCompound compound = new NBTTagCompound(); compound.setTag("List", list); + compound.setTag("ListDate", listDate); Server.sendData(player, EnumPacketClient.GUI_DATA, compound); } @@ -1043,7 +1048,10 @@ public class PacketHandlerServer{ PlayerData data = PlayerDataController.instance.getPlayerData(player); if(data.cloned == null) return; - ServerCloneController.Instance.addClone(data.cloned, Server.readString(buffer), buffer.readInt()); + String name = Server.readString(buffer); + int tab = buffer.readInt(); + NBTTagCompound tagExtra = Server.readNBT(buffer); + ServerCloneController.Instance.addClone(data.cloned, name, tab, tagExtra); } else if(type == EnumPacketServer.CloneRemove){ int tab = buffer.readInt(); @@ -1054,19 +1062,29 @@ public class PacketHandlerServer{ for(String name : ServerCloneController.Instance.getClones(tab)) list.appendTag(new NBTTagString(name)); + NBTTagList listDate = new NBTTagList(); + for(String name : ServerCloneController.Instance.getClonesDate(tab)) + listDate.appendTag(new NBTTagString(name)); + NBTTagCompound compound = new NBTTagCompound(); compound.setTag("List", list); + compound.setTag("ListDate", listDate); Server.sendData(player, EnumPacketClient.GUI_DATA, compound); } else if(type == EnumPacketServer.CloneList){ NBTTagList list = new NBTTagList(); - - for(String name : ServerCloneController.Instance.getClones(buffer.readInt())) + int tab = buffer.readInt(); + for(String name : ServerCloneController.Instance.getClones(tab)) list.appendTag(new NBTTagString(name)); + NBTTagList listDate = new NBTTagList(); + for(String name : ServerCloneController.Instance.getClonesDate(tab)) + listDate.appendTag(new NBTTagString(name)); + NBTTagCompound compound = new NBTTagCompound(); compound.setTag("List", list); + compound.setTag("ListDate", listDate); Server.sendData(player, EnumPacketClient.GUI_DATA, compound); } @@ -1089,6 +1107,18 @@ public class PacketHandlerServer{ compound.setTag("AllTags", validTagList); Server.sendData(player, EnumPacketClient.GUI_DATA, compound); } + else if (type == EnumPacketServer.CloneAllTagsShort) { + NBTTagCompound compound = new NBTTagCompound(); + HashSet validTags = TagController.getInstance().getAllTags(); + NBTTagList validTagList = new NBTTagList(); + for(Tag tag : validTags){ + NBTTagCompound tagCompound = new NBTTagCompound(); + tag.writeShortNBT(tagCompound); + validTagList.appendTag(tagCompound); + } + compound.setTag("ShortTags", validTagList); + Server.sendData(player, EnumPacketClient.GUI_DATA, compound); + } else if (type == EnumPacketServer.TagSet) { EntityNPCInterface npc = NoppesUtilServer.getEditingNpc(player); this.setTags(npc,buffer); diff --git a/src/main/java/noppes/npcs/VersionCompatibility.java b/src/main/java/noppes/npcs/VersionCompatibility.java index fa63cb159..a16e48a3d 100644 --- a/src/main/java/noppes/npcs/VersionCompatibility.java +++ b/src/main/java/noppes/npcs/VersionCompatibility.java @@ -13,7 +13,7 @@ import java.util.Collection; import java.util.List; public class VersionCompatibility { - public static int ModRev = 20; + public static int ModRev = 21; public static void CheckNpcCompatibility(EntityNPCInterface npc, NBTTagCompound compound){ if(npc.npcVersion == ModRev) diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java index 693ce20c7..ec65abc7e 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java @@ -25,7 +25,14 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { public static HashMap tagNames = new HashMap<>(); public static HashSet tagFilters = new HashSet<>(); public static byte displayTags = 0; - public static boolean ascending = true; + + // 0 - Any, 1 - All, 2 - Not Any, 3 - Not All + public static byte filterCondition = 0; + + public static byte ascending = 0; + + // 0 - By Name, 1 - By Date + public static byte sortType = 0; public TagMap tagMap; @@ -118,17 +125,38 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { } } else { // Show Filters - addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("menu.tags"), guiLeft + 7, guiTop + 7)); + addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("cloner.tagFilters"), guiLeft + 7, guiTop + 7)); addScroll(filterScroll); addTextField(new GuiNpcTextField(2, this, fontRendererObj, guiLeft + 4, guiTop + 190, 140, 20, tagSearch)); - addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("display.visible") + ":", guiLeft + 150, guiTop + 27)); - addButton(new GuiNpcButton(12, guiLeft + 190, guiTop + 20, new String[]{"display.show", "display.all", "display.hide"}, displayTags)); - addButton(new GuiNpcButton(11, guiLeft + 150, guiTop + 43, 100, 20, "gui.deselectAll")); + addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("cloner.tagVisibility"), guiLeft + 150, guiTop + 27)); + addButton(new GuiNpcButton(12, guiLeft + 215, guiTop + 20, new String[]{"display.show", "display.all", "display.hide"}, displayTags)); - getButton(12).width = 60; + addLabel(new GuiNpcLabel(3, StatCollector.translateToLocal("filter.contains"), guiLeft + 150, guiTop + 50)); + addButton(new GuiNpcButton(13, guiLeft + 215, guiTop + 43, new String[]{"filter.any", "filter.all", "filter.notany", "filter.notall"}, filterCondition)); + + addButton(new GuiNpcButton(11, guiLeft + 150, guiTop + 66, 130, 20, "gui.deselectAll")); + + + addLabel(new GuiNpcLabel(4, StatCollector.translateToLocal("cloner.order"), guiLeft + 150, guiTop + 112)); + addButton(new GuiNpcButton(14, guiLeft + 215, guiTop + 105, new String[]{"cloner.ascending", "cloner.descending"}, ascending)); + + addLabel(new GuiNpcLabel(5, StatCollector.translateToLocal("cloner.type"), guiLeft + 150, guiTop + 135)); + addButton(new GuiNpcButton(15, guiLeft + 215, guiTop + 128, new String[]{"cloner.name", "cloner.date"}, sortType)); + + + getButton(12).width = 65; getButton(12).height = 20; + getButton(13).width = 65; + getButton(13).height = 20; + + getButton(14).width = 65; + getButton(14).height = 20; + + getButton(15).width = 65; + getButton(15).height = 20; + showFilters(); } } @@ -153,7 +181,7 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { } } this.list = list; - scroll.setList(getSearchList(), ascending); + scroll.setList(getSearchList(), ascending == 0, sortType == 0); } private void showClones() { if(showingClones == 2){ @@ -161,10 +189,16 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { Client.sendData(EnumPacketServer.CloneList, activeTab); return; } - ArrayList list = new ArrayList(); - this.list = ClientCloneController.Instance.getClones(activeTab); + + if(sortType == 0){ + this.list = ClientCloneController.Instance.getClones(activeTab); + } + else { + this.list = ClientCloneController.Instance.getClonesDate(activeTab); + } + this.tagMap = ClientTagMapController.Instance.getTagMap(activeTab); - scroll.setList(getSearchList(), ascending); + scroll.setList(getSearchList(), ascending == 0, sortType == 0); } public void keyTyped(char c, int i) { @@ -173,7 +207,7 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { if(search.equals(getTextField(1).getText())) return; search = getTextField(1).getText().toLowerCase(); - scroll.setList(getSearchList(), ascending); + scroll.setList(getSearchList(), ascending == 0, sortType == 0); } if(getTextField(2) != null){ if(tagSearch.equals(getTextField(2).getText())) @@ -188,56 +222,45 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { if(this.list == null){ this.list = new ArrayList(); } - // No Search // No Filters - or - Entities - if(search.isEmpty() && (tagFilters.size() == 0 || showingClones == 1)) - return new ArrayList(list); - // Yes Search // No Filters - or - Entities - else if(!search.isEmpty() && (tagFilters.size() == 0 || showingClones == 1)){ - List list = new ArrayList(); - for(String name : this.list){ - if(name.toLowerCase().contains(search)) - list.add(name); + + // No Filters - or - Entities + if(tagFilters.size() == 0 || showingClones == 1){ + // No Search + if(search.isEmpty()) + return new ArrayList(this.list); + // Yes Search + else { + List list = new ArrayList(); + for(String name : this.list){ + if(name.toLowerCase().contains(search)) + list.add(name); + } + return list; } - return list; } - // No Search // Yes Filters - else if(search.isEmpty() && tagFilters.size() > 0){ + + //////////////////////// + //// WITH FILTERS + + // No Search + if(search.isEmpty()){ List list = new ArrayList(); for(String name : this.list){ if(tagMap.hasClone(name)){ - boolean hasAll = true; - for(String tagName : tagFilters){ - UUID tagUUID = tagNames.get(tagName); - if(tagUUID != null){ - if(!tagMap.hasTag(name, tagUUID)){ - hasAll = false; - break; - } - } - } - if(hasAll){ + if(meetsCondition(name)){ list.add(name); } } } return list; } - // Yes Search // Yes Filters + + // Yes Search List list = new ArrayList(); for(String name : this.list){ if(name.toLowerCase().contains(search)) { if(tagMap.hasClone(name)){ - boolean hasAll = true; - for(String tagName : tagFilters){ - UUID tagUUID = tagNames.get(tagName); - if(tagUUID != null){ - if(!tagMap.hasTag(name, tagUUID)){ - hasAll = false; - break; - } - } - } - if(hasAll){ + if(meetsCondition(name)){ list.add(name); } } @@ -246,6 +269,40 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { return list; } + private boolean meetsCondition(String name){ + if(tagMap == null){ + return true; + } + boolean conditionMet = true; + boolean allRequirement = filterCondition == 1 || filterCondition == 3; + + for(String tagName : tagFilters){ + UUID tagUUID = tagNames.get(tagName); + if(tagUUID != null) { + boolean hasTag = tagMap.hasTag(name, tagUUID); + if (!allRequirement) { + if (!hasTag && filterCondition == 0) { + conditionMet = false; + break; + } else if (hasTag && filterCondition == 2) { + conditionMet = false; + break; + } + } else { + if (!hasTag && filterCondition == 1) { + conditionMet = false; + break; + } else if (hasTag && filterCondition == 3) { + conditionMet = false; + break; + } + } + } + } + + return conditionMet; + } + private List getTagList(){ if(this.tagList == null){ this.tagList = new ArrayList(); @@ -359,6 +416,18 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { GuiNpcButton button = (GuiNpcButton) guibutton; displayTags = (byte) button.getValue(); } + if (id == 13) { + GuiNpcButton button = (GuiNpcButton) guibutton; + filterCondition = (byte) button.getValue(); + } + if (id == 14) { + GuiNpcButton button = (GuiNpcButton) guibutton; + ascending = (byte) button.getValue(); + } + if (id == 15) { + GuiNpcButton button = (GuiNpcButton) guibutton; + sortType = (byte) button.getValue(); + } if(id > 20){ activeTab = id - 20; initGui(); @@ -397,13 +466,22 @@ public class GuiNpcMobSpawner extends GuiNPCInterface implements IGuiData { } } else { - NBTTagList nbtlist = compound.getTagList("List", 8); List list = new ArrayList(); - for(int i = 0; i < nbtlist.tagCount(); i++){ - list.add(nbtlist.getStringTagAt(i)); + if(sortType == 1){ + NBTTagList nbtlist = compound.getTagList("ListDate", 8); + for(int i = 0; i < nbtlist.tagCount(); i++){ + list.add(nbtlist.getStringTagAt(i)); + } } + else { + NBTTagList nbtlist = compound.getTagList("List", 8); + for(int i = 0; i < nbtlist.tagCount(); i++){ + list.add(nbtlist.getStringTagAt(i)); + } + } + this.list = list; - scroll.setList(getSearchList(), ascending); + scroll.setList(getSearchList(), ascending == 0, sortType == 0); } } diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java index a3c7060d7..ad5cc9795 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java @@ -8,44 +8,48 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; import noppes.npcs.client.Client; -import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.controllers.ClientCloneController; -import noppes.npcs.client.gui.advanced.GuiNPCTagSetup; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumPacketServer; +import noppes.npcs.controllers.data.Tag; +import noppes.npcs.controllers.data.TagMap; import noppes.npcs.entity.EntityNPCInterface; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.UUID; +import java.util.*; -public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCallback, IGuiData, ISubGuiListener{ +public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCallback, IGuiData, ISubGuiListener { private Entity toClone; - private boolean isNPC; private NBTTagCompound compound; - public HashSet npcTags = new HashSet(); - - public static ArrayList allTags = new ArrayList<>(); private static boolean serverSide = false; private static int tab = 1; + public boolean isNPC = false; + + // Selected Tags to Add + public static HashSet addTags; + public static ArrayList allTags = new ArrayList<>(); + public static HashMap tagMap = new HashMap<>(); public GuiNpcMobSpawnerAdd(NBTTagCompound compound){ this.toClone = EntityList.createEntityFromNBT(compound, Minecraft.getMinecraft().theWorld); this.compound = compound; - - // Get Tag UUIDs - this.getTagUUIDs(); - if(isNPC){ - Client.sendData(EnumPacketServer.TagsGet); + if(toClone instanceof EntityNPCInterface){ + isNPC = true; } setBackground("menubg.png"); xSize = 256; ySize = 216; closeOnEsc = true; + + if(addTags == null){ + addTags = new HashSet<>(); + } + if(isNPC){ + Client.sendData(EnumPacketServer.CloneAllTagsShort); + } } @Override @@ -68,18 +72,8 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall if(isNPC){ addButton(new GuiNpcButton(4, guiLeft + 4, guiTop + 120, 99, 20, "cloner.wandTags")); addButton(new GuiNpcButton(5, guiLeft + 106, guiTop + 120, 99, 20, "cloner.npcTags")); - } - } - - public void getTagUUIDs(){ - // Is an NPC - if(compound.hasKey("ModRev")){ - this.isNPC = true; - if(compound.hasKey("TagUUIDs")){ - NBTTagList nbtTagList = compound.getTagList("TagUUIDs",8); - for (int i = 0; i < nbtTagList.tagCount(); i++) { - npcTags.add(UUID.fromString(nbtTagList.getStringTagAt(i))); - } + if(addTags.size() > 0){ + addLabel(new GuiNpcLabel(6, "cloner.wandtagsapplied", guiLeft + 10, guiTop + 160)); } } } @@ -109,8 +103,15 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall if(id == 3){ serverSide = ((GuiNpcButton)guibutton).getValue() == 1; } + if (id == 4) { + if(isNPC){ + this.setSubGui(new SubGuiClonerQuickTags(this)); + } + } if (id == 5) { - this.setSubGui(new SubGuiClonerNPCTags((EntityNPCInterface) toClone)); + if(isNPC){ + this.setSubGui(new SubGuiClonerNPCTags((EntityNPCInterface) toClone)); + } } } @@ -119,10 +120,17 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall public void confirmClicked(boolean confirm, int id){ if(confirm){ String name = getTextField(0).getText(); - if(!serverSide) - ClientCloneController.Instance.addClone(compound, name, tab); - else - Client.sendData(EnumPacketServer.CloneSave, name, tab); + NBTTagCompound extraTags = new NBTTagCompound(); + if(isNPC && addTags.size() > 0){ + extraTags = setTempTags(); + } + if(!serverSide){ + ClientCloneController.Instance.addClone(compound, name, tab, extraTags); + } + else{ + Client.sendData(EnumPacketServer.CloneSave, name, tab, extraTags); + } + close(); } else @@ -135,7 +143,6 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall } - @Override public void setGuiData(NBTTagCompound compound) { if(compound.hasKey("NameExists")){ @@ -144,21 +151,44 @@ public class GuiNpcMobSpawnerAdd extends GuiNPCInterface implements GuiYesNoCall else confirmClicked(true, 0); } - if(compound.hasKey("TagNames")){ - NBTTagList tagList = compound.getTagList("TagNames",8); + else if (compound.hasKey("ShortTags")) { + NBTTagList validTags = compound.getTagList("ShortTags", 10); + tagMap.clear(); allTags.clear(); - for (int i = 0; i < tagList.tagCount(); i++) { - allTags.add(tagList.getStringTagAt(i)); + if(validTags != null){ + for(int j = 0; j < validTags.tagCount(); j++) + { + NBTTagCompound tagStructure = validTags.getCompoundTagAt(j); + Tag tag = new Tag(); + tag.readShortNBT(tagStructure); + tagMap.put(tag.name, tag.uuid); + } + allTags.addAll(tagMap.keySet()); + allTags.sort(String.CASE_INSENSITIVE_ORDER); } + initGui(); } } @Override public void subGuiClosed(SubGuiInterface subgui) { - if (subgui instanceof SubGuiNpcQuickTags) { - SubGuiNpcQuickTags filterGui = (SubGuiNpcQuickTags) subgui; - // filter = filterGui.filterScroll.getSelectedList(); - } initGui(); } + + public NBTTagCompound setTempTags(){ + NBTTagCompound nbtTagCompound = new NBTTagCompound(); + NBTTagList nbtTagList = new NBTTagList(); + for (String name : addTags) { + if(tagMap.containsKey(name)){ + nbtTagList.appendTag(new NBTTagString(tagMap.get(name).toString())); + } + else { + addTags.remove(name); + } + } + nbtTagCompound.setTag("TempTagUUIDs", nbtTagList); + + return nbtTagCompound; + } + } diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java b/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java index 72006bd71..3a7b608dd 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java @@ -12,54 +12,62 @@ import noppes.npcs.entity.EntityNPCInterface; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Vector; -public class SubGuiClonerNPCTags extends SubGuiInterface implements IGuiData,IScrollData,ICustomScrollListener { - private final EntityNPCInterface npc; +public class SubGuiClonerNPCTags extends SubGuiInterface implements IGuiData,IScrollData { private GuiCustomScroll scrollTags; private GuiCustomScroll npcTags; - private HashMap data = new HashMap<>(); + private final ArrayList allTags = new ArrayList<>(); private final ArrayList tagNames = new ArrayList<>(); + private String search = ""; + private final EntityNPCInterface npc; public SubGuiClonerNPCTags(EntityNPCInterface npc) { - this.npc = npc; Client.sendData(EnumPacketServer.TagsGet); Client.sendData(EnumPacketServer.NpcTagsGet); setBackground("menubg.png"); xSize = 305; ySize = 220; - closeOnEsc = true; + closeOnEsc = false; + this.npc = npc; } public void initGui() { super.initGui(); - addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("tags.allTags"), guiLeft + 5, guiTop + 11)); + addLabel(new GuiNpcLabel(5, npc.display.name + " " + StatCollector.translateToLocal("tags.tags"), guiLeft + 10, guiTop + 8)); + + addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("tags.allTags"), guiLeft + 10, guiTop + 22)); if(scrollTags == null){ scrollTags = new GuiCustomScroll(this,0); - scrollTags.setSize(100, 180); + scrollTags.setSize(110, 145); } - scrollTags.guiLeft = guiLeft + 5; - scrollTags.guiTop = guiTop + 24; + scrollTags.guiLeft = guiLeft + 10; + scrollTags.guiTop = guiTop + 34; this.addScroll(scrollTags); + addTextField(new GuiNpcTextField(4, this, fontRendererObj, guiLeft + 10, guiTop + 24 + 160, 110, 20, search)); - addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("tags.selectedTags"), guiLeft + 190, guiTop + 11)); + addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("tags.selectedTags"), guiLeft + 185, guiTop + 22)); if(npcTags == null){ npcTags = new GuiCustomScroll(this,1); - npcTags.setSize(100, 180); + npcTags.setSize(110, 170); } - npcTags.guiLeft = guiLeft + 190; - npcTags.guiTop = guiTop + 24; + npcTags.guiLeft = guiLeft + 185; + npcTags.guiTop = guiTop + 34; npcTags.setList(tagNames); this.addScroll(npcTags); - addButton(new GuiNpcButton(10, guiLeft + 120, guiTop + 90, 55, 20, ">")); - addButton(new GuiNpcButton(11, guiLeft + 120, guiTop + 112, 55, 20, "<")); + addButton(new GuiNpcButton(66, guiLeft + 125, guiTop + 34, 55, 20, "gui.save")); + + addButton(new GuiNpcButton(10, guiLeft + 125, guiTop + 90, 55, 20, ">")); + addButton(new GuiNpcButton(11, guiLeft + 125, guiTop + 112, 55, 20, "<")); + + addButton(new GuiNpcButton(12, guiLeft + 125, guiTop + 140, 55, 20, ">>")); + addButton(new GuiNpcButton(13, guiLeft + 125, guiTop + 162, 55, 20, "<<")); - addButton(new GuiNpcButton(12, guiLeft + 120, guiTop + 140, 55, 20, ">>")); - addButton(new GuiNpcButton(13, guiLeft + 120, guiTop + 162, 55, 20, "<<")); } @Override @@ -69,7 +77,7 @@ public class SubGuiClonerNPCTags extends SubGuiInterface implements IGuiData,ISc } if (guibutton.id == 12) { tagNames.clear(); - tagNames.addAll(data.keySet()); + tagNames.addAll(allTags); } if (guibutton.id == 11 && npcTags.hasSelected()) { tagNames.remove(npcTags.getSelected()); @@ -77,14 +85,18 @@ public class SubGuiClonerNPCTags extends SubGuiInterface implements IGuiData,ISc if (guibutton.id == 13) { tagNames.clear(); } + if (guibutton.id == 66) { + close(); + } initGui(); } @Override public void setData(Vector list, HashMap data) { - this.data = data; - scrollTags.setList(list); + allTags.addAll(data.keySet()); + allTags.sort(String.CASE_INSENSITIVE_ORDER); + scrollTags.setList(allTags); initGui(); } @@ -110,9 +122,6 @@ public class SubGuiClonerNPCTags extends SubGuiInterface implements IGuiData,ISc } @Override - public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) { - } - public void save() { NBTTagCompound tagCompound = new NBTTagCompound(); NBTTagList tagList = new NBTTagList(); @@ -122,4 +131,34 @@ public class SubGuiClonerNPCTags extends SubGuiInterface implements IGuiData,ISc tagCompound.setTag("TagNames",tagList); Client.sendData(EnumPacketServer.TagSet, tagCompound); } + + public void keyTyped(char c, int i) + { + super.keyTyped(c, i); + if(getTextField(4) != null){ + if(search.equals(getTextField(4).getText())) + return; + search = getTextField(4).getText().toLowerCase(); + scrollTags.setList(getSearchList()); + } + } + + private List getSearchList(){ + if(search.isEmpty()){ + return new ArrayList(allTags); + } + List list = new ArrayList(); + for(String name : this.allTags){ + if(name.toLowerCase().contains(search)) + list.add(name); + } + return list; + } + + @Override + public void close() { + save(); + super.close(); + } + } diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiClonerQuickTags.java b/src/main/java/noppes/npcs/client/gui/SubGuiClonerQuickTags.java new file mode 100644 index 000000000..fc9331318 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/SubGuiClonerQuickTags.java @@ -0,0 +1,101 @@ +package noppes.npcs.client.gui; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.StatCollector; +import noppes.npcs.client.Client; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.constants.EnumPacketServer; +import noppes.npcs.controllers.data.Tag; +import noppes.npcs.controllers.data.TagMap; + +import java.util.*; + +public class SubGuiClonerQuickTags extends SubGuiInterface implements IScrollData +{ + public GuiNpcMobSpawnerAdd parent; + public GuiCustomScroll quickScroll = new GuiCustomScroll(this,0); + private static String quickSearch = ""; + + public SubGuiClonerQuickTags(GuiNpcMobSpawnerAdd par){ + this.parent = par; + setBackground("menubg.png"); + xSize = 305; + ySize = 220; + closeOnEsc = true; + } + + public void initGui(){ + super.initGui(); + quickScroll.clear(); + quickScroll.setSize(140, 166); + quickScroll.guiLeft = guiLeft + 4; + quickScroll.guiTop = guiTop + 19; + quickScroll.multipleSelection = true; + quickScroll.setSelectedList(GuiNpcMobSpawnerAdd.addTags); + this.addScroll(quickScroll); + + addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("cloner.wandtags"), guiLeft + 7, guiTop + 7)); + addScroll(quickScroll); + addTextField(new GuiNpcTextField(2, this, fontRendererObj, guiLeft + 4, guiTop + 190, 140, 20, quickSearch)); + + addButton(new GuiNpcButton(10, guiLeft + 150, guiTop + 20, 120, 20, "gui.selectAll")); + addButton(new GuiNpcButton(11, guiLeft + 150, guiTop + 43, 120, 20, "gui.deselectAll")); + + addButton(new GuiNpcButton(66, guiLeft + 240, guiTop + 175, 60, 20, "gui.done")); + + getSelected(); + } + protected void actionPerformed(GuiButton guibutton){ + if (guibutton.id == 10) { + GuiNpcMobSpawnerAdd.addTags = new HashSet<>(parent.allTags); + quickScroll.setSelectedList(GuiNpcMobSpawnerAdd.addTags); + } + if (guibutton.id == 11) { + GuiNpcMobSpawnerAdd.addTags = new HashSet<>(); + quickScroll.setSelectedList(GuiNpcMobSpawnerAdd.addTags); + } + if (guibutton.id == 66) { + close(); + } + } + + public void getSelected(){ + quickScroll.setList(getQuickTags()); + } + + @Override + public void keyTyped(char c, int i) + { + super.keyTyped(c, i); + if(getTextField(2) != null){ + if(quickSearch.equals(getTextField(2).getText())) + return; + quickSearch = getTextField(2).getText().toLowerCase(); + quickScroll.setList(getQuickTags()); + } + } + + private List getQuickTags(){ + if(quickSearch.isEmpty()){ + return new ArrayList(parent.allTags); + } + List list = new ArrayList(); + for(String name : this.parent.allTags){ + if(name.toLowerCase().contains(quickSearch)) + list.add(name); + } + return list; + } + + @Override + public void setData(Vector list, HashMap data) { + + } + + @Override + public void setSelected(String selected) { + + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuickTags.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuickTags.java deleted file mode 100644 index 029b15835..000000000 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuickTags.java +++ /dev/null @@ -1,59 +0,0 @@ -package noppes.npcs.client.gui; - -import net.minecraft.client.gui.GuiButton; -import net.minecraft.util.StatCollector; -import noppes.npcs.client.gui.util.GuiCustomScroll; -import noppes.npcs.client.gui.util.GuiNpcButton; -import noppes.npcs.client.gui.util.GuiNpcLabel; -import noppes.npcs.client.gui.util.SubGuiInterface; - -import java.util.ArrayList; -import java.util.HashSet; - -public class SubGuiNpcQuickTags extends SubGuiInterface -{ - public GuiNpcMobSpawnerAdd parent; - ArrayList allTags = new ArrayList<>(); - HashSet filter; - public GuiCustomScroll filterScroll; - - public SubGuiNpcQuickTags(GuiNpcMobSpawnerAdd par){ - this.parent = par; - setBackground("menubg.png"); - xSize = 305; - ySize = 200; - closeOnEsc = true; - } - - public void initGui(){ - super.initGui(); - if(filterScroll == null){ - filterScroll = new GuiCustomScroll(this,0); - filterScroll.setSize(140, 180); - } - filterScroll.guiLeft = guiLeft + 4; - filterScroll.guiTop = guiTop + 14; - filterScroll.setList(this.allTags); - filterScroll.multipleSelection = true; - filterScroll.setSelectedList(this.filter); - this.addScroll(filterScroll); - addButton(new GuiNpcButton(10, guiLeft + 150, guiTop + 20, 120, 20, "gui.selectAll")); - addButton(new GuiNpcButton(11, guiLeft + 150, guiTop + 43, 120, 20, "gui.deselectAll")); - addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("tags.taglessEntries") + ":", guiLeft + 150, guiTop + 72)); - getButton(12).width = 60; - getButton(12).height = 20; - addButton(new GuiNpcButton(66, guiLeft + 240, guiTop + 175, 60, 20, "gui.done")); - } - protected void actionPerformed(GuiButton guibutton){ - if (guibutton.id == 10) { - HashSet hashSet = new HashSet<>(this.allTags); - filterScroll.setSelectedList(hashSet); - } - if (guibutton.id == 11) { - filterScroll.setSelectedList(new HashSet<>()); - } - if (guibutton.id == 66) { - close(); - } - } -} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCTagSetup.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCTagSetup.java index 47836488d..b29914159 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCTagSetup.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCTagSetup.java @@ -1,6 +1,7 @@ package noppes.npcs.client.gui.advanced; import net.minecraft.client.gui.GuiButton; +import net.minecraft.item.crafting.IRecipe; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; @@ -9,6 +10,7 @@ import noppes.npcs.client.Client; import noppes.npcs.client.gui.SubGuiNpcFactionOptions; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumPacketServer; +import noppes.npcs.controllers.RecipeController; import noppes.npcs.entity.EntityNPCInterface; import java.util.*; @@ -17,8 +19,9 @@ public class GuiNPCTagSetup extends GuiNPCInterface2 implements IScrollData,ICus { private GuiCustomScroll scrollTags; private GuiCustomScroll npcTags; - private HashMap data = new HashMap<>(); - private final ArrayList tagNames = new ArrayList<>(); + private final ArrayList allTags = new ArrayList<>(); + private ArrayList tagNames = new ArrayList<>(); + private String search = ""; public GuiNPCTagSetup(EntityNPCInterface npc) { @@ -31,30 +34,31 @@ public class GuiNPCTagSetup extends GuiNPCInterface2 implements IScrollData,ICus { super.initGui(); - addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("tags.allTags"), guiLeft + 54, guiTop + 11)); + addLabel(new GuiNpcLabel(1, StatCollector.translateToLocal("tags.allTags"), guiLeft + 22, guiTop + 11)); if(scrollTags == null){ scrollTags = new GuiCustomScroll(this,0); - scrollTags.setSize(120, 180); + scrollTags.setSize(150, 155); } - scrollTags.guiLeft = guiLeft + 50; + scrollTags.guiLeft = guiLeft + 20; scrollTags.guiTop = guiTop + 24; this.addScroll(scrollTags); + addTextField(new GuiNpcTextField(4, this, fontRendererObj, guiLeft + 20, guiTop + 24 + 160, 150, 20, search)); - addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("tags.selectedTags"), guiLeft + 254, guiTop + 11)); + addLabel(new GuiNpcLabel(2, StatCollector.translateToLocal("tags.selectedTags"), guiLeft + 252, guiTop + 11)); if(npcTags == null){ npcTags = new GuiCustomScroll(this,1); - npcTags.setSize(120, 180); + npcTags.setSize(150, 180); } npcTags.guiLeft = guiLeft + 250; npcTags.guiTop = guiTop + 24; npcTags.setList(tagNames); this.addScroll(npcTags); - addButton(new GuiNpcButton(10, guiLeft + 180, guiTop + 90, 55, 20, ">")); - addButton(new GuiNpcButton(11, guiLeft + 180, guiTop + 112, 55, 20, "<")); + addButton(new GuiNpcButton(10, guiLeft + 185, guiTop + 90, 55, 20, ">")); + addButton(new GuiNpcButton(11, guiLeft + 185, guiTop + 112, 55, 20, "<")); - addButton(new GuiNpcButton(12, guiLeft + 180, guiTop + 140, 55, 20, ">>")); - addButton(new GuiNpcButton(13, guiLeft + 180, guiTop + 162, 55, 20, "<<")); + addButton(new GuiNpcButton(12, guiLeft + 185, guiTop + 140, 55, 20, ">>")); + addButton(new GuiNpcButton(13, guiLeft + 185, guiTop + 162, 55, 20, "<<")); } @Override @@ -64,7 +68,7 @@ public class GuiNPCTagSetup extends GuiNPCInterface2 implements IScrollData,ICus } if (guibutton.id == 12) { tagNames.clear(); - tagNames.addAll(data.keySet()); + tagNames.addAll(allTags); } if (guibutton.id == 11 && npcTags.hasSelected()) { tagNames.remove(npcTags.getSelected()); @@ -78,8 +82,9 @@ public class GuiNPCTagSetup extends GuiNPCInterface2 implements IScrollData,ICus @Override public void setData(Vector list, HashMap data) { - this.data = data; - scrollTags.setList(list); + allTags.addAll(data.keySet()); + allTags.sort(String.CASE_INSENSITIVE_ORDER); + scrollTags.setList(allTags); initGui(); } @@ -117,4 +122,27 @@ public class GuiNPCTagSetup extends GuiNPCInterface2 implements IScrollData,ICus tagCompound.setTag("TagNames",tagList); Client.sendData(EnumPacketServer.TagSet, tagCompound); } + + public void keyTyped(char c, int i) + { + super.keyTyped(c, i); + if(getTextField(4) != null){ + if(search.equals(getTextField(4).getText())) + return; + search = getTextField(4).getText().toLowerCase(); + scrollTags.setList(getSearchList()); + } + } + + private List getSearchList(){ + if(search.isEmpty()){ + return new ArrayList(allTags); + } + List list = new ArrayList(); + for(String name : this.allTags){ + if(name.toLowerCase().contains(search)) + list.add(name); + } + return list; + } } diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiCustomScroll.java b/src/main/java/noppes/npcs/client/gui/util/GuiCustomScroll.java index 295db8a2d..cf61ca36c 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiCustomScroll.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiCustomScroll.java @@ -239,9 +239,11 @@ public class GuiCustomScroll extends GuiScreen setSize(xSize,ySize); } - public void setList(List list, boolean ascending){ + public void setList(List list, boolean ascending, boolean caseOrder){ isSorted = true; - Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + if(caseOrder){ + Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + } if(!ascending){ Collections.reverse(list); } diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiCustomScrollCloner.java b/src/main/java/noppes/npcs/client/gui/util/GuiCustomScrollCloner.java index 36e50a69f..cb6a00f8a 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiCustomScrollCloner.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiCustomScrollCloner.java @@ -59,7 +59,7 @@ public class GuiCustomScrollCloner extends GuiCustomScroll { int tagStartX = j + fontRendererObj.getStringWidth(displayString) + 5; if(GuiNpcMobSpawner.displayTags == 0 || GuiNpcMobSpawner.displayTags == 1){ if (this.parent.tagMap.hasClone(list.get(i))) { - for (UUID tagUUID : this.parent.tagMap.getUUIDs(list.get(i))){ + for (UUID tagUUID : this.parent.tagMap.getUUIDsList(list.get(i))){ Tag tag = this.parent.tags.get(tagUUID); if(tag != null){ if(GuiNpcMobSpawner.displayTags == 1 || !tag.getIsHidden()){ diff --git a/src/main/java/noppes/npcs/config/ConfigClient.java b/src/main/java/noppes/npcs/config/ConfigClient.java index 665abb982..675395d12 100644 --- a/src/main/java/noppes/npcs/config/ConfigClient.java +++ b/src/main/java/noppes/npcs/config/ConfigClient.java @@ -31,12 +31,6 @@ public class ConfigClient public static Property FontSizeProperty; public static int FontSize = 18; - public static Property EntityRendererMixinProperty; - public static boolean EntityRendererMixin = true; - - public static Property AnimationMixinProperty; - public static boolean AnimationMixin = true; - /** * Questing Properties **/ @@ -70,12 +64,6 @@ public class ConfigClient FontSizeProperty = config.get(VISUAL, "Font Size", 18, "Font size for custom fonts (doesn't work with minecrafts font)"); FontSize = FontSizeProperty.getInt(18); - EntityRendererMixinProperty = config.get(VISUAL, "Entity Render Mixin", true, "Enables Overlay Mixins for Conflicts relating to Optifine or other Skin Renderers. If crashes occur, please disable."); - EntityRendererMixin = EntityRendererMixinProperty.getBoolean(true); - - AnimationMixinProperty = config.get(VISUAL, "Animation Mixin", true, "Enables mixins for the ModelRenderer and RenderPlayer classes, allowing for additional animation functionality in the API. If crashes or visual errors occur, please disable."); - AnimationMixin = AnimationMixinProperty.getBoolean(true); - // Questing TrackingInfoAlignmentProperty = config.get(QUESTING, "Tracking Info Alignment", 3, "Client sided! Determines where tracking quest info shows up on the screen based on a number from 0 to 8. Default: 3"); TrackingInfoAlignment = TrackingInfoAlignmentProperty.getInt(3); @@ -100,9 +88,6 @@ public class ConfigClient FontSize = LegacyConfig.FontSize; FontSizeProperty.set(FontSize); - EntityRendererMixin = LegacyConfig.EntityRendererMixin; - EntityRendererMixinProperty.set(EntityRendererMixin); - TrackingInfoAlignment = LegacyConfig.TrackingInfoAlignment; TrackingInfoAlignmentProperty.set(TrackingInfoAlignment); diff --git a/src/main/java/noppes/npcs/config/ConfigMixin.java b/src/main/java/noppes/npcs/config/ConfigMixin.java new file mode 100644 index 000000000..08dd65063 --- /dev/null +++ b/src/main/java/noppes/npcs/config/ConfigMixin.java @@ -0,0 +1,54 @@ +package noppes.npcs.config; + +import cpw.mods.fml.common.FMLLog; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; +import noppes.npcs.CustomNpcs; +import noppes.npcs.config.legacy.LegacyConfig; +import org.apache.logging.log4j.Level; + +import java.io.File; + +public class ConfigMixin +{ + public static Configuration config; + + public final static String CLIENT = "CLIENT"; + public final static String GENERAL = "GENERAL"; + + /** + * General Properties + **/ + public static Property EntityRendererMixinProperty; + public static boolean EntityRendererMixin = true; + + public static Property AnimationMixinProperty; + public static boolean AnimationMixin = true; + + public static void init(File configFile) + { + config = new Configuration(configFile); + + try + { + config.load(); + + EntityRendererMixinProperty = config.get(CLIENT, "Entity Render Mixin", true, "Enables Overlay Mixins for Conflicts relating to Optifine or other Skin Renderers. If crashes occur, please disable."); + EntityRendererMixin = EntityRendererMixinProperty.getBoolean(true); + + AnimationMixinProperty = config.get(CLIENT, "Animation Mixin", true, "Enables mixins for the ModelRenderer and RenderPlayer classes, allowing for additional animation functionality in the API. If crashes or visual errors occur, please disable."); + AnimationMixin = AnimationMixinProperty.getBoolean(true); + + } + catch (Exception e) + { + FMLLog.log(Level.ERROR, e, "CNPC+ has had a problem loading its mixin configuration"); + } + finally + { + if (config.hasChanged()) { + config.save(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/noppes/npcs/constants/EnumPacketServer.java b/src/main/java/noppes/npcs/constants/EnumPacketServer.java index fdde8cf0c..036ee6b14 100644 --- a/src/main/java/noppes/npcs/constants/EnumPacketServer.java +++ b/src/main/java/noppes/npcs/constants/EnumPacketServer.java @@ -33,7 +33,7 @@ public enum EnumPacketServer { RoleCompanionUpdate(CustomNpcsPermissions.NPC_ADVANCED, true), LinkedSet(CustomNpcsPermissions.NPC_ADVANCED, true), - ClonePreSave(CustomNpcsPermissions.NPC_CLONE), CloneSave(CustomNpcsPermissions.NPC_CLONE), CloneRemove(CustomNpcsPermissions.NPC_CLONE), CloneList, CloneTagList, CloneAllTags, + ClonePreSave(CustomNpcsPermissions.NPC_CLONE), CloneSave(CustomNpcsPermissions.NPC_CLONE), CloneRemove(CustomNpcsPermissions.NPC_CLONE), CloneList, CloneTagList, CloneAllTags, CloneAllTagsShort, ScriptGlobalGuiDataSave(CustomNpcsPermissions.TOOL_SCRIPTER, false), ScriptGlobalGuiDataGet(false), diff --git a/src/main/java/noppes/npcs/controllers/ServerCloneController.java b/src/main/java/noppes/npcs/controllers/ServerCloneController.java index 6aa99088f..d9b754e62 100644 --- a/src/main/java/noppes/npcs/controllers/ServerCloneController.java +++ b/src/main/java/noppes/npcs/controllers/ServerCloneController.java @@ -6,6 +6,7 @@ import net.minecraft.entity.EntityList; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; import net.minecraft.util.ChatComponentText; import noppes.npcs.CustomNpcs; import noppes.npcs.LogWriter; @@ -121,13 +122,12 @@ public class ServerCloneController implements ICloneHandler { File file = new File(dir, filename + "_new"); File file2 = new File(dir, filename); - NBTJsonUtil.SaveFile(file, compound); + addToTagMap(compound, name, tab); if(file2.exists()){ file2.delete(); } file.renameTo(file2); - addToTagMap(compound, name, tab); } catch (Exception e) { LogWriter.except(e); } @@ -144,6 +144,27 @@ public class ServerCloneController implements ICloneHandler { return list; } + public List getClonesDate(int tab){ + List list = new ArrayList(); + File dir = new File(getDir(), tab + ""); + if(!dir.exists() || !dir.isDirectory()) + return list; + File[] files = dir.listFiles(); + Arrays.sort(files, new Comparator(){ + public int compare(File f1, File f2) + { + return Long.compare(f1.lastModified(), f2.lastModified()); + } + }); + + for(File file : files){ + String fileName = file.getName(); + if(fileName.endsWith(".json")) + list.add(fileName.substring(0, fileName.length() - 5)); + } + return list; + } + public boolean removeClone(String name, int tab){ File file = new File(new File(getDir(), tab + ""), name + ".json"); if(!file.exists()) @@ -159,6 +180,43 @@ public class ServerCloneController implements ICloneHandler { return name; } + public String addClone(NBTTagCompound nbttagcompound, String name, int tab, NBTTagCompound tempTags) { + cleanTagList(nbttagcompound, tempTags); + cleanTags(nbttagcompound); + saveClone(tab, name, nbttagcompound); + return name; + } + + public NBTTagCompound cleanTagList(NBTTagCompound nbttagcompound, NBTTagCompound tempTags){ + HashSet tagUUIDs = new HashSet(); + if(nbttagcompound.hasKey("TagUUIDs")){ + NBTTagList nbtTagList = nbttagcompound.getTagList("TagUUIDs",8); + for (int i = 0; i < nbtTagList.tagCount(); i++) { + tagUUIDs.add(UUID.fromString(nbtTagList.getStringTagAt(i))); + } + + nbttagcompound.removeTag("TagUUIDs"); + } + if(tempTags.hasKey("TempTagUUIDs")){ + NBTTagList nbtTagList = tempTags.getTagList("TempTagUUIDs",8); + for (int i = 0; i < nbtTagList.tagCount(); i++) { + tagUUIDs.add(UUID.fromString(nbtTagList.getStringTagAt(i))); + } + + tempTags.removeTag("TempTagUUIDs"); + } + + if(tagUUIDs.size() > 0){ + NBTTagList nbtTagList = new NBTTagList(); + for (UUID uuid : tagUUIDs) { + nbtTagList.appendTag(new NBTTagString(uuid.toString())); + } + nbttagcompound.setTag("TagUUIDs", nbtTagList); + } + + return nbttagcompound; + } + public boolean addToTagMap(NBTTagCompound nbttagcompound, String name, int tab){ HashSet tagUUIDs = new HashSet(); if(nbttagcompound.hasKey("TagUUIDs")){ diff --git a/src/main/java/noppes/npcs/controllers/data/DataTransform.java b/src/main/java/noppes/npcs/controllers/data/DataTransform.java index e7990ec85..ad5402165 100644 --- a/src/main/java/noppes/npcs/controllers/data/DataTransform.java +++ b/src/main/java/noppes/npcs/controllers/data/DataTransform.java @@ -232,8 +232,8 @@ public class DataTransform { inv = compound; } npc.updateHitbox(); - this.isActive = isActive; - npc.updateAI= true; + npc.updateAI = true; + this.isActive = isActive; npc.updateClient = true; } } diff --git a/src/main/java/noppes/npcs/controllers/data/Tag.java b/src/main/java/noppes/npcs/controllers/data/Tag.java index 6484142c6..4116e719e 100644 --- a/src/main/java/noppes/npcs/controllers/data/Tag.java +++ b/src/main/java/noppes/npcs/controllers/data/Tag.java @@ -40,6 +40,14 @@ public class Tag implements ITag { compound.setString("Uuid", uuid.toString()); compound.setBoolean("HideTag", hideTag); } + public void readShortNBT(NBTTagCompound compound){ + name = compound.getString("Name"); + uuid = UUID.fromString(compound.getString("Uuid")); + } + public void writeShortNBT(NBTTagCompound compound){ + compound.setString("Name", name); + compound.setString("Uuid", uuid.toString()); + } public int getId() { return this.id; diff --git a/src/main/java/noppes/npcs/controllers/data/TagMap.java b/src/main/java/noppes/npcs/controllers/data/TagMap.java index 4a14706c9..023a0c9d9 100644 --- a/src/main/java/noppes/npcs/controllers/data/TagMap.java +++ b/src/main/java/noppes/npcs/controllers/data/TagMap.java @@ -72,6 +72,17 @@ public class TagMap { return null; } + public List getUUIDsList(String cloneName) { + HashSet uuids = getUUIDs(cloneName); + if(uuids != null){ + List tagUUIDS = new ArrayList<>(uuids); + Collections.sort(tagUUIDS); + return tagUUIDS; + } + + return null; + } + public boolean removeClone(String cloneName) { return tagMap.remove(cloneName) != null; } diff --git a/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java b/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java index afd2c963a..b00fd404d 100644 --- a/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java +++ b/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java @@ -1,10 +1,14 @@ package noppes.npcs.mixin; +import cpw.mods.fml.relauncher.FMLLaunchHandler; import noppes.npcs.config.ConfigClient; +import noppes.npcs.config.ConfigMixin; import org.spongepowered.asm.lib.tree.ClassNode; +import org.spongepowered.asm.mixin.MixinEnvironment; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -32,13 +36,23 @@ public class CustomNPCsMixinPlugin implements IMixinConfigPlugin { @Override public List getMixins() { + + // Load Mixin Config + String configPath = "config" + File.separator + "CustomNpcPlus" + File.separator; + ConfigMixin.init(new File(configPath + "mixin.cfg")); + boolean client = FMLLaunchHandler.side().isClient(); + List mixins = new ArrayList<>(); - if (ConfigClient.EntityRendererMixin){ - mixins.add("MixinEntityRenderer"); - } - if (ConfigClient.AnimationMixin) { - mixins.add("MixinModelRenderer"); - mixins.add("MixinRenderPlayer"); + + // Client Only Mixins + if(client){ + if (ConfigMixin.EntityRendererMixin){ + mixins.add("MixinEntityRenderer"); + } + if (ConfigMixin.AnimationMixin) { + mixins.add("MixinModelRenderer"); + mixins.add("MixinRenderPlayer"); + } } return mixins; } diff --git a/src/main/resources/assets/customnpcs/lang/de_DE.lang b/src/main/resources/assets/customnpcs/lang/de_DE.lang index aaf2fcc55..72d987994 100644 --- a/src/main/resources/assets/customnpcs/lang/de_DE.lang +++ b/src/main/resources/assets/customnpcs/lang/de_DE.lang @@ -100,7 +100,7 @@ gui.select=Wähle gui.range=Entfernung gui.name=Name gui.partly=Geist -gui.copy=Kopie +gui.copy=Kopieren gui.clear=Löschen gui.done=Fertig gui.paste=Einfügen @@ -125,7 +125,7 @@ spawner.mobspawner=Spawner spawner.mount=Geritten von... spawner.mountplayer=Geritten von selbst -spawner.diesafter=Stirbt, nachdem Laiche sterben +spawner.diesafter=Stirbt, nachdem Leichen sterben spawner.posoffset=Position Offset spawner.type=Spawn Typ spawner.all=Alle @@ -196,7 +196,7 @@ availability.areaNotAvailble=Sie können auf diese Weise nicht weitergehen availability.permission=Du hast keine Rechte um dies zu tun availability.editIcon=Für die nächsten 10 Sekunden können Sie ein beliebiges Item, mit der rechten Maustaste einfügen -spawning.availableBiomes=Erhätliche Biome +spawning.availableBiomes=Verfügbare Biome spawning.spawningBiomes=Spawning Biome spawning.biomes=Biome spawning.weightedChance=Chance @@ -207,7 +207,7 @@ role.trader=Händler role.follower=Verfolger role.bank=Bank role.transporter=Transporter -role.mailman=Mailman +role.mailman=Postbote role.marketname=Verlinkter Händler Name role.companion=Begleiter @@ -342,7 +342,7 @@ menu.advanced=Erweitert menu.global=Global menu.role=Rolle -global.banks=Banks +global.banks=Banken global.transport=Transport global.playerdata=PlayerData global.recipes=Rezepte @@ -362,7 +362,7 @@ follower.daysleft=verbleibende Tage follower.lastday=Letzter Tag follower.day=Tag follower.days=Tage -follower.hireText=Danke, das du mich angeheuert hast.Ich folge dir für +follower.hireText=Danke, das du mich angeheuert hast. Ich folge dir für follower.farewellText=Meine Tage mit dir sind vorrüber. Machs gut! follower.infiniteDays=Unendlich Tage follower.guiDisabled=Gui deaktivieren @@ -373,14 +373,14 @@ transporter.discovered=Verfügbar, wenn entdeckt transporter.start=Von Anfang an verfügbar transporter.interaction=Erhältlich nach Wechselwirkung -conversation.delay=Delay +conversation.delay=Verzögerung conversation.line=Text bard.jukebox=Play an Jukebox bard.background=Play in Hintergrund -bard.ondistance=On Distance -bard.offdistance=Off Distance -bard.hasoff=Has Off Distance +bard.ondistance=On Distanz +bard.offdistance=Off Distanz +bard.hasoff=Hat Off Distanz dialog.dialog=Dialog dialog.dialogs=Dialogs @@ -392,7 +392,7 @@ dialog.selectoption=Wähle Optionen dialog.quitoption=Optionen verlassen dialog.option=Dialog Optionen dialog.roleoption=Rolle Optionen -dialog.commandoption=Kommand Optionen +dialog.commandoption=Kommando Optionen dialog.commandoptionplayer=Benutze "@dp" für den Namen der mit den NPC spricht dialog.hideNPC=Verstecke NPC dialog.showWheel=Zeige Dialog Rad @@ -401,7 +401,7 @@ quest.quest=Quest quest.quests=Quests quest.item=Item quest.kill=Tötungs Quest -quest.areakill=Area Tötungs Quest +quest.areakill=Bereich Tötungs Quest quest.dialog=Dialog quest.location=Location quest.completedtext=Abgeschlossener Text @@ -412,7 +412,7 @@ quest.repeatable=Wiederholbar quest.mcdaily=MC Täglich quest.mcweekly=MC Wöchentlich quest.rldaily=RL Täglich -quest.rlweekly=RL Täglich +quest.rlweekly=RL Wöchentlich quest.instant=Sofort Abgeschlossen quest.npc=Abgeschlossen bei npc quest.next=Nächste Quest @@ -868,4 +868,4 @@ companion.fullgrown=Voll gewachsen companion.age=Alter companion.stage=Bühne -#German by DewTix \ No newline at end of file +#German by DewTix diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index 5bdae4e21..4e3e8a6ff 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -129,6 +129,11 @@ gui.selectAll=Select All gui.deselectAll=Deselect All scale.shared=Shared +filter.contains=Contains +filter.any=Any +filter.all=All +filter.notany=Not Any +filter.notall=Not All remote.title=Nearby NPCs remote.reset=Reset @@ -401,11 +406,22 @@ menu.role=Role menu.animations=Animations menu.tags=Tags +cloner.tagFilters=Tag Filters +cloner.tagVisibility=Tag Visibility cloner.wandTags=Wand Tags cloner.npcTags=NPC Tags +cloner.order=Sort Order +cloner.ascending=Ascending +cloner.descending=Descending +cloner.type=Sort Type +cloner.name=Name +cloner.date=Date +cloner.wandtags=Wand Tags +cloner.wandtagsapplied=Wand Tags will be applied tags.allTags=All Tags tags.selectedTags=Selected Tags +tags.tags=Tags global.banks=Banks global.transport=Transport