diff --git a/build.gradle b/build.gradle index c13a3e25d..30013f9b8 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { id 'idea' } -version = "1.9.4-beta2.9" +version = "1.10-beta1" group= "kamkeel.customnpc-plus" archivesBaseName = "CustomNPC-Plus" diff --git a/src/api b/src/api index 0d9abd56f..dd3d8c552 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 0d9abd56f6f1ab8bdc7d5ce844a668df86f20bf3 +Subproject commit dd3d8c552c515b48901f4c8d443b8c7cb85c0a20 diff --git a/src/main/java/kamkeel/npcs/addon/client/DBCClient.java b/src/main/java/kamkeel/npcs/addon/client/DBCClient.java index 5fdc75d7e..9f839936b 100644 --- a/src/main/java/kamkeel/npcs/addon/client/DBCClient.java +++ b/src/main/java/kamkeel/npcs/addon/client/DBCClient.java @@ -2,7 +2,6 @@ package kamkeel.npcs.addon.client; import net.minecraft.entity.EntityLivingBase; import noppes.npcs.client.gui.mainmenu.GuiNpcStats; -import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory; import noppes.npcs.client.gui.util.GuiNPCInterface2; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.entity.EntityNPCInterface; @@ -34,7 +33,4 @@ public class DBCClient { public GuiNPCInterface2 manageCustomForms(EntityNPCInterface npcInterface){ return null; } // Manage Custom Forms public GuiNPCInterface2 manageCustomAuras(EntityNPCInterface npcInterface){ return null; } - - // Inventory GUI - public GuiCNPCInventory inventoryGUI(){ return null; } } diff --git a/src/main/java/kamkeel/npcs/command/AnimationCommand.java b/src/main/java/kamkeel/npcs/command/AnimationCommand.java index 05e5e517f..e8388e802 100644 --- a/src/main/java/kamkeel/npcs/command/AnimationCommand.java +++ b/src/main/java/kamkeel/npcs/command/AnimationCommand.java @@ -9,6 +9,9 @@ import noppes.npcs.controllers.data.PlayerData; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class AnimationCommand extends CommandKamkeelBase { @Override diff --git a/src/main/java/kamkeel/npcs/command/CloneCommand.java b/src/main/java/kamkeel/npcs/command/CloneCommand.java index b62308d30..3ce2f02b8 100644 --- a/src/main/java/kamkeel/npcs/command/CloneCommand.java +++ b/src/main/java/kamkeel/npcs/command/CloneCommand.java @@ -17,6 +17,8 @@ import noppes.npcs.entity.EntityNPCInterface; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.*; + public class CloneCommand extends CommandKamkeelBase { @Override diff --git a/src/main/java/kamkeel/npcs/command/CommandCommand.java b/src/main/java/kamkeel/npcs/command/CommandCommand.java index facac35f1..edc20b84d 100644 --- a/src/main/java/kamkeel/npcs/command/CommandCommand.java +++ b/src/main/java/kamkeel/npcs/command/CommandCommand.java @@ -10,6 +10,9 @@ import noppes.npcs.api.IWorld; import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.event.CustomNPCsEvent; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendMessage; + public class CommandCommand extends CommandKamkeelBase { @Override diff --git a/src/main/java/kamkeel/npcs/command/CommandKamkeel.java b/src/main/java/kamkeel/npcs/command/CommandKamkeel.java index 85adfce4c..59920807e 100644 --- a/src/main/java/kamkeel/npcs/command/CommandKamkeel.java +++ b/src/main/java/kamkeel/npcs/command/CommandKamkeel.java @@ -47,7 +47,7 @@ public class CommandKamkeel extends CommandBase{ @Override public String getCommandName() { - return "kamkeel/npcs"; + return "kamkeel"; } @Override diff --git a/src/main/java/kamkeel/npcs/command/CommandKamkeelBase.java b/src/main/java/kamkeel/npcs/command/CommandKamkeelBase.java index cf87c5d36..cc874f392 100644 --- a/src/main/java/kamkeel/npcs/command/CommandKamkeelBase.java +++ b/src/main/java/kamkeel/npcs/command/CommandKamkeelBase.java @@ -4,7 +4,6 @@ import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.ChatComponentTranslation; import noppes.npcs.CustomNpcsPermissions; import java.lang.annotation.ElementType; @@ -55,18 +54,6 @@ public abstract class CommandKamkeelBase extends CommandBase{ return !subcommands.isEmpty(); } - protected static void sendMessage(ICommandSender sender, String message, Object... obs) { - sender.addChatMessage(new ChatComponentTranslation(message, obs)); - } - - protected static void sendResult(ICommandSender sender, String message, Object... obs) { - sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A77 " + message, obs)); - } - - protected static void sendError(ICommandSender sender, String message, Object... obs) { - sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A74 Error:\u00A7c " + message, obs)); - } - @Retention(value = RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SubCommand { diff --git a/src/main/java/kamkeel/npcs/command/ConfigCommand.java b/src/main/java/kamkeel/npcs/command/ConfigCommand.java index f31a1dc18..b432df26e 100644 --- a/src/main/java/kamkeel/npcs/command/ConfigCommand.java +++ b/src/main/java/kamkeel/npcs/command/ConfigCommand.java @@ -20,6 +20,9 @@ import noppes.npcs.controllers.PlayerDataController; import java.util.Arrays; import java.util.Set; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class ConfigCommand extends CommandKamkeelBase { diff --git a/src/main/java/kamkeel/npcs/command/DialogCategoryCommand.java b/src/main/java/kamkeel/npcs/command/DialogCategoryCommand.java index d149a15b7..cf1424386 100644 --- a/src/main/java/kamkeel/npcs/command/DialogCategoryCommand.java +++ b/src/main/java/kamkeel/npcs/command/DialogCategoryCommand.java @@ -11,6 +11,9 @@ import noppes.npcs.controllers.data.PlayerData; import java.util.Collection; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class DialogCategoryCommand extends CommandKamkeelBase { @Override diff --git a/src/main/java/kamkeel/npcs/command/DialogCommand.java b/src/main/java/kamkeel/npcs/command/DialogCommand.java index 4ad1e7e22..d3953bad3 100644 --- a/src/main/java/kamkeel/npcs/command/DialogCommand.java +++ b/src/main/java/kamkeel/npcs/command/DialogCommand.java @@ -20,6 +20,9 @@ import noppes.npcs.entity.EntityDialogNpc; import java.util.Collection; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class DialogCommand extends CommandKamkeelBase { @Override diff --git a/src/main/java/kamkeel/npcs/command/EffectCommand.java b/src/main/java/kamkeel/npcs/command/EffectCommand.java index b82f1a5c0..054795c44 100644 --- a/src/main/java/kamkeel/npcs/command/EffectCommand.java +++ b/src/main/java/kamkeel/npcs/command/EffectCommand.java @@ -2,8 +2,8 @@ package kamkeel.npcs.command; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.CustomEffectController; +import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.data.CustomEffect; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.scripted.event.PlayerEvent.EffectEvent.ExpirationType; @@ -13,6 +13,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class EffectCommand extends CommandKamkeelBase { @Override @@ -26,7 +29,7 @@ public class EffectCommand extends CommandKamkeelBase { } @SubCommand(desc = "Lists all Effects") - public void infoAll(ICommandSender sender, String[] args) throws CommandException { + public void list(ICommandSender sender, String[] args) throws CommandException { CustomEffectController controller = CustomEffectController.getInstance(); if (controller.indexMapper.isEmpty()) { sendError(sender, "No effects found."); diff --git a/src/main/java/kamkeel/npcs/command/FactionCommand.java b/src/main/java/kamkeel/npcs/command/FactionCommand.java index f5de2f3b5..32bea0d2d 100644 --- a/src/main/java/kamkeel/npcs/command/FactionCommand.java +++ b/src/main/java/kamkeel/npcs/command/FactionCommand.java @@ -11,6 +11,9 @@ import noppes.npcs.controllers.data.PlayerFactionData; import java.util.Arrays; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class FactionCommand extends CommandKamkeelBase { public Faction selectedFaction; diff --git a/src/main/java/kamkeel/npcs/command/HelpCommand.java b/src/main/java/kamkeel/npcs/command/HelpCommand.java index f5e0828da..18423a975 100644 --- a/src/main/java/kamkeel/npcs/command/HelpCommand.java +++ b/src/main/java/kamkeel/npcs/command/HelpCommand.java @@ -7,6 +7,9 @@ import net.minecraft.util.ChatComponentTranslation; import java.lang.reflect.Method; import java.util.Map.Entry; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendMessage; + public class HelpCommand extends CommandKamkeelBase{ private CommandKamkeel parent; diff --git a/src/main/java/kamkeel/npcs/command/NpcCommand.java b/src/main/java/kamkeel/npcs/command/NpcCommand.java index fe775928c..4e5745906 100644 --- a/src/main/java/kamkeel/npcs/command/NpcCommand.java +++ b/src/main/java/kamkeel/npcs/command/NpcCommand.java @@ -22,6 +22,9 @@ import org.apache.commons.lang3.ArrayUtils; import java.util.Arrays; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class NpcCommand extends CommandKamkeelBase { public EntityNPCInterface selectedNpc; diff --git a/src/main/java/kamkeel/npcs/command/OverlayCommand.java b/src/main/java/kamkeel/npcs/command/OverlayCommand.java index e740bc5e0..95e098f7c 100644 --- a/src/main/java/kamkeel/npcs/command/OverlayCommand.java +++ b/src/main/java/kamkeel/npcs/command/OverlayCommand.java @@ -9,6 +9,9 @@ import noppes.npcs.controllers.data.SkinOverlay; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class OverlayCommand extends CommandKamkeelBase { @Override diff --git a/src/main/java/kamkeel/npcs/command/QuestCategoryCommand.java b/src/main/java/kamkeel/npcs/command/QuestCategoryCommand.java index 9e3e238fd..eb673da35 100644 --- a/src/main/java/kamkeel/npcs/command/QuestCategoryCommand.java +++ b/src/main/java/kamkeel/npcs/command/QuestCategoryCommand.java @@ -1,12 +1,16 @@ package kamkeel.npcs.command; +import kamkeel.npcs.controllers.ProfileController; import kamkeel.npcs.network.packets.data.AchievementPacket; import kamkeel.npcs.network.packets.data.ChatAlertPacket; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.config.ConfigMain; +import noppes.npcs.constants.EnumProfileSync; import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.controllers.PlayerDataController; +import noppes.npcs.controllers.PlayerQuestController; import noppes.npcs.controllers.QuestController; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.controllers.data.Quest; @@ -16,6 +20,9 @@ import noppes.npcs.controllers.data.QuestData; import java.util.Collection; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class QuestCategoryCommand extends CommandKamkeelBase { @Override @@ -82,15 +89,20 @@ public class QuestCategoryCommand extends CommandKamkeelBase { int count = 0; for(PlayerData playerdata : data){ + count = 0; for(Quest quest : questCategory.quests.values()){ - if(playerdata.questData.activeQuests.containsKey(quest.id)){ - playerdata.questData.activeQuests.remove(quest.id); + playerdata.questData.activeQuests.remove(quest.id); + long completeTime; + if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY || quest.repeat == EnumQuestRepeat.RLCUSTOM){ + completeTime = System.currentTimeMillis(); + playerdata.questData.finishedQuests.put(quest.id, completeTime); + } else { + completeTime = sender.getEntityWorld().getTotalWorldTime(); + playerdata.questData.finishedQuests.put(quest.id, completeTime); } - if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY) - playerdata.questData.finishedQuests.put(quest.id, System.currentTimeMillis()); - else - playerdata.questData.finishedQuests.put(quest.id, sender.getEntityWorld().getTotalWorldTime()); + if(ConfigMain.ProfilesEnabled && playerdata.player != null && quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared) + ProfileController.Instance.shareQuestCompletion(playerdata.player, quest.id, completeTime);; if(playerdata.player != null){ AchievementPacket.sendAchievement((EntityPlayerMP) playerdata.player, false, "quest.completed", quest.title); diff --git a/src/main/java/kamkeel/npcs/command/QuestCommand.java b/src/main/java/kamkeel/npcs/command/QuestCommand.java index 7ac9b1fcd..e1e0894d0 100644 --- a/src/main/java/kamkeel/npcs/command/QuestCommand.java +++ b/src/main/java/kamkeel/npcs/command/QuestCommand.java @@ -1,5 +1,6 @@ package kamkeel.npcs.command; +import kamkeel.npcs.controllers.ProfileController; import kamkeel.npcs.controllers.SyncController; import kamkeel.npcs.network.packets.data.AchievementPacket; import kamkeel.npcs.network.packets.data.ChatAlertPacket; @@ -8,6 +9,8 @@ import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import noppes.npcs.api.handler.data.IQuestObjective; +import noppes.npcs.config.ConfigMain; +import noppes.npcs.constants.EnumProfileSync; import noppes.npcs.constants.EnumQuestCompletion; import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.controllers.PlayerDataController; @@ -21,6 +24,9 @@ import noppes.npcs.util.ValueUtil; import java.util.Collection; import java.util.List; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class QuestCommand extends CommandKamkeelBase { @Override @@ -100,14 +106,18 @@ public class QuestCommand extends CommandKamkeelBase { return; } for(PlayerData playerdata : data){ - if(playerdata.questData.activeQuests.containsKey(questid)){ - playerdata.questData.activeQuests.remove(questid); + playerdata.questData.activeQuests.remove(questid); + long completeTime; + if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY || quest.repeat == EnumQuestRepeat.RLCUSTOM){ + completeTime = System.currentTimeMillis(); + playerdata.questData.finishedQuests.put(quest.id, completeTime); + } else { + completeTime = sender.getEntityWorld().getTotalWorldTime(); + playerdata.questData.finishedQuests.put(quest.id, completeTime); } - if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY) - playerdata.questData.finishedQuests.put(quest.id, System.currentTimeMillis()); - else - playerdata.questData.finishedQuests.put(quest.id, sender.getEntityWorld().getTotalWorldTime()); + if(ConfigMain.ProfilesEnabled && playerdata.player != null && quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared) + ProfileController.Instance.shareQuestCompletion(playerdata.player, quest.id, completeTime); playerdata.save(); if(playerdata.player != null){ diff --git a/src/main/java/kamkeel/npcs/command/ScriptCommand.java b/src/main/java/kamkeel/npcs/command/ScriptCommand.java index bf62cc3fb..f314d2e42 100644 --- a/src/main/java/kamkeel/npcs/command/ScriptCommand.java +++ b/src/main/java/kamkeel/npcs/command/ScriptCommand.java @@ -3,6 +3,9 @@ package kamkeel.npcs.command; import net.minecraft.command.ICommandSender; import noppes.npcs.controllers.ScriptController; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class ScriptCommand extends CommandKamkeelBase { diff --git a/src/main/java/kamkeel/npcs/command/SlayCommand.java b/src/main/java/kamkeel/npcs/command/SlayCommand.java index 60af6d6cf..82400b148 100644 --- a/src/main/java/kamkeel/npcs/command/SlayCommand.java +++ b/src/main/java/kamkeel/npcs/command/SlayCommand.java @@ -20,6 +20,8 @@ import noppes.npcs.entity.EntityNPCInterface; import java.util.*; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class SlayCommand extends CommandKamkeelBase { public Map> SlayMap = new LinkedHashMap>(); diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandHelpProfile.java b/src/main/java/kamkeel/npcs/command/profile/CommandHelpProfile.java index 672e7886c..a03d30ea0 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandHelpProfile.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandHelpProfile.java @@ -2,69 +2,92 @@ package kamkeel.npcs.command.profile; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ChatComponentTranslation; +import noppes.npcs.CustomNpcsPermissions; import java.lang.reflect.Method; import java.util.Map.Entry; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendMessage; + public class CommandHelpProfile extends CommandProfileBase { - private CommandProfile parent; + private CommandProfile parent; - public CommandHelpProfile(CommandProfile parent){ - this.parent = parent; - } + public CommandHelpProfile(CommandProfile parent){ + this.parent = parent; + } - @Override - public String getCommandName() { - return "help"; - } + @Override + public String getCommandName() { + return "help"; + } - @Override - public String getDescription() { - return "help [command]"; - } + @Override + public String getDescription() { + return "help [command]"; + } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if(args.length == 0){ - sendMessage(sender, "\u00A78------ \u00A7aProfile Commands \u00A78------"); - for(Entry entry : parent.map.entrySet()){ - sendMessage(sender, "\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + entry.getValue().getCommandUsage(sender)); - } - return; - } + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + if(args.length == 0){ + sendMessage(sender, "\u00A78------ \u00A7aProfile Commands \u00A78------"); + for(Entry entry : parent.map.entrySet()){ + sendMessage(sender, "\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + + entry.getValue().getCommandUsage(sender)); + } + return; + } CommandProfileBase command = parent.getCommand(args); - if(command == null){ - sendError(sender, "Unknown command " + args[0]); - return; - } + if(command == null){ + sendError(sender, "Unknown command " + args[0]); + return; + } - if(command.subcommands.isEmpty()){ - sender.addChatMessage(new ChatComponentTranslation(command.getCommandUsage(sender))); - return; - } + if(command.subcommands.isEmpty()){ + sender.addChatMessage(new ChatComponentTranslation(command.getCommandUsage(sender))); + return; + } - Method m = null; - if(args.length > 1){ - m = command.subcommands.get(args[1].toLowerCase()); - } - if(m == null){ - sendMessage(sender, "\u00A78------ \u00A7a" + command.getCommandName().toUpperCase() + " SubCommands \u00A78------"); - sendMessage(sender, "\u00A77Usage: \u00A76" + command.getUsage()); - for(Entry entry : command.subcommands.entrySet()){ - sender.addChatMessage(new ChatComponentTranslation("\u00A77> " + "\u00A7e" + entry.getKey() + "\u00A78: \u00A77" + entry.getValue().getAnnotation(SubCommand.class).desc())); - } - sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + CommandProfile.getCommandPermission(command.getCommandName()))); - } - else{ - sendMessage(sender, "\u00A78------ \u00A7b" + command.getCommandName().toUpperCase() + "." + args[1].toUpperCase() + " Command \u00A78------"); - SubCommand sc = m.getAnnotation(SubCommand.class); - sender.addChatMessage(new ChatComponentTranslation("\u00A77" + sc.desc())); - if(!sc.usage().isEmpty()) - sender.addChatMessage(new ChatComponentTranslation("\u00A77Usage: \u00A76" + sc.usage())); - sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + getSubCommandPermission(args[1]))); - } - } + Method m = null; + if(args.length > 1){ + m = command.subcommands.get(args[1].toLowerCase()); + } + if(m == null){ + sendMessage(sender, "\u00A78------ \u00A7a" + command.getCommandName().toUpperCase() + + " SubCommands \u00A78------"); + sendMessage(sender, "\u00A77Usage: \u00A76" + command.getUsage()); + for(Entry entry : command.subcommands.entrySet()){ + SubCommand sc = entry.getValue().getAnnotation(SubCommand.class); + // For players, only list subcommands if they have permission; for console, show all. + if(!(sender instanceof EntityPlayer) || command.canSendCommand(sender, sc, entry.getKey())){ + sender.addChatMessage(new ChatComponentTranslation("\u00A77> " + + "\u00A7e" + entry.getKey() + + "\u00A78: \u00A77" + sc.desc())); + } + } + // Show permission node only if sender is console or has permission. + if(!(sender instanceof EntityPlayer) || + CustomNpcsPermissions.hasPermission((EntityPlayer)sender, CustomNpcsPermissions.PROFILE_ADMIN)){ + sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + + CommandProfile.getCommandPermission(command.getCommandName()))); + } + } + else{ + sendMessage(sender, "\u00A78------ \u00A7b" + command.getCommandName().toUpperCase() + + "." + args[1].toUpperCase() + " Command \u00A78------"); + SubCommand sc = m.getAnnotation(SubCommand.class); + sender.addChatMessage(new ChatComponentTranslation("\u00A77" + sc.desc())); + if(!sc.usage().isEmpty()){ + sender.addChatMessage(new ChatComponentTranslation("\u00A77Usage: \u00A76" + sc.usage())); + } + if(!(sender instanceof EntityPlayer) || + CustomNpcsPermissions.hasPermission((EntityPlayer)sender, CustomNpcsPermissions.PROFILE_ADMIN)){ + sender.addChatMessage(new ChatComponentTranslation("\u00A78Permission:\u00A77 " + + getSubCommandPermission(args[1]))); + } + } + } } diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfile.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfile.java index 035fecb1a..4987f1bbf 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfile.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfile.java @@ -23,8 +23,10 @@ public class CommandProfile extends CommandBase { public CommandProfile(){ registerCommand(help); registerCommand(new CommandProfileChange()); + registerCommand(new CommandProfileCreate()); registerCommand(new CommandProfileRemove()); registerCommand(new CommandProfileAdmin()); + registerCommand(new CommandProfileRegion()); registerCommand(new CommandProfileList()); registerCommand(new CommandProfileRename()); } @@ -99,7 +101,8 @@ public class CommandProfile extends CommandBase { if(args.length <= useArgs.length + 2) { if(args.length - 3 >= 0){ String usage = useArgs[args.length - 3]; - if(usage.equals("") || usage.equals("[player]")) { + if(usage.equals("") || usage.equals("[player]") || usage.equals("") + || usage.equals("") || usage.equals("")) { return CommandBase.getListOfStringsMatchingLastWord(args, MinecraftServer.getServer().getAllUsernames()); } } @@ -115,7 +118,7 @@ public class CommandProfile extends CommandBase { @Override public int getRequiredPermissionLevel(){ - return 0; + return 4; } public static String getCommandPermission(String command){ diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileAdmin.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileAdmin.java index 4b1c2429d..4bc21da09 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfileAdmin.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileAdmin.java @@ -1,17 +1,19 @@ package kamkeel.npcs.command.profile; import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.EnumProfileOperation; +import noppes.npcs.api.handler.data.ISlot; import kamkeel.npcs.controllers.data.Profile; import kamkeel.npcs.controllers.data.ProfileOperation; -import kamkeel.npcs.controllers.data.Slot; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import noppes.npcs.LogWriter; -import net.minecraft.nbt.NBTTagCompound; +import java.io.File; import java.util.Map; import java.util.UUID; +import static kamkeel.npcs.util.ColorUtil.*; + public class CommandProfileAdmin extends CommandProfileBase { @Override @@ -21,7 +23,7 @@ public class CommandProfileAdmin extends CommandProfileBase { @Override public String getDescription() { - return "Admin profile management: clone, remove, change, and list a player's slots."; + return "Admin profile management: clone, remove, change, list, rename, and rollback profiles."; } @Override @@ -34,7 +36,7 @@ public class CommandProfileAdmin extends CommandProfileBase { usage = " [temp]" ) public void clone(ICommandSender sender, String[] args) throws CommandException { - if (args.length < 4) { + if(args.length < 4) { sendError(sender, "Usage: /profile admin clone [temp]"); return; } @@ -45,55 +47,20 @@ public class CommandProfileAdmin extends CommandProfileBase { sourceSlot = Integer.parseInt(args[2]); destinationSlot = Integer.parseInt(args[3]); } catch (NumberFormatException ex) { - sendError(sender, "Source and destination slot IDs must be numbers."); + sendError(sender, "Slot IDs must be numbers."); return; } boolean temporary = (args.length >= 5 && args[4].equalsIgnoreCase("temp")); - - Profile sourceProfile = ProfileController.getProfile(sourcePlayer); - if (sourceProfile == null) { - sendError(sender, "Source profile not found for player: " + sourcePlayer); - return; - } - Profile destProfile = ProfileController.getProfile(destinationPlayer); - if (destProfile == null) { - sendError(sender, "Destination profile not found for player: " + destinationPlayer); - return; - } - if (destProfile.locked) { - sendError(sender, "Destination profile is locked. Please try again later."); - return; - } - if (!sourceProfile.slots.containsKey(sourceSlot)) { - sendError(sender, "Source slot " + sourceSlot + " does not exist for player: " + sourcePlayer); - return; - } - if (destinationSlot == destProfile.currentID) { - sendError(sender, "Cannot clone into the destination's active slot."); - return; - } - try { - Slot sourceSlotObj = sourceProfile.slots.get(sourceSlot); - if (sourceSlotObj == null) { - sendError(sender, "Source slot is invalid."); - return; - } - NBTTagCompound clonedData = (NBTTagCompound) sourceSlotObj.getCompound().copy(); - Slot clonedSlot = new Slot(destinationSlot, "Admin Cloned Slot " + destinationSlot, clonedData, System.currentTimeMillis(), temporary); - destProfile.slots.put(destinationSlot, clonedSlot); - - if (destProfile.player != null) { - ProfileController.save(destProfile.player, destProfile); - } else { - UUID destUUID = ProfileController.getUUIDFromUsername(destinationPlayer); - if (destUUID != null) - ProfileController.saveOffline(destProfile, destUUID); - } - sendResult(sender, "Successfully cloned slot %d from %s to slot %d for %s%s.", - sourceSlot, sourcePlayer, destinationSlot, destinationPlayer, (temporary ? " (temporary)" : "")); - } catch (Exception e) { - LogWriter.error("Error cloning slot", e); - sendError(sender, "An error occurred while cloning slot."); + ProfileOperation result = ProfileController.Instance.cloneSlot(sourcePlayer, sourceSlot, destinationSlot, temporary); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "Successfully cloned slot %d from %s to slot %d for %s.", sourceSlot, sourcePlayer, destinationSlot, destinationPlayer); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + // Detail message for admins – note: using result.getMessage() for further details. + sendError(sender, "Clone failed for %s: Profile is locked. Details: %s", sourcePlayer, result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error cloning slot for %s: %s", sourcePlayer, result.getMessage()); + } else { + sendError(sender, "Unexpected error cloning slot: %s", result.getMessage()); } } @@ -102,7 +69,7 @@ public class CommandProfileAdmin extends CommandProfileBase { usage = " " ) public void remove(ICommandSender sender, String[] args) throws CommandException { - if (args.length < 2) { + if(args.length < 2) { sendError(sender, "Usage: /profile admin remove "); return; } @@ -110,29 +77,19 @@ public class CommandProfileAdmin extends CommandProfileBase { int slotId; try { slotId = Integer.parseInt(args[1]); - } catch (NumberFormatException ex) { + } catch(NumberFormatException ex) { sendError(sender, "Slot ID must be a number."); return; } - Profile targetProfile = ProfileController.getProfile(targetPlayer); - if (targetProfile == null) { - sendError(sender, "Profile not found for player: " + targetPlayer); - return; - } - if (targetProfile.locked) { - sendError(sender, "Profile for " + targetPlayer + " is locked. Please try again later."); - return; - } - ProfileOperation result = ProfileController.removeSlot(targetPlayer, slotId); - switch (result) { - case SUCCESS: - sendResult(sender, "Successfully removed slot %d from %s.", slotId, targetPlayer); - break; - case LOCKED: - sendError(sender, "Profile for " + targetPlayer + " is locked."); - break; - default: - sendError(sender, "Error removing slot %d from %s.", slotId, targetPlayer); + ProfileOperation result = ProfileController.Instance.removeSlot(targetPlayer, slotId); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "Successfully removed slot %d from %s.", slotId, targetPlayer); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + sendError(sender, "Remove failed for %s: Profile is locked. Details: %s", targetPlayer, result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error removing slot %d from %s: %s", slotId, targetPlayer, result.getMessage()); + } else { + sendError(sender, "Unexpected error during removal: %s", result.getMessage()); } } @@ -141,7 +98,7 @@ public class CommandProfileAdmin extends CommandProfileBase { usage = " " ) public void change(ICommandSender sender, String[] args) throws CommandException { - if (args.length < 2) { + if(args.length < 2) { sendError(sender, "Usage: /profile admin change "); return; } @@ -149,29 +106,46 @@ public class CommandProfileAdmin extends CommandProfileBase { int newSlotId; try { newSlotId = Integer.parseInt(args[1]); - } catch (NumberFormatException ex) { + } catch(NumberFormatException ex) { sendError(sender, "Slot ID must be a number."); return; } - Profile targetProfile = ProfileController.getProfile(targetPlayer); - if (targetProfile == null) { - sendError(sender, "Profile not found for player: " + targetPlayer); + ProfileOperation result = ProfileController.Instance.changeSlot(targetPlayer, newSlotId); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "Successfully changed %s's active slot to %d.", targetPlayer, newSlotId); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + sendError(sender, "Change failed for %s: Profile is locked. Details: %s", targetPlayer, result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error changing active slot for %s: %s", targetPlayer, result.getMessage()); + } else { + sendError(sender, "Unexpected error during change: %s", result.getMessage()); + } + } + + @SubCommand( + desc = "Create a new slot for a specified player's profile.", + usage = "" + ) + public void create(ICommandSender sender, String[] args) throws CommandException { + if(args.length < 1) { + sendError(sender, "Usage: /profile admin create "); return; } - if (targetProfile.locked) { - sendError(sender, "Profile for " + targetPlayer + " is locked. Please try again later."); + String targetPlayer = args[0]; + Profile profile = ProfileController.Instance.getProfile(targetPlayer); + if(profile == null) { + sendError(sender, "Profile not found for player: %s", targetPlayer); return; } - ProfileOperation result = ProfileController.changeSlot(targetPlayer, newSlotId); - switch (result) { - case SUCCESS: - sendResult(sender, "Successfully changed %s's active slot to %d.", targetPlayer, newSlotId); - break; - case LOCKED: - sendError(sender, "Profile for " + targetPlayer + " is locked."); - break; - default: - sendError(sender, "Error changing active slot for " + targetPlayer); + ProfileOperation result = ProfileController.Instance.createSlotInternal(profile); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "New slot created successfully for %s.", targetPlayer); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + sendError(sender, "Create failed for %s: Profile is locked. Details: %s", targetPlayer, result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error creating new slot for %s: %s", targetPlayer, result.getMessage()); + } else { + sendError(sender, "Unexpected error during slot creation: %s", result.getMessage()); } } @@ -180,21 +154,21 @@ public class CommandProfileAdmin extends CommandProfileBase { usage = "" ) public void list(ICommandSender sender, String[] args) throws CommandException { - if (args.length < 1) { + if(args.length < 1) { sendError(sender, "Usage: /profile admin list "); return; } String targetPlayer = args[0]; - Profile targetProfile = ProfileController.getProfile(targetPlayer); - if (targetProfile == null) { - sendError(sender, "Profile not found for player: " + targetPlayer); + Profile profile = ProfileController.Instance.getProfile(targetPlayer); + if(profile == null) { + sendError(sender, "Profile not found for player: %s", targetPlayer); return; } - sendMessage(sender, "Profile Slots for " + targetPlayer + ":"); - for (Map.Entry entry : targetProfile.slots.entrySet()) { + sendMessage(sender, "Profile Slots for %s:", targetPlayer); + for(Map.Entry entry : profile.getSlots().entrySet()) { int id = entry.getKey(); String name = entry.getValue().getName(); - String prefix = (id == targetProfile.currentID) ? "* " : "- "; + String prefix = (id == profile.currentSlotId) ? "* " : "- "; sendMessage(sender, prefix + "Slot " + id + ": " + name); } } @@ -204,7 +178,7 @@ public class CommandProfileAdmin extends CommandProfileBase { usage = " " ) public void rename(ICommandSender sender, String[] args) throws CommandException { - if (args.length < 3) { + if(args.length < 3) { sendError(sender, "Usage: /profile admin rename "); return; } @@ -212,50 +186,74 @@ public class CommandProfileAdmin extends CommandProfileBase { int slotId; try { slotId = Integer.parseInt(args[1]); - } catch (NumberFormatException ex) { + } catch(NumberFormatException ex) { sendError(sender, "Slot ID must be a number."); return; } - // Combine remaining arguments for the new name. StringBuilder sb = new StringBuilder(); - for (int i = 2; i < args.length; i++) { - if (i > 2) sb.append(" "); + for(int i = 2; i < args.length; i++){ + if(i > 2) sb.append(" "); sb.append(args[i]); } String newName = sb.toString().trim(); - // Cap name at 20 characters. - if (newName.length() > 20) { + if(newName.length() > 20) { newName = newName.substring(0, 20); } - // Validate that name contains only letters and spaces. - if (!newName.matches("[A-Za-z ]+")) { + if(!newName.matches("[A-Za-z ]+")){ sendError(sender, "Invalid name. Only alphabetic characters and spaces are allowed."); return; } - Profile targetProfile = ProfileController.getProfile(targetPlayer); - if (targetProfile == null) { - sendError(sender, "Profile not found for player: " + targetPlayer); + Profile profile = ProfileController.Instance.getProfile(targetPlayer); + if(profile == null) { + sendError(sender, "Profile not found for player: %s", targetPlayer); return; } - if (targetProfile.locked) { - sendError(sender, "Profile for " + targetPlayer + " is locked. Please try again later."); + if(profile.isLocked()) { + sendError(sender, "Profile for %s is locked. Please try again later.", targetPlayer); return; } - if (!targetProfile.slots.containsKey(slotId)) { - sendError(sender, "Slot " + slotId + " not found in " + targetPlayer + "'s profile."); + if(!profile.getSlots().containsKey(slotId)) { + sendError(sender, "Slot %d not found in %s's profile.", slotId, targetPlayer); return; } - // Rename the slot. - Slot targetSlot = targetProfile.slots.get(slotId); - targetSlot.setName(newName); - // Save the updated profile. - if (targetProfile.player != null) { - ProfileController.save(targetProfile.player, targetProfile); + profile.getSlots().get(slotId).setName(newName); + if(profile.getPlayer() != null) { + ProfileController.Instance.save(profile.player, profile); } else { - UUID uuid = ProfileController.getUUIDFromUsername(targetPlayer); - if (uuid != null) - ProfileController.saveOffline(targetProfile, uuid); + UUID uuid = ProfileController.Instance.getUUIDFromUsername(targetPlayer); + if(uuid != null) + ProfileController.Instance.saveOffline(profile, uuid); + } + sendResult(sender, "Successfully renamed slot %d for %s to '%s'.", slotId, targetPlayer, newName); + } + + @SubCommand( + desc = "Rollback a player's profile to one of their backups.", + usage = " " + ) + public void rollback(ICommandSender sender, String[] args) throws CommandException { + if(args.length < 2) { + sendError(sender, "Usage: /profile admin rollback "); + return; + } + String targetPlayer = args[0]; + String backupFileName = args[1] + ".dat"; + + Profile profile = ProfileController.Instance.getProfile(targetPlayer); + if(profile == null || profile.player == null) + return; + + File backupDir = new File(ProfileController.getBackupDir(), profile.getPlayer().getUniqueID().toString()); + File backupFile = new File(backupDir, backupFileName); + if(!backupFile.exists()){ + sendError(sender, "Backup file %s not found for player %s.", backupFileName, targetPlayer); + return; + } + boolean success = ProfileController.Instance.rollbackProfile(targetPlayer, backupFile); + if(success) { + sendResult(sender, "Successfully rolled back %s's profile to backup %s.", targetPlayer, backupFileName); + } else { + sendError(sender, "Failed to rollback %s's profile.", targetPlayer); } - sendResult(sender, "Successfully renamed slot %s for %s to '%s'.", slotId, targetPlayer, newName); } } diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileBase.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileBase.java index 18c06ad4f..71f44a4be 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfileBase.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileBase.java @@ -4,7 +4,6 @@ import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.ChatComponentTranslation; import noppes.npcs.CustomNpcsPermissions; import java.lang.annotation.ElementType; @@ -55,19 +54,7 @@ public abstract class CommandProfileBase extends CommandBase{ return !subcommands.isEmpty(); } - protected static void sendMessage(ICommandSender sender, String message, Object... obs) { - sender.addChatMessage(new ChatComponentTranslation(message, obs)); - } - - protected static void sendResult(ICommandSender sender, String message, Object... obs) { - sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A77 " + message, obs)); - } - - protected static void sendError(ICommandSender sender, String message, Object... obs) { - sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A74 Error:\u00A7c " + message, obs)); - } - - @Retention(value = RetentionPolicy.RUNTIME) + @Retention(value = RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SubCommand { diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileChange.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileChange.java index bbce07b84..b7373aa34 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfileChange.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileChange.java @@ -1,11 +1,15 @@ package kamkeel.npcs.command.profile; import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.EnumProfileOperation; import kamkeel.npcs.controllers.data.ProfileOperation; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class CommandProfileChange extends CommandProfileBase { @Override @@ -30,35 +34,31 @@ public class CommandProfileChange extends CommandProfileBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (!(sender instanceof EntityPlayer)) { + if(!(sender instanceof EntityPlayer)) { sendError(sender, "This command can only be used by a player."); return; } - if (args.length < 1) { + if(args.length < 1) { sendError(sender, "Usage: " + getUsage()); return; } int slotId; try { slotId = Integer.parseInt(args[0]); - } catch (NumberFormatException ex) { + } catch(NumberFormatException ex) { sendError(sender, "Slot ID must be a number: " + args[0]); return; } - EntityPlayer player = (EntityPlayer) sender; - ProfileOperation result = ProfileController.changeSlot(player, slotId); - switch(result) { - case SUCCESS: - sendResult(sender, "Successfully changed profile slot to %s.", slotId); - break; - case LOCKED: - sendError(sender, "Profile is locked. Please try again later."); - break; - case ERROR: - sendError(sender, "Error occurred while changing your profile slot."); - break; - default: - sendError(sender, "Operation could not be completed."); + EntityPlayer player = (EntityPlayer)sender; + ProfileOperation result = ProfileController.Instance.changeSlot(player, slotId); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "Successfully changed profile slot to %d.", slotId); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + sendError(sender, "Profile is locked. Details: %s", result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error changing your profile slot: %s", result.getMessage()); + } else { + sendError(sender, "Unexpected error: %s", result.getMessage()); } } } diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileCreate.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileCreate.java new file mode 100644 index 000000000..6b06f266a --- /dev/null +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileCreate.java @@ -0,0 +1,57 @@ +package kamkeel.npcs.command.profile; + +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.EnumProfileOperation; +import kamkeel.npcs.controllers.data.ProfileOperation; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; + +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + +public class CommandProfileCreate extends CommandProfileBase { + + @Override + public String getCommandName() { + return "create"; + } + + @Override + public String getDescription() { + return "Create a new profile slot."; + } + + @Override + public String getUsage() { + return ""; + } + + @Override + public boolean runSubCommands() { + return false; + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + if(!(sender instanceof EntityPlayer)) { + sendError(sender, "This command can only be used by a player."); + return; + } + EntityPlayer player = (EntityPlayer)sender; + if(ProfileController.Instance.getProfile(player) == null) { + sendError(sender, "Profile not found."); + return; + } + ProfileOperation result = ProfileController.Instance.createSlotInternal(ProfileController.Instance.getProfile(player)); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "New profile slot created successfully."); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + sendError(sender, "Profile is locked. Details: %s", result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error creating new profile slot: %s", result.getMessage()); + } else { + sendError(sender, "Unexpected error: %s", result.getMessage()); + } + } +} diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileList.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileList.java index 3ba49fc9a..17e82fcce 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfileList.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileList.java @@ -1,14 +1,17 @@ package kamkeel.npcs.command.profile; import kamkeel.npcs.controllers.ProfileController; +import noppes.npcs.api.handler.data.ISlot; import kamkeel.npcs.controllers.data.Profile; -import kamkeel.npcs.controllers.data.Slot; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; import java.util.Map; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendMessage; + public class CommandProfileList extends CommandProfileBase { @Override @@ -28,21 +31,24 @@ public class CommandProfileList extends CommandProfileBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (!(sender instanceof EntityPlayer)) { + if(!(sender instanceof EntityPlayer)) { sendError(sender, "This command can only be used by a player."); return; } - EntityPlayer player = (EntityPlayer) sender; - Profile profile = ProfileController.getProfile(player); - if (profile == null) { + EntityPlayer player = (EntityPlayer)sender; + Profile profile = ProfileController.Instance.getProfile(player); + if(profile == null) { sendError(sender, "Profile not found."); return; } + if(profile.getSlots().isEmpty()){ + sendMessage(sender, "No slots found. Using default slot 0."); + } sendMessage(sender, "Your Profile Slots:"); - for (Map.Entry entry : profile.slots.entrySet()) { + for(Map.Entry entry : profile.getSlots().entrySet()) { int id = entry.getKey(); String name = entry.getValue().getName(); - String prefix = (id == profile.currentID) ? "* " : "- "; + String prefix = (id == profile.currentSlotId) ? "* " : "- "; sendMessage(sender, prefix + "Slot " + id + ": " + name); } } diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileRegion.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileRegion.java new file mode 100644 index 000000000..24b993d77 --- /dev/null +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileRegion.java @@ -0,0 +1,159 @@ +package kamkeel.npcs.command.profile; + +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import noppes.npcs.config.ConfigMain; + +import java.util.ArrayList; +import java.util.List; + +import static kamkeel.npcs.util.ColorUtil.*; + +public class CommandProfileRegion extends CommandProfileBase { + + @Override + public String getCommandName() { + return "region"; + } + + @Override + public String getDescription() { + return "Manage profile region switching and restricted regions"; + } + + @Override + public String getUsage() { + return ""; + } + + @SubCommand( + desc = "Enable region-based profile switching", + usage = "" + ) + public void enable(ICommandSender sender, String[] args) throws CommandException { + ConfigMain.RegionProfileSwitching = true; + ConfigMain.RegionProfileSwitchingProperty.set(true); + if(ConfigMain.config.hasChanged()){ + ConfigMain.config.save(); + } + sendResult(sender, "Profile region switching enabled."); + } + + @SubCommand( + desc = "Disable region-based profile switching", + usage = "" + ) + public void disable(ICommandSender sender, String[] args) throws CommandException { + ConfigMain.RegionProfileSwitching = false; + ConfigMain.RegionProfileSwitchingProperty.set(false); + if(ConfigMain.config.hasChanged()){ + ConfigMain.config.save(); + } + sendResult(sender, "Profile region switching disabled."); + } + + @SubCommand( + desc = "Add a new region. Format: DIM, X1, Y1, Z1, X2, Y2, Z2", + usage = " " + ) + public void add(ICommandSender sender, String[] args) throws CommandException { + if(args.length < 1){ + sendError(sender, "Usage: /profile region add "); + return; + } + // Combine args in case the region data was split by spaces + String regionStr = String.join(" ", args).trim(); + String[] parts = regionStr.split(","); + if(parts.length != 7){ + sendError(sender, "Invalid region format. Must contain 7 integers separated by commas."); + return; + } + List regionList = new ArrayList<>(); + try { + for(String part : parts){ + regionList.add(Integer.parseInt(part.trim())); + } + } catch(NumberFormatException e){ + sendError(sender, "Invalid number format in region data."); + return; + } + ConfigMain.RestrictedProfileRegions.add(regionList); + // Update config property value + List regionStrings = new ArrayList<>(); + for(List region : ConfigMain.RestrictedProfileRegions) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < region.size(); i++) { + if(i > 0) sb.append(", "); + sb.append(region.get(i)); + } + regionStrings.add(sb.toString()); + } + ConfigMain.RestrictedProfileRegionsProperty.set(regionStrings.toArray(new String[0])); + if(ConfigMain.config.hasChanged()){ + ConfigMain.config.save(); + } + sendResult(sender, "Region added successfully."); + } + + @SubCommand( + desc = "Remove a region by its index (1-based).", + usage = "" + ) + public void remove(ICommandSender sender, String[] args) throws CommandException { + if(args.length < 1){ + sendError(sender, "Usage: /profile region remove "); + return; + } + int index; + try { + index = Integer.parseInt(args[0]); + } catch(NumberFormatException e){ + sendError(sender, "Index must be a number."); + return; + } + index = index - 1; // Convert to 0-based index + if(index < 0 || index >= ConfigMain.RestrictedProfileRegions.size()){ + sendError(sender, "Invalid index. Must be between 1 and " + ConfigMain.RestrictedProfileRegions.size()); + return; + } + ConfigMain.RestrictedProfileRegions.remove(index); + // Update config property value + List regionStrings = new ArrayList<>(); + for(List region : ConfigMain.RestrictedProfileRegions) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < region.size(); i++) { + if(i > 0) sb.append(", "); + sb.append(region.get(i)); + } + regionStrings.add(sb.toString()); + } + ConfigMain.RestrictedProfileRegionsProperty.set(regionStrings.toArray(new String[0])); + if(ConfigMain.config.hasChanged()){ + ConfigMain.config.save(); + } + sendResult(sender, "Region removed successfully."); + } + + @SubCommand( + desc = "List all restricted profile regions.", + usage = "" + ) + public void list(ICommandSender sender, String[] args) throws CommandException { + if(ConfigMain.RestrictedProfileRegions.isEmpty()){ + sendMessage(sender, "No restricted profile regions configured."); + return; + } + sendMessage(sender, "Restricted Profile Regions:"); + int i = 1; + for(List region : ConfigMain.RestrictedProfileRegions) { + StringBuilder sb = new StringBuilder(); + sb.append(i).append(": "); + for (int j = 0; j < region.size(); j++) { + if(j > 0) sb.append(", "); + sb.append(region.get(j)); + } + sendMessage(sender, sb.toString()); + i++; + } + } +} diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileRemove.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileRemove.java index 9af22fca5..a80d76f8b 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfileRemove.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileRemove.java @@ -1,11 +1,15 @@ package kamkeel.npcs.command.profile; import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.EnumProfileOperation; import kamkeel.npcs.controllers.data.ProfileOperation; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class CommandProfileRemove extends CommandProfileBase { @Override @@ -30,35 +34,31 @@ public class CommandProfileRemove extends CommandProfileBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (!(sender instanceof EntityPlayer)) { + if(!(sender instanceof EntityPlayer)) { sendError(sender, "This command can only be used by a player."); return; } - if (args.length < 1) { + if(args.length < 1) { sendError(sender, "Usage: " + getUsage()); return; } int slotId; try { slotId = Integer.parseInt(args[0]); - } catch (NumberFormatException ex) { + } catch(NumberFormatException ex) { sendError(sender, "Slot ID must be a number: " + args[0]); return; } - EntityPlayer player = (EntityPlayer) sender; - ProfileOperation result = ProfileController.removeSlot(player, slotId); - switch(result) { - case SUCCESS: - sendResult(sender, "Successfully removed slot %d from your profile.", slotId); - break; - case LOCKED: - sendError(sender, "Profile is locked. Please try again later."); - break; - case ERROR: - sendError(sender, "Error removing slot. Ensure the slot exists and is not your active slot."); - break; - default: - sendError(sender, "Operation could not be completed."); + EntityPlayer player = (EntityPlayer)sender; + ProfileOperation result = ProfileController.Instance.removeSlot(player, slotId); + if(result.getResult() == EnumProfileOperation.SUCCESS) { + sendResult(sender, "Successfully removed slot %d from your profile.", slotId); + } else if(result.getResult() == EnumProfileOperation.LOCKED) { + sendError(sender, "Profile is locked. Details: %s", result.getMessage()); + } else if(result.getResult() == EnumProfileOperation.ERROR) { + sendError(sender, "Error removing slot: %s", result.getMessage()); + } else { + sendError(sender, "Unexpected error: %s", result.getMessage()); } } } diff --git a/src/main/java/kamkeel/npcs/command/profile/CommandProfileRename.java b/src/main/java/kamkeel/npcs/command/profile/CommandProfileRename.java index 53c092b45..50108d7b1 100644 --- a/src/main/java/kamkeel/npcs/command/profile/CommandProfileRename.java +++ b/src/main/java/kamkeel/npcs/command/profile/CommandProfileRename.java @@ -1,12 +1,13 @@ package kamkeel.npcs.command.profile; import kamkeel.npcs.controllers.ProfileController; -import kamkeel.npcs.controllers.data.Profile; -import kamkeel.npcs.controllers.data.Slot; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayer; +import static kamkeel.npcs.util.ColorUtil.sendError; +import static kamkeel.npcs.util.ColorUtil.sendResult; + public class CommandProfileRename extends CommandProfileBase { @Override @@ -26,52 +27,45 @@ public class CommandProfileRename extends CommandProfileBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (!(sender instanceof EntityPlayer)) { + if(!(sender instanceof EntityPlayer)) { sendError(sender, "This command can only be used by a player."); return; } - if (args.length < 2) { + if(args.length < 2) { sendError(sender, "Usage: " + getUsage()); return; } int slotId; try { slotId = Integer.parseInt(args[0]); - } catch (NumberFormatException e) { + } catch(NumberFormatException ex) { sendError(sender, "Slot ID must be a number."); return; } - // Combine remaining arguments into one name string. StringBuilder sb = new StringBuilder(); - for (int i = 1; i < args.length; i++) { - if (i > 1) sb.append(" "); + for(int i = 1; i < args.length; i++){ + if(i > 1) sb.append(" "); sb.append(args[i]); } String newName = sb.toString().trim(); - // Cap at 20 characters. - if (newName.length() > 20) { + if(newName.length() > 20) { newName = newName.substring(0, 20); } - // Validate that the new name contains only letters and spaces. - if (!newName.matches("[A-Za-z ]+")) { + if(!newName.matches("[A-Za-z ]+")){ sendError(sender, "Invalid name. Only alphabetic characters and spaces are allowed."); return; } - - EntityPlayer player = (EntityPlayer) sender; - Profile profile = ProfileController.getProfile(player); - if (profile == null) { + EntityPlayer player = (EntityPlayer)sender; + if(ProfileController.Instance.getProfile(player) == null) { sendError(sender, "Profile not found."); return; } - if (!profile.slots.containsKey(slotId)) { - sendError(sender, "Slot " + slotId + " not found in your profile."); + if(!ProfileController.Instance.getProfile(player).getSlots().containsKey(slotId)) { + sendError(sender, "Slot %d not found in your profile.", slotId); return; } - Slot slot = profile.slots.get(slotId); - slot.setName(newName); - // Save the profile after renaming. - ProfileController.save(player, profile); - sendResult(sender, "Successfully renamed slot %s to '%s'.", slotId, newName); + ProfileController.Instance.getProfile(player).getSlots().get(slotId).setName(newName); + ProfileController.Instance.save(player, ProfileController.Instance.getProfile(player)); + sendResult(sender, "Successfully renamed slot %d to '%s'.", slotId, newName); } } diff --git a/src/main/java/kamkeel/npcs/controllers/ProfileController.java b/src/main/java/kamkeel/npcs/controllers/ProfileController.java index 96ee90145..0a4078450 100644 --- a/src/main/java/kamkeel/npcs/controllers/ProfileController.java +++ b/src/main/java/kamkeel/npcs/controllers/ProfileController.java @@ -1,54 +1,78 @@ package kamkeel.npcs.controllers; -import kamkeel.npcs.controllers.data.IProfileData; -import kamkeel.npcs.controllers.data.ProfileOperation; -import kamkeel.npcs.controllers.data.Profile; -import kamkeel.npcs.controllers.data.Slot; +import kamkeel.npcs.controllers.data.*; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.server.MinecraftServer; import noppes.npcs.CustomNpcs; +import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.LogWriter; +import noppes.npcs.NoppesUtilServer; +import noppes.npcs.api.entity.IPlayer; +import noppes.npcs.api.handler.IPlayerData; +import noppes.npcs.api.handler.data.IProfile; +import noppes.npcs.api.handler.IProfileHandler; +import noppes.npcs.api.handler.data.ISlot; +import noppes.npcs.config.ConfigMain; +import noppes.npcs.controllers.QuestController; import noppes.npcs.controllers.data.PlayerData; +import noppes.npcs.controllers.data.PlayerQuestData; import noppes.npcs.util.CustomNPCsThreader; import noppes.npcs.util.NBTJsonUtil; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStreamReader; -import java.io.IOException; +import java.io.*; import java.net.HttpURLConnection; import java.net.URL; -import java.util.HashMap; -import java.util.UUID; +import java.text.SimpleDateFormat; +import java.util.*; -public class ProfileController { +import static noppes.npcs.CustomNpcsPermissions.PROFILE_REGION_BYPASS; +import static noppes.npcs.CustomNpcsPermissions.hasPermission; - public static HashMap profileTypes; - public static HashMap activeProfiles; +public class ProfileController implements IProfileHandler { + + // Message constants + private static final String MSG_PLAYER_NOT_FOUND = "Player not found."; + private static final String MSG_PROFILE_LOCKED_CLONE = "Profile is locked; cannot clone slot."; + private static final String MSG_SOURCE_SLOT_NOT_EXIST = "Source slot does not exist."; + private static final String MSG_CANNOT_CLONE_CURRENT = "Cannot clone to the current active slot."; + private static final String MSG_INVALID_DEST_SLOT = "Invalid destination slot id."; + private static final String MSG_CLONE_SUCCESS = "Slot cloned successfully."; + private static final String MSG_PROFILE_LOCKED_REMOVE = "Profile is locked; cannot remove slot."; + private static final String MSG_CANNOT_REMOVE_ACTIVE = "Cannot remove the currently active slot."; + private static final String MSG_SLOT_NOT_EXIST = "Slot does not exist."; + private static final String MSG_REMOVE_SUCCESS = "Slot removed successfully."; + private static final String MSG_PROFILE_LOCKED_CREATE = "Profile is locked; cannot create slot."; + private static final String MSG_MAX_SLOTS_REACHED = "Maximum allowed slots reached."; + private static final String MSG_NEW_SLOT_CREATED = "New slot created successfully."; + private static final String MSG_PROFILE_LOCKED_CHANGE = "Profile is locked; cannot change slot."; + private static final String MSG_SLOT_ALREADY_ACTIVE = "Slot is already active."; + private static final String MSG_REGION_NOT_ALLOWED = "Profile switching not allowed from your current location."; + private static final String MSG_CHANGE_SUCCESS = "Slot changed successfully."; + + public static Map profileTypes = new HashMap<>(); + public static Map activeProfiles = new HashMap<>(); public static String profile_directory = "profiles"; - public ProfileController(){ + public static ProfileController Instance; + + public ProfileController() { + Instance = this; profileTypes = new HashMap<>(); activeProfiles = new HashMap<>(); } - // ---------- Registration & I/O ---------- - - public static boolean registerProfileType(IProfileData type){ - if(profileTypes.containsKey(type.getTagName())) + public static boolean registerProfileType(IProfileData type) { + if (profileTypes.containsKey(type.getTagName())) return false; profileTypes.put(type.getTagName(), type); return true; } - public static File getProfileDir(){ + public static File getProfileDir() { try { File file = new File(CustomNpcs.getWorldSaveDirectory(), profile_directory); - if(!file.exists()) + if (!file.exists()) file.mkdir(); return file; } catch (Exception e) { @@ -57,27 +81,48 @@ public class ProfileController { } } - // Login for online players - public static synchronized void login(EntityPlayer player){ - if(player == null) + public static File getBackupDir() { + File base = getProfileDir(); + File backup = new File(base, "backup"); + if (!backup.exists()) { + backup.mkdir(); + } + return backup; + } + + public synchronized void login(EntityPlayer player) { + if(!ConfigMain.ProfilesEnabled) + return; + + if (player == null) return; Profile profile; - if(activeProfiles.containsKey(player.getUniqueID())){ + if (activeProfiles.containsKey(player.getUniqueID())) { profile = activeProfiles.get(player.getUniqueID()); profile.player = player; } else { NBTTagCompound compound = load(player); profile = new Profile(player, compound); + if (profile.getSlots().isEmpty()) { + Slot defaultSlot = new Slot(0, "Default Slot"); + defaultSlot.setLastLoaded(System.currentTimeMillis()); + profile.getSlots().put(0, defaultSlot); + profile.currentSlotId = 0; + saveSlotData(player); + } + profile.player = player; activeProfiles.put(player.getUniqueID(), profile); + verifySlotQuests(profile.player); + save(player, profile); } } - public static synchronized NBTTagCompound load(EntityPlayer player) { + public synchronized NBTTagCompound load(EntityPlayer player) { File saveDir = getProfileDir(); String filename = player.getUniqueID().toString() + ".dat"; try { File file = new File(saveDir, filename); - if(file.exists()){ + if (file.exists()) { return NBTJsonUtil.loadNBTData(file); } } catch (Exception e) { @@ -86,12 +131,12 @@ public class ProfileController { return new NBTTagCompound(); } - public static synchronized NBTTagCompound load(UUID uuid) { + public synchronized NBTTagCompound load(UUID uuid) { File saveDir = getProfileDir(); String filename = uuid.toString() + ".dat"; try { File file = new File(saveDir, filename); - if(file.exists()){ + if (file.exists()) { return NBTJsonUtil.loadNBTData(file); } } catch (Exception e) { @@ -100,27 +145,31 @@ public class ProfileController { return new NBTTagCompound(); } - // Offline save (synchronous) when no EntityPlayer is available - public static synchronized void saveOffline(Profile profile, UUID uuid) { - final NBTTagCompound compound = profile.writeToNBT(); - final String filename = uuid.toString() + ".dat"; - try { - File saveDir = getProfileDir(); - File fileNew = new File(saveDir, filename + "_new"); - File fileOld = new File(saveDir, filename); - CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew)); - if(fileOld.exists()){ - fileOld.delete(); + public synchronized void saveOffline(Profile profile, UUID uuid) { + profile.setLocked(true); + CustomNPCsThreader.customNPCThread.execute(() -> { + final NBTTagCompound compound = profile.writeToNBT(); + final String filename = uuid.toString() + ".dat"; + try { + File saveDir = getProfileDir(); + File fileNew = new File(saveDir, filename + "_new"); + File fileOld = new File(saveDir, filename); + CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew)); + if (fileOld.exists()) { + fileOld.delete(); + } + fileNew.renameTo(fileOld); + backupProfile(uuid, compound); + } catch (Exception e) { + LogWriter.except(e); + } finally { + profile.setLocked(false); } - fileNew.renameTo(fileOld); - } catch (Exception e) { - LogWriter.except(e); - } + }); } - // Save for online players (asynchronous) - public static synchronized void save(EntityPlayer player, Profile profile) { - profile.locked = true; + public synchronized void save(EntityPlayer player, Profile profile) { + profile.setLocked(true); CustomNPCsThreader.customNPCThread.execute(() -> { final NBTTagCompound compound = profile.writeToNBT(); final String filename = player.getUniqueID() + ".dat"; @@ -129,58 +178,107 @@ public class ProfileController { File fileNew = new File(saveDir, filename + "_new"); File fileOld = new File(saveDir, filename); CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew)); - if(fileOld.exists()){ + if (fileOld.exists()) { fileOld.delete(); } fileNew.renameTo(fileOld); + if (ConfigMain.AllowProfileBackups) { + backupProfile(player.getUniqueID(), compound); + } } catch (Exception e) { LogWriter.except(e); } finally { - profile.locked = false; + profile.setLocked(false); } }); } - // Logout removes an active profile - public static synchronized void logout(EntityPlayer player) { - if(player != null) { + private void backupProfile(UUID uuid, NBTTagCompound compound) { + try { + File backupDir = new File(getBackupDir(), uuid.toString()); + if (!backupDir.exists()) { + backupDir.mkdirs(); + } + String dateStr = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + File backupFile = new File(backupDir, dateStr + ".dat"); + CompressedStreamTools.writeCompressed(compound, new FileOutputStream(backupFile)); + File[] backups = backupDir.listFiles((dir, name) -> name.endsWith(".dat")); + if (backups != null && backups.length > ConfigMain.ProfileBackupAmount) { + Arrays.sort(backups, Comparator.comparingLong(File::lastModified)); + for (int i = 0; i < backups.length - ConfigMain.ProfileBackupAmount; i++) { + backups[i].delete(); + } + } + } catch (Exception e) { + LogWriter.except(e); + } + } + + public boolean rollbackProfile(String username, File backupFile) { + UUID uuid = getUUIDFromUsername(username); + if (uuid == null) + return false; + try (FileInputStream fis = new FileInputStream(backupFile)) { + NBTTagCompound compound = CompressedStreamTools.readCompressed(fis); + File saveDir = getProfileDir(); + File mainFile = new File(saveDir, uuid.toString() + ".dat"); + File fileNew = new File(saveDir, uuid.toString() + "_new"); + CompressedStreamTools.writeCompressed(compound, new FileOutputStream(fileNew)); + if (mainFile.exists()) { + mainFile.delete(); + } + fileNew.renameTo(mainFile); + EntityPlayer player = NoppesUtilServer.getPlayerByName(username); + Profile newProfile; + if (player != null) { + newProfile = new Profile(player, compound); + activeProfiles.put(uuid, newProfile); + loadSlotData(player); + } else { + newProfile = new Profile(null, compound); + activeProfiles.put(uuid, newProfile); + } + return true; + } catch (Exception e) { + LogWriter.except(e); + return false; + } + } + + public synchronized void logout(EntityPlayer player) { + if (player != null) { activeProfiles.remove(player.getUniqueID()); } } - // ---------- Profile Retrieval Helpers ---------- - - // Get profile via EntityPlayer (online) - public static Profile getProfile(EntityPlayer player) { - if(player == null) return null; - if(!activeProfiles.containsKey(player.getUniqueID())) + public Profile getProfile(EntityPlayer player) { + if (player == null) + return null; + if (!activeProfiles.containsKey(player.getUniqueID())) login(player); return activeProfiles.get(player.getUniqueID()); } - // Get profile via UUID (may be offline) - public static Profile getProfile(UUID uuid) { - if(activeProfiles.containsKey(uuid)) + public Profile getProfile(UUID uuid) { + if (activeProfiles.containsKey(uuid)) return activeProfiles.get(uuid); NBTTagCompound compound = load(uuid); return new Profile(null, compound); } - // Get profile via username (tries online first, then offline via Mojang API) - public static Profile getProfile(String username) { - EntityPlayer player = getPlayer(username); - if(player != null) { + public Profile getProfile(String username) { + EntityPlayer player = NoppesUtilServer.getPlayerByName(username); + if (player != null) { return getProfile(player); } else { UUID uuid = getUUIDFromUsername(username); - if(uuid == null) return null; + if (uuid == null) + return null; return getProfile(uuid); } } - // ---------- Mojang API UUID Lookup ---------- - - public static UUID getUUIDFromUsername(String username) { + public UUID getUUIDFromUsername(String username) { try { URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username); HttpURLConnection con = (HttpURLConnection) url.openConnection(); @@ -190,13 +288,13 @@ public class ProfileController { BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); StringBuilder temp = new StringBuilder(); String line; - while((line = in.readLine()) != null){ + while ((line = in.readLine()) != null) { temp.append(line); } in.close(); con.disconnect(); String response = temp.toString(); - if(response.contains("\"id\"")) { + if (response.contains("\"id\"")) { int idIndex = response.indexOf("\"id\""); int colonIndex = response.indexOf(":", idIndex); int quoteStart = response.indexOf("\"", colonIndex); @@ -214,267 +312,481 @@ public class ProfileController { return null; } - // ---------- Internal Slot Operation Helpers ---------- - - // Returns the next available temporary (negative) slot id (starting at -1) - private static int getNextAvailableTempSlot(Profile profile) { + private int getNextAvailableTempSlot(Profile profile) { int id = -1; - while(profile.slots.containsKey(id)) { + while (profile.getSlots().containsKey(id)) { id--; } return id; } - // Clone a slot within a Profile. - // sourceSlotId is the slot to copy. - // destinationSlotId is the target id for non-temporary clones. - // If temporary==true, destinationSlotId is computed automatically. - private static ProfileOperation cloneSlotInternal(Profile profile, int sourceSlotId, int destinationSlotId, boolean temporary) { - if(profile.locked) { - LogWriter.error("Profile is locked; cannot clone slot."); - return ProfileOperation.LOCKED; + private ProfileOperation cloneSlotInternal(Profile profile, int sourceSlotId, int destinationSlotId, boolean temporary) { + if (profile.isLocked()) { + return ProfileOperation.locked(MSG_PROFILE_LOCKED_CLONE); } - if(!profile.slots.containsKey(sourceSlotId)) { - LogWriter.error("Source slot " + sourceSlotId + " does not exist."); - return ProfileOperation.ERROR; - } - if(destinationSlotId == profile.currentID) { - LogWriter.error("Cannot clone to the current active slot (" + profile.currentID + ")."); - return ProfileOperation.ERROR; - } - if(temporary) { - destinationSlotId = getNextAvailableTempSlot(profile); - } else { - if(destinationSlotId <= 0) { - LogWriter.error("Invalid destination slot id for a non-temporary clone."); - return ProfileOperation.ERROR; + if (profile.player != null) { + List dataList = new ArrayList<>(profileTypes.values()); + dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority)); + for (IProfileData pd : dataList) { + if (pd.verifySwitch(profile.player).getResult() != EnumProfileOperation.SUCCESS) { + return pd.verifySwitch(profile.player); + } } } - Slot sourceSlot = profile.slots.get(sourceSlotId); - NBTTagCompound clonedData = (NBTTagCompound) sourceSlot.getCompound().copy(); - Slot clonedSlot = new Slot(destinationSlotId, "Cloned Slot " + destinationSlotId, clonedData, System.currentTimeMillis(), temporary); - profile.slots.put(destinationSlotId, clonedSlot); - return ProfileOperation.SUCCESS; + if (!profile.getSlots().containsKey(sourceSlotId)) { + return ProfileOperation.error(MSG_SOURCE_SLOT_NOT_EXIST); + } + if (destinationSlotId == profile.getCurrentSlotId()) { + return ProfileOperation.error(MSG_CANNOT_CLONE_CURRENT); + } + if (temporary) { + destinationSlotId = getNextAvailableTempSlot(profile); + } else { + if (destinationSlotId <= 0) { + return ProfileOperation.error(MSG_INVALID_DEST_SLOT); + } + } + ISlot sourceSlot = profile.getSlots().get(sourceSlotId); + Map newComponents = new HashMap<>(); + for (String key : sourceSlot.getComponents().keySet()) { + newComponents.put(key, (NBTTagCompound) sourceSlot.getComponentData(key).copy()); + } + Slot clonedSlot = new Slot(destinationSlotId, "Cloned Slot " + destinationSlotId, System.currentTimeMillis(), temporary, newComponents); + profile.getSlots().put(destinationSlotId, clonedSlot); + return ProfileOperation.success(MSG_CLONE_SUCCESS); } - // Remove a slot from a Profile. - private static ProfileOperation removeSlotInternal(Profile profile, int slotId) { - if(profile.locked) { - LogWriter.error("Profile is locked; cannot remove slot."); - return ProfileOperation.LOCKED; + private ProfileOperation removeSlotInternal(Profile profile, int slotId) { + if (profile.isLocked()) { + return ProfileOperation.locked(MSG_PROFILE_LOCKED_REMOVE); } - if(slotId == profile.currentID) { - LogWriter.error("Cannot remove the currently active slot (" + profile.currentID + ")."); - return ProfileOperation.ERROR; + if (slotId == profile.getCurrentSlotId()) { + return ProfileOperation.error(MSG_CANNOT_REMOVE_ACTIVE); } - if(!profile.slots.containsKey(slotId)) { - LogWriter.error("Slot " + slotId + " does not exist."); - return ProfileOperation.ERROR; + if (!profile.getSlots().containsKey(slotId)) { + return ProfileOperation.error(MSG_SLOT_NOT_EXIST); } - profile.slots.remove(slotId); - return ProfileOperation.SUCCESS; + profile.getSlots().remove(slotId); + return ProfileOperation.success(MSG_REMOVE_SUCCESS); } - // Change the active slot in a Profile. - // Saves current slot data before switching. - private static ProfileOperation changeSlotInternal(Profile profile, int newSlotId) { - if(profile.locked) { - LogWriter.error("Profile is locked; cannot change slot."); - return ProfileOperation.LOCKED; + public ProfileOperation createSlotInternal(Profile profile) { + if (profile.isLocked()) { + return ProfileOperation.locked(MSG_PROFILE_LOCKED_CREATE); } - if(profile.player != null) + int newSlotId = 0; + while (profile.getSlots().containsKey(newSlotId)) { + newSlotId++; + } + if (!allowSlotPermission(profile.player)) { + return ProfileOperation.error(MSG_MAX_SLOTS_REACHED); + } + if (profile.player != null) { + List dataList = new ArrayList<>(profileTypes.values()); + dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority)); + for (IProfileData pd : dataList) { + if (pd.verifySwitch(profile.player).getResult() != EnumProfileOperation.SUCCESS) { + return pd.verifySwitch(profile.player); + } + } + } + Slot newSlot = new Slot(newSlotId, "Slot " + newSlotId); + newSlot.setLastLoaded(System.currentTimeMillis()); + profile.getSlots().put(newSlotId, newSlot); + if(profile.player != null){ + verifySlotQuests(profile.player); + save(profile.player, profile); + } + return ProfileOperation.success(MSG_NEW_SLOT_CREATED); + } + + private ProfileOperation changeSlotInternal(Profile profile, int newSlotId) { + if (profile.isLocked()) { + return ProfileOperation.locked(MSG_PROFILE_LOCKED_CHANGE); + } + if (profile.getCurrentSlotId() == newSlotId) { + return ProfileOperation.error(MSG_SLOT_ALREADY_ACTIVE); + } + if (!profile.getSlots().containsKey(newSlotId)) { + return ProfileOperation.error(MSG_SLOT_NOT_EXIST); + } + if (profile.player != null) { + if (ConfigMain.RegionProfileSwitching) { + boolean allowed = hasPermission(profile.player, PROFILE_REGION_BYPASS); + if (!allowed) { + int playerDim = profile.player.dimension; + int playerX = (int) profile.player.posX; + int playerY = (int) profile.player.posY; + int playerZ = (int) profile.player.posZ; + for (List region : ConfigMain.RestrictedProfileRegions) { + if (region.size() == 7) { + int dim = region.get(0); + int x1 = Math.min(region.get(1), region.get(4)); + int y1 = Math.min(region.get(2), region.get(5)); + int z1 = Math.min(region.get(3), region.get(6)); + int x2 = Math.max(region.get(1), region.get(4)); + int y2 = Math.max(region.get(2), region.get(5)); + int z2 = Math.max(region.get(3), region.get(6)); + if (playerDim == dim && + playerX >= x1 && playerX <= x2 && + playerY >= y1 && playerY <= y2 && + playerZ >= z1 && playerZ <= z2) { + allowed = true; + break; + } + } + } + } + if (!allowed) { + return ProfileOperation.error(MSG_REGION_NOT_ALLOWED); + } + } + List dataList = new ArrayList<>(profileTypes.values()); + dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority)); + for (IProfileData pd : dataList) { + if (pd.verifySwitch(profile.player).getResult() != EnumProfileOperation.SUCCESS) { + return pd.verifySwitch(profile.player); + } + } saveSlotData(profile.player); - // If the new slot doesn't exist, create it. - if(!profile.slots.containsKey(newSlotId)) { - Slot newSlot = new Slot(newSlotId, "Slot " + newSlotId); - newSlot.setCompound(new NBTTagCompound()); - profile.slots.put(newSlotId, newSlot); - } - - profile.currentID = newSlotId; - if(profile.player != null) + profile.currentSlotId = newSlotId; loadSlotData(profile.player); - - // Update PlayerData so that PlayerData.get(player).profileSlot matches Profile.currentID - if(profile.player != null) { PlayerData pdata = PlayerData.get(profile.player); pdata.profileSlot = newSlotId; pdata.save(); - } - return ProfileOperation.SUCCESS; - } - - // ---------- Public Operations (Overloaded for EntityPlayer, UUID, or username) ---------- - - // ----- Clone Slot ----- - public static ProfileOperation cloneSlot(EntityPlayer player, int sourceSlotId, int destinationSlotId, boolean temporary) { - Profile profile = getProfile(player); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary); - if(result == ProfileOperation.SUCCESS && player != null) - save(player, profile); - return result; - } - - public static ProfileOperation cloneSlot(UUID uuid, int sourceSlotId, int destinationSlotId, boolean temporary) { - Profile profile = getProfile(uuid); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary); - if(result == ProfileOperation.SUCCESS) { - if(profile.player != null) - save(profile.player, profile); - else - saveOffline(profile, uuid); - } - return result; - } - - public static ProfileOperation cloneSlot(String username, int sourceSlotId, int destinationSlotId, boolean temporary) { - Profile profile = getProfile(username); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary); - if(result == ProfileOperation.SUCCESS) { - if(profile.player != null) - save(profile.player, profile); - else { - UUID uuid = getUUIDFromUsername(username); - if(uuid != null) - saveOffline(profile, uuid); - } - } - return result; - } - - // ----- Remove Slot ----- - public static ProfileOperation removeSlot(EntityPlayer player, int slotId) { - Profile profile = getProfile(player); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = removeSlotInternal(profile, slotId); - if(result == ProfileOperation.SUCCESS && player != null) - save(player, profile); - return result; - } - - public static ProfileOperation removeSlot(UUID uuid, int slotId) { - Profile profile = getProfile(uuid); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = removeSlotInternal(profile, slotId); - if(result == ProfileOperation.SUCCESS) { - if(profile.player != null) - save(profile.player, profile); - else - saveOffline(profile, uuid); - } - return result; - } - - public static ProfileOperation removeSlot(String username, int slotId) { - Profile profile = getProfile(username); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = removeSlotInternal(profile, slotId); - if(result == ProfileOperation.SUCCESS) { - if(profile.player != null) - save(profile.player, profile); - else { - UUID uuid = getUUIDFromUsername(username); - if(uuid != null) - saveOffline(profile, uuid); - } - } - return result; - } - - // ----- Change Slot ----- - public static ProfileOperation changeSlot(EntityPlayer player, int newSlotId) { - Profile profile = getProfile(player); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = changeSlotInternal(profile, newSlotId); - if(result == ProfileOperation.SUCCESS && player != null) - save(player, profile); - return result; - } - - public static ProfileOperation changeSlot(UUID uuid, int newSlotId) { - Profile profile = getProfile(uuid); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = changeSlotInternal(profile, newSlotId); - if(result == ProfileOperation.SUCCESS) { - if(profile.player != null) - save(profile.player, profile); - else - saveOffline(profile, uuid); - } - return result; - } - - public static ProfileOperation changeSlot(String username, int newSlotId) { - Profile profile = getProfile(username); - if(profile == null) return ProfileOperation.PLAYER_NOT_FOUND; - ProfileOperation result = changeSlotInternal(profile, newSlotId); - if(result == ProfileOperation.SUCCESS) { - if(profile.player != null) - save(profile.player, profile); - else { - UUID uuid = getUUIDFromUsername(username); - if(uuid != null) - saveOffline(profile, uuid); - } - } - return result; - } - - // ---------- Saving current slot data (used before switching) ---------- - public static void saveSlotData(EntityPlayer player){ - if(player == null || !activeProfiles.containsKey(player.getUniqueID())) - return; - Profile profile = activeProfiles.get(player.getUniqueID()); - if(profile.locked) { - LogWriter.error("Profile is locked; cannot save slot data."); - return; - } - NBTTagCompound dataCompound; - Slot slot; - if(!profile.slots.isEmpty() && profile.slots.containsKey(profile.currentID)){ - slot = profile.slots.get(profile.currentID); - dataCompound = (NBTTagCompound) slot.getCompound().copy(); } else { - slot = new Slot(profile.currentID, "Slot " + profile.currentID); - dataCompound = new NBTTagCompound(); - slot.setCompound(dataCompound); + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); } - for(IProfileData profileData : profileTypes.values()){ - NBTTagCompound cloned = (NBTTagCompound) profileData.getCurrentNBT(player).copy(); - dataCompound.setTag(profileData.getTagName(), cloned); - } - slot.setCompound(dataCompound); + return ProfileOperation.success(MSG_CHANGE_SUCCESS); } - // TODO: - public static void loadSlotData(EntityPlayer player) { - if(player == null || !activeProfiles.containsKey(player.getUniqueID())) - return; + public ProfileOperation cloneSlot(EntityPlayer player, int sourceSlotId, int destinationSlotId, boolean temporary) { + Profile profile = getProfile(player); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary); + if (result.getResult() == EnumProfileOperation.SUCCESS && player != null) { + save(player, profile); + } + return result; + } + public ProfileOperation cloneSlot(UUID uuid, int sourceSlotId, int destinationSlotId, boolean temporary) { + Profile profile = getProfile(uuid); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary); + if (result.getResult() == EnumProfileOperation.SUCCESS) { + if (profile.player != null) + save(profile.player, profile); + else + saveOffline(profile, uuid); + } + return result; + } + + public ProfileOperation cloneSlot(String username, int sourceSlotId, int destinationSlotId, boolean temporary) { + Profile profile = getProfile(username); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = cloneSlotInternal(profile, sourceSlotId, destinationSlotId, temporary); + if (result.getResult() == EnumProfileOperation.SUCCESS) { + if (profile.player != null) + save(profile.player, profile); + else { + UUID uuid = getUUIDFromUsername(username); + if (uuid != null) + saveOffline(profile, uuid); + } + } + return result; + } + + public ProfileOperation removeSlot(EntityPlayer player, int slotId) { + Profile profile = getProfile(player); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = removeSlotInternal(profile, slotId); + if (result.getResult() == EnumProfileOperation.SUCCESS && player != null) { + save(player, profile); + } + return result; + } + + public ProfileOperation removeSlot(String username, int slotId) { + Profile profile = getProfile(username); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = removeSlotInternal(profile, slotId); + if (result.getResult() == EnumProfileOperation.SUCCESS) { + if (profile.player != null) + save(profile.player, profile); + else { + UUID uuid = getUUIDFromUsername(username); + if (uuid != null) + saveOffline(profile, uuid); + } + } + return result; + } + + public ProfileOperation changeSlot(EntityPlayer player, int newSlotId) { + Profile profile = getProfile(player); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = changeSlotInternal(profile, newSlotId); + if (result.getResult() == EnumProfileOperation.SUCCESS && player != null) + save(player, profile); + return result; + } + + public ProfileOperation changeSlot(String username, int newSlotId) { + Profile profile = getProfile(username); + if (profile == null) + return ProfileOperation.error(MSG_PLAYER_NOT_FOUND); + ProfileOperation result = changeSlotInternal(profile, newSlotId); + if (result.getResult() == EnumProfileOperation.SUCCESS) { + if (profile.player != null) + save(profile.player, profile); + else { + UUID uuid = getUUIDFromUsername(username); + if (uuid != null) + saveOffline(profile, uuid); + } + } + return result; + } + + public void saveSlotData(EntityPlayer player) { + if (player == null || !activeProfiles.containsKey(player.getUniqueID())) + return; Profile profile = activeProfiles.get(player.getUniqueID()); - if(profile.slots.isEmpty() || !profile.slots.containsKey(profile.currentID)) + if (profile.isLocked()) { return; + } + ISlot slot = profile.getSlots().get(profile.getCurrentSlotId()); + if (slot == null) { + slot = new Slot(profile.getCurrentSlotId(), "Slot " + profile.getCurrentSlotId()); + profile.getSlots().put(profile.getCurrentSlotId(), slot); + } + for (IProfileData profileData : profileTypes.values()) { + NBTTagCompound cloned = (NBTTagCompound) profileData.getCurrentNBT(player).copy(); + slot.setComponentData(profileData.getTagName(), cloned); + } + slot.setLastLoaded(System.currentTimeMillis()); + } - // Get a copy of the active slot's NBT compound. - NBTTagCompound slotCompound = (NBTTagCompound) profile.slots.get(profile.currentID).getCompound().copy(); - - // For each registered profile data type, load its saved compound onto the player. - for(IProfileData profileData : profileTypes.values()){ + public void loadSlotData(EntityPlayer player) { + if (player == null || !activeProfiles.containsKey(player.getUniqueID())) + return; + Profile profile = activeProfiles.get(player.getUniqueID()); + ISlot slot = profile.getSlots().get(profile.getCurrentSlotId()); + if (slot == null) + return; + for (IProfileData profileData : profileTypes.values()) { NBTTagCompound data; - if(slotCompound.hasKey(profileData.getTagName())) - data = slotCompound.getCompoundTag(profileData.getTagName()); + if (slot.getComponents().containsKey(profileData.getTagName())) + data = slot.getComponentData(profileData.getTagName()); else data = new NBTTagCompound(); - profileData.setNBT(player, data); + } + for (IProfileData profileData : profileTypes.values()) { profileData.save(player); } } - public static EntityPlayerMP getPlayer(String username){ - return MinecraftServer.getServer().getConfigurationManager().func_152612_a(username); + public List getProfileInfo(EntityPlayer player, int slotId) { + List infoList = new ArrayList<>(); + Profile profile = getProfile(player); + if (profile == null) + return infoList; + + List dataList = new ArrayList<>(profileTypes.values()); + dataList.sort(Comparator.comparingInt(IProfileData::getSwitchPriority)); + if (slotId == profile.getCurrentSlotId()) { + for (IProfileData pd : dataList) { + NBTTagCompound currentNBT = pd.getCurrentNBT(player); + List subInfo = pd.getInfo(player, currentNBT); + infoList.addAll(subInfo); + } + } else { + if (!profile.getSlots().containsKey(slotId)) + return infoList; + ISlot slot = profile.getSlots().get(slotId); + for (IProfileData pd : dataList) { + if (slot.getComponents().containsKey(pd.getTagName())) { + NBTTagCompound sub = slot.getComponentData(pd.getTagName()); + List subInfo = pd.getInfo(player, sub); + infoList.addAll(subInfo); + } + } + } + return infoList; + } + + public boolean allowSlotPermission(EntityPlayer player) { + Profile profile = getProfile(player); + int currentSlots = profile.getSlots().size(); + if (CustomNpcsPermissions.hasCustomPermission(player, "customnpcs.profile.max.*")) { + return true; + } + int highestAllowed = 0; + for (int i = 1; i <= 50; i++) { + String perm = "customnpcs.profile.max." + i; + if (CustomNpcsPermissions.hasCustomPermission(player, perm)) { + highestAllowed = i; + } + } + if (highestAllowed == 0) { + highestAllowed = 1; + } + return currentSlots < highestAllowed; + } + + @Override + public IProfile getProfile(IPlayer player) { + if(player == null || player.getMCEntity() == null) + return null; + return getProfile((EntityPlayer) player.getMCEntity()); + } + + @Override + public boolean changeSlot(IPlayer player, int slotID) { + if(player == null || player.getMCEntity() == null) + return false; + + EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity(); + ProfileOperation profileOperation = changeSlot(entityPlayer, slotID); + return profileOperation.getResult() == EnumProfileOperation.SUCCESS; + } + + @Override + public boolean hasSlot(IPlayer player, int slotID) { + if(player == null || player.getMCEntity() == null) + return false; + + EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity(); + Profile profile = getProfile(entityPlayer); + if(profile == null) + return false; + return profile.getSlots().containsKey(slotID); + } + + @Override + public boolean removeSlot(IPlayer player, int slotID) { + if(player == null || player.getMCEntity() == null) + return false; + + EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity(); + ProfileOperation profileOperation = removeSlot(entityPlayer, slotID); + return profileOperation.getResult() == EnumProfileOperation.SUCCESS; + } + + @Override + public IPlayerData getSlotPlayerData(IPlayer player, int slotID) { + PlayerData playerData; + if(player == null || player.getMCEntity() == null) + return null; + + EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity(); + Profile profile = getProfile(entityPlayer); + if(profile == null) + return null; + return getSlotPlayerData(entityPlayer, slotID); + } + + @Override + public void saveSlotData(IPlayer player) { + if(player == null || player.getMCEntity() == null) + return; + + EntityPlayer entityPlayer = (EntityPlayer) player.getMCEntity(); + saveSlotData(entityPlayer); + } + + public IPlayerData getSlotPlayerData(EntityPlayer player, int slotID) { + PlayerData playerData; + Profile profile = getProfile(player); + if(profile == null) + return null; + + if(profile.currentSlotId == slotID){ + playerData = PlayerData.get(player); + } else { + Slot slot = (Slot) profile.getSlots().get(slotID); + playerData = getSlotPlayerData(player, slot); + } + return playerData; + } + + public PlayerData getSlotPlayerData(EntityPlayer player, Slot slot) { + if(slot == null) + return null; + + PlayerData playerData = new PlayerData(); + playerData.player = player; + + NBTTagCompound compound = slot.getComponentData(new CNPCData().getTagName()); + if(compound == null) + compound = new NBTTagCompound(); + playerData.setNBT(compound); + return playerData; + } + + public void verifySlotQuests(EntityPlayer player) { + Profile profile = getProfile(player); + if (profile == null) { + return; + } + + Map universalFinished = new HashMap<>(); + for (Integer questId : QuestController.Instance.sharedQuests.keySet()) { + long maxTime = 0; + for (ISlot slot : profile.getSlots().values()) { + IPlayerData data = getSlotPlayerData(player, slot.getId()); + if (data == null) { + continue; + } + PlayerQuestData questData = (PlayerQuestData) data.getQuestData(); + Long t = questData.finishedQuests.get(questId); + if (t != null && t > maxTime) { + maxTime = t; + } + } + if (maxTime > 0) { + universalFinished.put(questId, maxTime); + } + } + + // Push the universal shared completion times into every slot. + for (ISlot slot : profile.getSlots().values()) { + IPlayerData data = getSlotPlayerData(player, slot.getId()); + if (data != null) { + PlayerData playerData = (PlayerData) data; + PlayerQuestData questData = (PlayerQuestData) data.getQuestData(); + questData.finishedQuests.putAll(universalFinished); + slot.setComponentData(new CNPCData().getTagName(), playerData.getNBT()); + } + } + } + + public void shareQuestCompletion(EntityPlayer player, int questId, long completeTime) { + Profile profile = getProfile(player); + if (profile == null) { + return; + } + for (ISlot slot : profile.getSlots().values()) { + IPlayerData playerData = getSlotPlayerData(player, slot.getId()); + if (playerData != null) { + PlayerQuestData questData = (PlayerQuestData) playerData.getQuestData(); + Long existing = questData.finishedQuests.get(questId); + if (existing == null || completeTime > existing) { + questData.finishedQuests.put(questId, completeTime); + } + playerData.save(); + } + } + save(player, profile); } } diff --git a/src/main/java/kamkeel/npcs/controllers/SyncController.java b/src/main/java/kamkeel/npcs/controllers/SyncController.java index 1b936cd9b..153b79d76 100644 --- a/src/main/java/kamkeel/npcs/controllers/SyncController.java +++ b/src/main/java/kamkeel/npcs/controllers/SyncController.java @@ -4,10 +4,11 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.addon.DBCAddon; import kamkeel.npcs.network.PacketHandler; -import kamkeel.npcs.network.packets.data.large.SyncEffectPacket; -import kamkeel.npcs.network.packets.data.large.SyncPacket; import kamkeel.npcs.network.enums.EnumSyncAction; import kamkeel.npcs.network.enums.EnumSyncType; +import kamkeel.npcs.network.packets.data.LoginPacket; +import kamkeel.npcs.network.packets.data.large.SyncEffectPacket; +import kamkeel.npcs.network.packets.data.large.SyncPacket; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; @@ -17,12 +18,15 @@ import noppes.npcs.controllers.*; import noppes.npcs.controllers.data.*; import java.util.HashMap; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class SyncController { public static void syncPlayer(EntityPlayerMP player){ + + // Login Packet + PacketHandler.Instance.sendToPlayer(new LoginPacket(), player); + // 1) Factions PacketHandler.Instance.sendToPlayer(new SyncPacket( EnumSyncType.FACTION, diff --git a/src/main/java/kamkeel/npcs/controllers/data/CNPCData.java b/src/main/java/kamkeel/npcs/controllers/data/CNPCData.java index d4e61530f..9da19b00f 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/CNPCData.java +++ b/src/main/java/kamkeel/npcs/controllers/data/CNPCData.java @@ -6,11 +6,14 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.controllers.data.PlayerData; +import java.util.ArrayList; +import java.util.List; + public class CNPCData implements IProfileData { @Override public String getTagName() { - return "CustomNPC+"; + return "CNPC+"; } @Override @@ -39,4 +42,31 @@ public class CNPCData implements IProfileData { } customNPCData.updateClient = true; } + + @Override + public int getSwitchPriority() { + return 0; + } + + @Override + public ProfileOperation verifySwitch(EntityPlayer player) { + PlayerData playerData = PlayerData.get(player); + if(playerData.partyUUID != null) + return ProfileOperation.error("Cannot switch while in Party"); + + return ProfileOperation.success(""); + } + + @Override + public List getInfo(EntityPlayer player, NBTTagCompound compound) { + PlayerData playerData = new PlayerData(); + playerData.player = player; + playerData.setNBT(compound); + + List info = new ArrayList<>(); + info.add(new InfoEntry("profile.info.quest.finished", 0x60fa57, playerData.questData.finishedQuests.size(), 0xFFFFFF)); + info.add(new InfoEntry("profile.info.quest.active", 0xf75336, playerData.questData.activeQuests.size(), 0xFFFFFF)); + info.add(new InfoEntry("profile.info.dialog.read", 0x47acf5, playerData.dialogData.dialogsRead.size(), 0xFFFFFF)); + return info; + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/EnumProfileOperation.java b/src/main/java/kamkeel/npcs/controllers/data/EnumProfileOperation.java new file mode 100644 index 000000000..b4c10d3ec --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/EnumProfileOperation.java @@ -0,0 +1,7 @@ +package kamkeel.npcs.controllers.data; + +public enum EnumProfileOperation { + SUCCESS, + ERROR, + LOCKED +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/IProfileData.java b/src/main/java/kamkeel/npcs/controllers/data/IProfileData.java index a68abc597..b84af3d7d 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/IProfileData.java +++ b/src/main/java/kamkeel/npcs/controllers/data/IProfileData.java @@ -3,27 +3,50 @@ package kamkeel.npcs.controllers.data; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import java.util.List; + public interface IProfileData { /** - * Do not use the tag: - Name, lastLoaded, ID - * - * @return The Save Tag utilized in the Profile + * Do not use the tags: Name, lastLoaded, ID. + * @return The save tag utilized in the Profile. */ public String getTagName(); /** - * @return NBTTagCompound of their Current Data for a given Entity Player + * @return NBTTagCompound of the current data for a given EntityPlayer. */ public NBTTagCompound getCurrentNBT(EntityPlayer player); /** - * Called immediately after setNBT() Replaces existing NBT + * Called immediately after setNBT() to replace existing NBT. */ public void save(EntityPlayer player); /** - * Replaces their Current Data operation when changing Profiles + * Replaces the current data operation when changing profiles. */ public void setNBT(EntityPlayer player, NBTTagCompound replace); + + /** + * Returns the priority for this ProfileData's verification check. + * Lower numbers run first. + */ + public int getSwitchPriority(); + + /** + * Called before a profile switch occurs. + * @param player The player switching profiles. + * @return true if allowed, false if not. + */ + public ProfileOperation verifySwitch(EntityPlayer player); + + /** + * NEW: Builds and returns a list of informational strings about this profile data, + * based on the provided NBTTagCompound from the slot. + * @param player The player in question. + * @param compound The NBT data from the slot under this profile data's tag. + * @return A list of InfoEntry with information + */ + public List getInfo(EntityPlayer player, NBTTagCompound compound); } diff --git a/src/main/java/kamkeel/npcs/controllers/data/InfoEntry.java b/src/main/java/kamkeel/npcs/controllers/data/InfoEntry.java new file mode 100644 index 000000000..7a8f29991 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/InfoEntry.java @@ -0,0 +1,50 @@ +package kamkeel.npcs.controllers.data; + +import net.minecraft.nbt.NBTTagCompound; + +public class InfoEntry { + private String label; + private String result; + private int labelColor; + private int resultColor; + + public InfoEntry() {} + + public InfoEntry(String label, int labelColor, String result, int resultColor) { + this.label = label; + this.result = result; + this.labelColor = labelColor; + this.resultColor = resultColor; + } + + public InfoEntry(String label, int labelColor, int result, int resultColor) { + this(label, labelColor, String.valueOf(result), resultColor); + } + + public InfoEntry(String label, String result) { + this(label, 0xFFFFFF, result, 0xFFFFFF); + } + + public NBTTagCompound writeToNBT() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setString("Label", label); + tag.setInteger("LabelColor", labelColor); + tag.setString("Result", result); + tag.setInteger("ResultColor", resultColor); + return tag; + } + + public static InfoEntry readFromNBT(NBTTagCompound tag) { + return new InfoEntry( + tag.getString("Label"), + tag.getInteger("LabelColor"), + tag.getString("Result"), + tag.getInteger("ResultColor") + ); + } + + public String getLabel() { return label; } + public String getResult() { return result; } + public int getLabelColor() { return labelColor; } + public int getResultColor() { return resultColor; } +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/Profile.java b/src/main/java/kamkeel/npcs/controllers/data/Profile.java index 502bea91a..d1be4fd40 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/Profile.java +++ b/src/main/java/kamkeel/npcs/controllers/data/Profile.java @@ -2,56 +2,91 @@ package kamkeel.npcs.controllers.data; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.NoppesUtilServer; +import noppes.npcs.api.entity.IPlayer; +import noppes.npcs.api.handler.data.IProfile; +import noppes.npcs.api.handler.data.ISlot; import java.util.HashMap; +import java.util.Map; import java.util.Set; -public class Profile { - +public class Profile implements IProfile { public EntityPlayer player; - public int currentID; - public HashMap slots = new HashMap<>(); - public boolean locked = false; // Prevent modifications while saving + public int currentSlotId; + private Map slots = new HashMap<>(); + private boolean locked = false; - public Profile(EntityPlayer player, NBTTagCompound compound){ + public Profile(EntityPlayer player, NBTTagCompound compound) { this.player = player; - if(compound.hasKey("CurrentID")){ - this.currentID = compound.getInteger("CurrentID"); + if(compound.hasKey("CurrentSlotId")){ + this.currentSlotId = compound.getInteger("CurrentSlotId"); } else { - this.currentID = 0; + this.currentSlotId = 0; } - if (compound.hasKey("Slots")) { + if(compound.hasKey("Slots")){ NBTTagCompound slotsCompound = compound.getCompoundTag("Slots"); - for (String key : (Set) slotsCompound.func_150296_c()) { - int slotID = Integer.parseInt(key); - NBTTagCompound slotNBT = slotsCompound.getCompoundTag(key); - Slot slot = Slot.fromNBT(slotID, slotNBT); - slots.put(slotID, slot); + Set keys = slotsCompound.func_150296_c(); + for(String key : keys) { + try { + int slotId = Integer.parseInt(key); + NBTTagCompound slotNBT = slotsCompound.getCompoundTag(key); + ISlot slot = Slot.fromNBT(slotId, slotNBT); + slots.put(slotId, slot); + } catch (NumberFormatException e) { + // Skip keys that are not valid slot IDs. + } } } } + public Profile(EntityPlayer player) { + this.player = player; + this.currentSlotId = 0; + // Create a default slot. + Slot defaultSlot = new Slot(0, "Default Slot"); + defaultSlot.setLastLoaded(System.currentTimeMillis()); + slots.put(0, defaultSlot); + } + + @Override + public IPlayer getPlayer() { + return NoppesUtilServer.getIPlayer(player); + } + + @Override + public int getCurrentSlotId() { + return currentSlotId; + } + + @Override + public Map getSlots() { + return slots; + } + + public boolean isLocked() { + return locked; + } + + public void setLocked(boolean locked) { + this.locked = locked; + } + + @Override public NBTTagCompound writeToNBT() { - NBTTagCompound fullCompound = new NBTTagCompound(); - - if(this.player != null) - fullCompound.setString("Name", player.getCommandSenderName()); - fullCompound.setInteger("CurrentID", currentID); - - if(!slots.isEmpty()){ - NBTTagCompound slotsCompound = new NBTTagCompound(); - for (HashMap.Entry entry : slots.entrySet()) { - Slot slot = entry.getValue(); - if(slot.isTemporary()) - continue; // Do not save temporary slots - int id = entry.getKey(); - slot.setId(id); - NBTTagCompound slotTag = slot.toNBT(); - slotsCompound.setTag(String.valueOf(id), slotTag); - } - fullCompound.setTag("Slots", slotsCompound); + NBTTagCompound compound = new NBTTagCompound(); + if(player != null) + compound.setString("Name", player.getCommandSenderName()); + compound.setInteger("CurrentSlotId", currentSlotId); + NBTTagCompound slotsCompound = new NBTTagCompound(); + for(Map.Entry entry : slots.entrySet()) { + // Save only non-temporary slots. + if(entry.getValue().isTemporary()) + continue; + slotsCompound.setTag(String.valueOf(entry.getKey()), entry.getValue().toNBT()); } - return fullCompound; + compound.setTag("Slots", slotsCompound); + return compound; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ProfileOperation.java b/src/main/java/kamkeel/npcs/controllers/data/ProfileOperation.java index 62ec9508a..7c3844794 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ProfileOperation.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ProfileOperation.java @@ -1,8 +1,31 @@ package kamkeel.npcs.controllers.data; -public enum ProfileOperation { - SUCCESS, - ERROR, - LOCKED, - PLAYER_NOT_FOUND +public class ProfileOperation { + private final EnumProfileOperation result; + private final String message; + + public ProfileOperation(EnumProfileOperation result, String message) { + this.result = result; + this.message = message; + } + + public EnumProfileOperation getResult() { + return result; + } + + public String getMessage() { + return message; + } + + public static ProfileOperation success(String message) { + return new ProfileOperation(EnumProfileOperation.SUCCESS, message); + } + + public static ProfileOperation error(String message) { + return new ProfileOperation(EnumProfileOperation.ERROR, message); + } + + public static ProfileOperation locked(String message) { + return new ProfileOperation(EnumProfileOperation.LOCKED, message); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/Slot.java b/src/main/java/kamkeel/npcs/controllers/data/Slot.java index 9b3c5dd97..6c74b47c3 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/Slot.java +++ b/src/main/java/kamkeel/npcs/controllers/data/Slot.java @@ -1,74 +1,114 @@ package kamkeel.npcs.controllers.data; import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.api.handler.data.ISlot; -public class Slot { +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +public class Slot implements ISlot { private int id; private String name; private long lastLoaded; - private NBTTagCompound compound; - private boolean temporary = false; + private boolean temporary; + private Map components = new HashMap<>(); public Slot(int id, String name) { this.id = id; this.name = name; } - public Slot(int id, String name, NBTTagCompound compound, long last, boolean temporary) { + public Slot(int id, String name, long lastLoaded, boolean temporary, Map components) { this.id = id; this.name = name; - this.compound = compound; - this.lastLoaded = last; + this.lastLoaded = lastLoaded; this.temporary = temporary; + this.components = components; } - // Getters and setters + @Override public int getId() { return id; } + public void setId(int id) { this.id = id; } + + @Override public String getName() { return name; } + + @Override public void setName(String name) { this.name = name; } + + @Override public long getLastLoaded() { return lastLoaded; } - public void setLastLoaded(long lastLoaded) { - this.lastLoaded = lastLoaded; - } - public NBTTagCompound getCompound() { - return compound; - } - public void setCompound(NBTTagCompound compound) { - this.compound = compound; + + @Override + public void setLastLoaded(long time) { + this.lastLoaded = time; } + + @Override public boolean isTemporary() { return temporary; } + + @Override public void setTemporary(boolean temporary) { this.temporary = temporary; } + @Override + public Map getComponents() { + return components; + } + + @Override + public void setComponentData(String key, NBTTagCompound data) { + components.put(key, data); + } + + @Override + public NBTTagCompound getComponentData(String key) { + return components.get(key); + } + + @Override public NBTTagCompound toNBT() { NBTTagCompound slotNBT = new NBTTagCompound(); slotNBT.setString("Name", name); slotNBT.setLong("LastLoaded", lastLoaded); - slotNBT.setTag("Data", compound); slotNBT.setBoolean("Temporary", temporary); + NBTTagCompound compCompound = new NBTTagCompound(); + for (Map.Entry entry : components.entrySet()) { + compCompound.setTag(entry.getKey(), entry.getValue()); + } + slotNBT.setTag("Components", compCompound); return slotNBT; } public static Slot fromNBT(int id, NBTTagCompound slotNBT) { String name = slotNBT.getString("Name"); long lastLoaded = slotNBT.getLong("LastLoaded"); - NBTTagCompound compound = slotNBT.getCompoundTag("Data"); - boolean temporary = slotNBT.hasKey("Temporary") && slotNBT.getBoolean("Temporary"); - return new Slot(id, name, compound, lastLoaded, temporary); + boolean temporary = slotNBT.getBoolean("Temporary"); + Slot slot = new Slot(id, name); + slot.setLastLoaded(lastLoaded); + slot.setTemporary(temporary); + if (slotNBT.hasKey("Components")) { + NBTTagCompound compCompound = slotNBT.getCompoundTag("Components"); + Set keys = compCompound.func_150296_c(); + for (String key : keys) { + slot.setComponentData(key, compCompound.getCompoundTag(key)); + } + } + return slot; } } diff --git a/src/main/java/kamkeel/npcs/network/LargeAbstractPacket.java b/src/main/java/kamkeel/npcs/network/LargeAbstractPacket.java index 30941b233..c55e391f1 100644 --- a/src/main/java/kamkeel/npcs/network/LargeAbstractPacket.java +++ b/src/main/java/kamkeel/npcs/network/LargeAbstractPacket.java @@ -5,7 +5,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import net.minecraft.entity.player.EntityPlayer; import noppes.npcs.LogWriter; -import org.lwjgl.Sys; import java.io.IOException; import java.util.ArrayList; diff --git a/src/main/java/kamkeel/npcs/network/PacketHandler.java b/src/main/java/kamkeel/npcs/network/PacketHandler.java index 67003b53b..52c73929c 100644 --- a/src/main/java/kamkeel/npcs/network/PacketHandler.java +++ b/src/main/java/kamkeel/npcs/network/PacketHandler.java @@ -53,9 +53,8 @@ import kamkeel.npcs.network.packets.request.npc.*; import kamkeel.npcs.network.packets.request.party.*; import kamkeel.npcs.network.packets.request.pather.MovingPathGetPacket; import kamkeel.npcs.network.packets.request.pather.MovingPathSavePacket; -import kamkeel.npcs.network.packets.request.playerdata.PlayerDataGetPacket; -import kamkeel.npcs.network.packets.request.playerdata.PlayerDataMapRegenPacket; -import kamkeel.npcs.network.packets.request.playerdata.PlayerDataRemovePacket; +import kamkeel.npcs.network.packets.request.playerdata.*; +import kamkeel.npcs.network.packets.request.profile.*; import kamkeel.npcs.network.packets.request.quest.*; import kamkeel.npcs.network.packets.request.recipe.RecipeGetPacket; import kamkeel.npcs.network.packets.request.recipe.RecipeRemovePacket; @@ -224,8 +223,12 @@ public class PacketHandler { REQUEST_PACKET.registerPacket(new TagRemovePacket()); // PlayerData Packets - REQUEST_PACKET.registerPacket(new PlayerDataGetPacket()); + + + REQUEST_PACKET.registerPacket(new PlayerDataGetNamesPacket()); REQUEST_PACKET.registerPacket(new PlayerDataRemovePacket()); + REQUEST_PACKET.registerPacket(new PlayerDataGetInfoPacket()); + REQUEST_PACKET.registerPacket(new PlayerDataRemoveInfoPacket()); REQUEST_PACKET.registerPacket(new PlayerDataMapRegenPacket()); // Main Menu Packets @@ -323,6 +326,14 @@ public class PacketHandler { REQUEST_PACKET.registerPacket(new EffectSavePacket()); REQUEST_PACKET.registerPacket(new EffectRemovePacket()); + // Profile Packets + REQUEST_PACKET.registerPacket(new ProfileGetPacket()); + REQUEST_PACKET.registerPacket(new ProfileGetInfoPacket()); + REQUEST_PACKET.registerPacket(new ProfileCreatePacket()); + REQUEST_PACKET.registerPacket(new ProfileRemovePacket()); + REQUEST_PACKET.registerPacket(new ProfileRenamePacket()); + REQUEST_PACKET.registerPacket(new ProfileChangePacket()); + // Other Packets REQUEST_PACKET.registerPacket(new IsGuiOpenInform()); REQUEST_PACKET.registerPacket(new GuiRequestPacket()); @@ -338,6 +349,7 @@ public class PacketHandler { public void registerDataPackets(){ // Data Packets + DATA_PACKET.registerPacket(new LoginPacket()); DATA_PACKET.registerPacket(new AchievementPacket()); DATA_PACKET.registerPacket(new ChatAlertPacket()); DATA_PACKET.registerPacket(new ChatBubblePacket()); @@ -353,6 +365,7 @@ public class PacketHandler { DATA_PACKET.registerPacket(new SwingPlayerArmPacket()); DATA_PACKET.registerPacket(new UpdateAnimationsPacket()); DATA_PACKET.registerPacket(new VillagerListPacket()); + DATA_PACKET.registerPacket(new PlayerDataInfoPacket()); // Data | GUI Packets DATA_PACKET.registerPacket(new GuiClosePacket()); diff --git a/src/main/java/kamkeel/npcs/network/PacketUtil.java b/src/main/java/kamkeel/npcs/network/PacketUtil.java index 50967d743..684be11d6 100644 --- a/src/main/java/kamkeel/npcs/network/PacketUtil.java +++ b/src/main/java/kamkeel/npcs/network/PacketUtil.java @@ -17,7 +17,6 @@ import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.data.IScriptHandler; import java.io.IOException; -import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; diff --git a/src/main/java/kamkeel/npcs/network/enums/EnumDataPacket.java b/src/main/java/kamkeel/npcs/network/enums/EnumDataPacket.java index afde0e87e..874677af9 100644 --- a/src/main/java/kamkeel/npcs/network/enums/EnumDataPacket.java +++ b/src/main/java/kamkeel/npcs/network/enums/EnumDataPacket.java @@ -38,6 +38,7 @@ public enum EnumDataPacket { GUI_TELEPORTER, GUI_BOOK, GUI_DATA, + PLAYER_DATA, GUI_ERROR, GUI_CLOSE, ISGUIOPEN, diff --git a/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java b/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java index b68446eac..9f7278368 100644 --- a/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java +++ b/src/main/java/kamkeel/npcs/network/enums/EnumRequestPacket.java @@ -136,7 +136,9 @@ public enum EnumRequestPacket { QuestCategoryGet, - PlayerDataGet, + PlayerDataInfo, + PlayerDataGetNames, + PlayerDataDelete, PlayerDataRemove, PlayerDataMapRegen, @@ -185,5 +187,13 @@ public enum EnumRequestPacket { EffectSave, ColorSet, - ColorBrush + ColorBrush, + + ProfileGet, + ProfileGetAll, + ProfileGetInfo, + ProfileCreate, + ProfileRemove, + ProfileRename, + ProfileChange } diff --git a/src/main/java/kamkeel/npcs/network/packets/data/ChatAlertPacket.java b/src/main/java/kamkeel/npcs/network/packets/data/ChatAlertPacket.java index b57661e90..b8c259796 100644 --- a/src/main/java/kamkeel/npcs/network/packets/data/ChatAlertPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/data/ChatAlertPacket.java @@ -8,12 +8,16 @@ import kamkeel.npcs.network.PacketChannel; import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumDataPacket; import kamkeel.npcs.util.ByteBufUtils; +import kamkeel.npcs.util.ColorUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.StatCollector; import noppes.npcs.config.ConfigClient; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public final class ChatAlertPacket extends AbstractPacket { public static final String packetName = "Data|ChatAlert"; @@ -53,11 +57,20 @@ public final class ChatAlertPacket extends AbstractPacket { if (!ConfigClient.ChatAlerts) return; - StringBuilder message = new StringBuilder(); - String str; - while ((str = ByteBufUtils.readString(in)) != null && !str.isEmpty()) { - message.append(str); + // Read all objects (sent as strings) from the buffer. + List parts = new ArrayList<>(); + String part; + while ((part = ByteBufUtils.readString(in)) != null && !part.isEmpty()) { + parts.add(part); } - player.addChatMessage(new ChatComponentTranslation(message.toString())); + + StringBuilder finalMessage = new StringBuilder(); + for (String s : parts) { + finalMessage.append(StatCollector.translateToLocal(s)); + } + + String text = finalMessage.toString(); + IChatComponent comp = ColorUtil.assembleComponent(text); + player.addChatMessage(comp); } } diff --git a/src/main/java/kamkeel/npcs/network/packets/data/LoginPacket.java b/src/main/java/kamkeel/npcs/network/packets/data/LoginPacket.java index 385b8fda4..022f4bc5e 100644 --- a/src/main/java/kamkeel/npcs/network/packets/data/LoginPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/data/LoginPacket.java @@ -1,21 +1,21 @@ package kamkeel.npcs.network.packets.data; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; import kamkeel.npcs.network.AbstractPacket; import kamkeel.npcs.network.PacketChannel; import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumDataPacket; -import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; +import noppes.npcs.client.ClientCacheHandler; +import noppes.npcs.config.ConfigMain; import java.io.IOException; public final class LoginPacket extends AbstractPacket { public static final String packetName = "CNPC+|Login"; - - public LoginPacket() { - } - + public LoginPacket() {} @Override public Enum getType() { @@ -29,13 +29,14 @@ public final class LoginPacket extends AbstractPacket { @Override public void sendData(ByteBuf out) throws IOException { -// ByteBufUtils.writeUTF8String(out, this.data.player.getCommandSenderName()); -// ByteBufUtils.writeNBT(out,this.data.saveFromNBT(new NBTTagCompound())); + out.writeBoolean(ConfigMain.PartiesEnabled); + out.writeBoolean(ConfigMain.ProfilesEnabled); } + @SideOnly(Side.CLIENT) @Override public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { - String playerName = ByteBufUtils.readUTF8String(in); - + ClientCacheHandler.allowParties = in.readBoolean(); + ClientCacheHandler.allowProfiles = in.readBoolean(); } } diff --git a/src/main/java/kamkeel/npcs/network/packets/data/OverlayQuestTrackingPacket.java b/src/main/java/kamkeel/npcs/network/packets/data/OverlayQuestTrackingPacket.java index f31baf305..f64756ba1 100644 --- a/src/main/java/kamkeel/npcs/network/packets/data/OverlayQuestTrackingPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/data/OverlayQuestTrackingPacket.java @@ -12,7 +12,9 @@ import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.client.ClientCacheHandler; -import noppes.npcs.client.gui.OverlayQuestTracking; +import noppes.npcs.client.gui.hud.ClientHudManager; +import noppes.npcs.client.gui.hud.EnumHudComponent; +import noppes.npcs.client.gui.hud.HudComponent; import java.io.IOException; @@ -46,12 +48,14 @@ public final class OverlayQuestTrackingPacket extends AbstractPacket { @SideOnly(Side.CLIENT) @Override public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + HudComponent component = ClientHudManager.getInstance().getHudComponents().get(EnumHudComponent.QuestTracker); try { NBTTagCompound nbt = ByteBufUtils.readNBT(in); - ClientCacheHandler.questTrackingOverlay = new OverlayQuestTracking(Minecraft.getMinecraft()); - ClientCacheHandler.questTrackingOverlay.setOverlayData(nbt); + component.loadData(nbt); + if(nbt.hasNoTags()) + component.hasData = false; } catch (IOException e) { - ClientCacheHandler.questTrackingOverlay = null; + component.hasData = false; } } } diff --git a/src/main/java/kamkeel/npcs/network/packets/data/PlayerDataInfoPacket.java b/src/main/java/kamkeel/npcs/network/packets/data/PlayerDataInfoPacket.java new file mode 100644 index 000000000..ca639fb21 --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/data/PlayerDataInfoPacket.java @@ -0,0 +1,103 @@ +package kamkeel.npcs.network.packets.data; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import kamkeel.npcs.network.LargeAbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumDataPacket; +import kamkeel.npcs.util.ByteBufUtils; +import net.minecraft.entity.player.EntityPlayer; +import noppes.npcs.client.NoppesUtil; + +import java.io.IOException; +import java.util.Map; + +public final class PlayerDataInfoPacket extends LargeAbstractPacket { + public static final String packetName = "Large|PlayerDataSendNew"; + + private String playerName; + private Map questCategories; + private Map questActive; + private Map questFinished; + + private Map dialogCategories; + private Map dialogRead; + + private Map transportCategories; + private Map transportLocations; + + private Map bankData; + private Map factionData; + + public PlayerDataInfoPacket() {} + + public PlayerDataInfoPacket(String playerName, + Map questCategories, Map questActive, Map questFinished, + Map dialogCategories, Map dialogRead, + Map transportCategories, Map transportLocations, + Map bankData, Map factionData) { + this.playerName = playerName; + this.questCategories = questCategories; + this.questActive = questActive; + this.questFinished = questFinished; + this.dialogCategories = dialogCategories; + this.dialogRead = dialogRead; + this.transportCategories = transportCategories; + this.transportLocations = transportLocations; + this.bankData = bankData; + this.factionData = factionData; + } + + @Override + public Enum getType() { + return EnumDataPacket.PLAYER_DATA; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.DATA_PACKET; + } + + @Override + protected byte[] getData() throws IOException { + ByteBuf buffer = Unpooled.buffer(); + // Write player name: + ByteBufUtils.writeString(buffer, playerName); + // Write quest data maps: + writeMap(buffer, questCategories); + writeMap(buffer, questActive); + writeMap(buffer, questFinished); + // Write dialog data maps: + writeMap(buffer, dialogCategories); + writeMap(buffer, dialogRead); + // Write transport data maps: + writeMap(buffer, transportCategories); + writeMap(buffer, transportLocations); + // Write bank data map: + writeMap(buffer, bankData); + // Write faction data map: + writeMap(buffer, factionData); + + byte[] bytes = new byte[buffer.readableBytes()]; + buffer.readBytes(bytes); + return bytes; + } + + private void writeMap(ByteBuf buffer, Map map) { + if (map != null) { + buffer.writeInt(map.size()); + for (Map.Entry entry : map.entrySet()) { + ByteBufUtils.writeString(buffer, entry.getKey()); + buffer.writeInt(entry.getValue()); + } + } else { + buffer.writeInt(0); + } + } + + @Override + protected void handleCompleteData(ByteBuf data, EntityPlayer player) throws IOException { + NoppesUtil.handlePlayerData(data, player); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/data/large/SyncEffectPacket.java b/src/main/java/kamkeel/npcs/network/packets/data/large/SyncEffectPacket.java index 723df8658..2282be91b 100644 --- a/src/main/java/kamkeel/npcs/network/packets/data/large/SyncEffectPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/data/large/SyncEffectPacket.java @@ -9,8 +9,6 @@ import kamkeel.npcs.network.LargeAbstractPacket; import kamkeel.npcs.network.PacketChannel; import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumDataPacket; -import kamkeel.npcs.network.enums.EnumSyncAction; -import kamkeel.npcs.network.enums.EnumSyncType; import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; diff --git a/src/main/java/kamkeel/npcs/network/packets/player/DialogSelectPacket.java b/src/main/java/kamkeel/npcs/network/packets/player/DialogSelectPacket.java index c87f7ae5d..8932b22a0 100644 --- a/src/main/java/kamkeel/npcs/network/packets/player/DialogSelectPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/player/DialogSelectPacket.java @@ -8,8 +8,6 @@ import kamkeel.npcs.network.enums.EnumPlayerPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import noppes.npcs.NoppesUtilPlayer; -import noppes.npcs.NoppesUtilServer; -import noppes.npcs.entity.EntityNPCInterface; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/player/SaveSignPacket.java b/src/main/java/kamkeel/npcs/network/packets/player/SaveSignPacket.java index b00ce42bc..e1c50257e 100644 --- a/src/main/java/kamkeel/npcs/network/packets/player/SaveSignPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/player/SaveSignPacket.java @@ -8,7 +8,6 @@ import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumPlayerPacket; import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import noppes.npcs.blocks.tiles.TileBigSign; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/TileEntityGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/TileEntityGetPacket.java index 280dc89dc..0ef4419a1 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/TileEntityGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/TileEntityGetPacket.java @@ -10,16 +10,12 @@ import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; import kamkeel.npcs.network.packets.data.large.GuiDataPacket; -import kamkeel.npcs.network.packets.data.large.ScrollDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.WorldProvider; -import net.minecraftforge.common.DimensionManager; import java.io.IOException; -import java.util.HashMap; public final class TileEntityGetPacket extends AbstractPacket { public static final String packetName = "Request|TileEntityGet"; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneAllTagsPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneAllTagsPacket.java index 6aafe22dc..c593e5097 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneAllTagsPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneAllTagsPacket.java @@ -14,10 +14,8 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import noppes.npcs.controllers.ServerTagMapController; import noppes.npcs.controllers.TagController; import noppes.npcs.controllers.data.Tag; -import noppes.npcs.controllers.data.TagMap; import java.io.IOException; import java.util.HashSet; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneListPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneListPacket.java index 004ae7937..68ba3faba 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneListPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneListPacket.java @@ -1,6 +1,5 @@ package kamkeel.npcs.network.packets.request.clone; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; @@ -17,9 +16,6 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; -import noppes.npcs.LogWriter; -import noppes.npcs.NoppesUtilServer; -import noppes.npcs.config.ConfigDebug; import noppes.npcs.controllers.ServerCloneController; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneTagListPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneTagListPacket.java index 312831112..a12a1fe0c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneTagListPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/clone/CloneTagListPacket.java @@ -10,16 +10,11 @@ import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; import kamkeel.npcs.network.packets.data.large.GuiDataPacket; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; -import noppes.npcs.controllers.ServerCloneController; import noppes.npcs.controllers.ServerTagMapController; import noppes.npcs.controllers.data.TagMap; -import noppes.npcs.entity.EntityNPCInterface; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/clone/MobSpawnerPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/clone/MobSpawnerPacket.java index 29ff58063..55720121c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/clone/MobSpawnerPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/clone/MobSpawnerPacket.java @@ -1,6 +1,5 @@ package kamkeel.npcs.network.packets.request.clone; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; @@ -11,18 +10,13 @@ import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; import kamkeel.npcs.util.ByteBufUtils; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChatComponentText; import noppes.npcs.CustomNpcsPermissions; -import noppes.npcs.LogWriter; import noppes.npcs.NoppesUtilServer; -import noppes.npcs.config.ConfigDebug; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ServerCloneController; -import noppes.npcs.entity.EntityNPCInterface; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogCategoriesGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogCategoriesGetPacket.java index 1a264fd01..fb9ae8f84 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogCategoriesGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogCategoriesGetPacket.java @@ -9,13 +9,10 @@ import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; -import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import kamkeel.npcs.network.packets.data.large.ScrollDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.controllers.DialogController; -import noppes.npcs.controllers.data.DialogCategory; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogGetPacket.java index dfe96e28c..f8787f435 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/dialog/DialogGetPacket.java @@ -10,7 +10,6 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.NoppesUtilServer; import noppes.npcs.controllers.DialogController; import noppes.npcs.controllers.QuestController; import noppes.npcs.controllers.data.Dialog; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/effects/EffectGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/effects/EffectGetPacket.java index 140fc591b..0b9d8613e 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/effects/EffectGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/effects/EffectGetPacket.java @@ -15,7 +15,6 @@ import noppes.npcs.controllers.CustomEffectController; import noppes.npcs.controllers.data.CustomEffect; import java.io.IOException; -import java.util.HashMap; public final class EffectGetPacket extends AbstractPacket { public static final String packetName = "NPC|GetEffect"; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/faction/FactionsGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/faction/FactionsGetPacket.java index 36273b4d3..7f4d90b5e 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/faction/FactionsGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/faction/FactionsGetPacket.java @@ -12,8 +12,6 @@ import kamkeel.npcs.network.enums.EnumRequestPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import noppes.npcs.NoppesUtilServer; -import noppes.npcs.controllers.QuestController; -import noppes.npcs.controllers.data.QuestCategory; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/feather/DimensionTeleportPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/feather/DimensionTeleportPacket.java index 884552595..76215a38c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/feather/DimensionTeleportPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/feather/DimensionTeleportPacket.java @@ -9,17 +9,12 @@ import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; -import kamkeel.npcs.network.packets.data.large.GuiDataPacket; -import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.WorldServer; -import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.NoppesUtilPlayer; -import noppes.npcs.controllers.ServerCloneController; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/item/ColorSetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/item/ColorSetPacket.java index aafac6830..0d3529137 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/item/ColorSetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/item/ColorSetPacket.java @@ -3,7 +3,10 @@ package kamkeel.npcs.network.packets.request.item; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; -import kamkeel.npcs.network.*; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; import net.minecraft.entity.player.EntityPlayer; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/linked/LinkedItemBuildPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/linked/LinkedItemBuildPacket.java index bb54cc529..b72ea1b0c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/linked/LinkedItemBuildPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/linked/LinkedItemBuildPacket.java @@ -9,18 +9,11 @@ import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; -import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.CustomItems; import noppes.npcs.CustomNpcsPermissions; -import noppes.npcs.NoppesUtilServer; import noppes.npcs.controllers.LinkedItemController; import noppes.npcs.controllers.data.LinkedItem; -import noppes.npcs.scripted.NpcAPI; -import noppes.npcs.scripted.item.ScriptLinkedItem; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuDisplayGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuDisplayGetPacket.java index c286b37e2..c0e658dec 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuDisplayGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuDisplayGetPacket.java @@ -13,7 +13,6 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.CustomNpcsPermissions; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuStatsGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuStatsGetPacket.java index 4b0ab51ed..1c0165164 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuStatsGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/mainmenu/MainmenuStatsGetPacket.java @@ -13,7 +13,6 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.CustomNpcsPermissions; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetInfoPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetInfoPacket.java new file mode 100644 index 000000000..f4037e2c7 --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetInfoPacket.java @@ -0,0 +1,48 @@ +package kamkeel.npcs.network.packets.request.playerdata; + +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.util.ByteBufUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.NoppesUtilServer; + +import java.io.IOException; + +public final class PlayerDataGetInfoPacket extends AbstractPacket { + public static final String packetName = "Request|PlayerDataGetNew"; + private String playerName; + + public PlayerDataGetInfoPacket() {} + + public PlayerDataGetInfoPacket(String playerName) { + this.playerName = playerName; + } + + @Override + public Enum getType() { + return EnumRequestPacket.PlayerDataInfo; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public void sendData(ByteBuf out) throws IOException { + ByteBufUtils.writeString(out, playerName); + } + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + String playerName = ByteBufUtils.readString(in); + NoppesUtilServer.sendPlayerDataInfo(playerName, (EntityPlayerMP) player); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetNamesPacket.java similarity index 88% rename from src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetPacket.java rename to src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetNamesPacket.java index 557698999..7bc09452e 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataGetNamesPacket.java @@ -17,22 +17,22 @@ import noppes.npcs.constants.EnumPlayerData; import java.io.IOException; -public final class PlayerDataGetPacket extends AbstractPacket { +public final class PlayerDataGetNamesPacket extends AbstractPacket { public static String packetName = "Request|PlayerDataGet"; private EnumPlayerData playerData; private String name; - public PlayerDataGetPacket() {} + public PlayerDataGetNamesPacket() {} - public PlayerDataGetPacket(EnumPlayerData playerData, String name) { + public PlayerDataGetNamesPacket(EnumPlayerData playerData, String name) { this.playerData = playerData; this.name = name; } @Override public Enum getType() { - return EnumRequestPacket.PlayerDataGet; + return EnumRequestPacket.PlayerDataGetNames; } @Override diff --git a/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataRemoveInfoPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataRemoveInfoPacket.java new file mode 100644 index 000000000..50ab6148e --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/playerdata/PlayerDataRemoveInfoPacket.java @@ -0,0 +1,57 @@ +package kamkeel.npcs.network.packets.request.playerdata; + +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.util.ByteBufUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.NoppesUtilServer; +import noppes.npcs.constants.EnumPlayerData; + +import java.io.IOException; + +public final class PlayerDataRemoveInfoPacket extends AbstractPacket { + public static final String packetName = "Request|PlayerDataRemoveNew"; + + private String playerName; + private EnumPlayerData tabType; + private int value; + + public PlayerDataRemoveInfoPacket() {} + + public PlayerDataRemoveInfoPacket(String playerName, EnumPlayerData tabType, int selectedKey) { + this.playerName = playerName; + this.tabType = tabType; + this.value = selectedKey; + } + + @Override + public Enum getType() { + return EnumRequestPacket.PlayerDataDelete; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public void sendData(ByteBuf out) throws IOException { + ByteBufUtils.writeString(out, playerName); + out.writeInt(tabType.ordinal()); + out.writeInt(this.value); + } + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + String playerName = ByteBufUtils.readString(in); + int tabType = in.readInt(); + int value = in.readInt(); + NoppesUtilServer.removePlayerDataInfo(playerName, tabType, value, (EntityPlayerMP) player); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileChangePacket.java b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileChangePacket.java new file mode 100644 index 000000000..19c62ffff --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileChangePacket.java @@ -0,0 +1,66 @@ +package kamkeel.npcs.network.packets.request.profile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.ProfileOperation; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.network.packets.data.ChatAlertPacket; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.CustomNpcsPermissions; +import noppes.npcs.config.ConfigMain; + +import java.io.IOException; + +public final class ProfileChangePacket extends AbstractPacket { + public static String packetName = "Request|ProfileChange"; + + private int slotID; + + public ProfileChangePacket() {} + + public ProfileChangePacket(int slotID) { + this.slotID = slotID; + } + + @Override + public Enum getType() { + return EnumRequestPacket.ProfileChange; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public CustomNpcsPermissions.Permission getPermission() { + return CustomNpcsPermissions.PROFILE_CHANGE; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException { + out.writeInt(this.slotID); + } + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + if(!ConfigMain.ProfilesEnabled) + return; + + int slot = in.readInt(); + ProfileOperation operation = ProfileController.Instance.changeSlot(player, slot); + ProfileGetPacket.sendProfileNBT(player); + ProfileGetInfoPacket.sendProfileInfo(player); + ChatAlertPacket.sendChatAlert((EntityPlayerMP) player, operation.getMessage()); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileCreatePacket.java b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileCreatePacket.java new file mode 100644 index 000000000..b8d50e6d4 --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileCreatePacket.java @@ -0,0 +1,59 @@ +package kamkeel.npcs.network.packets.request.profile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.Profile; +import kamkeel.npcs.controllers.data.ProfileOperation; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.network.packets.data.ChatAlertPacket; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.CustomNpcsPermissions; +import noppes.npcs.config.ConfigMain; + +import java.io.IOException; + +public final class ProfileCreatePacket extends AbstractPacket { + public static String packetName = "Request|ProfileCreate"; + + public ProfileCreatePacket() {} + + @Override + public Enum getType() { + return EnumRequestPacket.ProfileCreate; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public CustomNpcsPermissions.Permission getPermission() { + return CustomNpcsPermissions.PROFILE_CREATE; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException {} + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + if(!ConfigMain.ProfilesEnabled) + return; + + Profile profile = ProfileController.Instance.getProfile(player); + ProfileOperation operation = ProfileController.Instance.createSlotInternal(profile); + ProfileGetPacket.sendProfileNBT(player); + ProfileGetInfoPacket.sendProfileInfo(player); + ChatAlertPacket.sendChatAlert((EntityPlayerMP) player, operation.getMessage()); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileGetInfoPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileGetInfoPacket.java new file mode 100644 index 000000000..50f9d8fe1 --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileGetInfoPacket.java @@ -0,0 +1,104 @@ +package kamkeel.npcs.network.packets.request.profile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.ProfileController; +import noppes.npcs.api.handler.data.ISlot; +import kamkeel.npcs.controllers.data.InfoEntry; +import kamkeel.npcs.controllers.data.Profile; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.network.packets.data.large.GuiDataPacket; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; +import noppes.npcs.config.ConfigMain; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public final class ProfileGetInfoPacket extends AbstractPacket { + public static String packetName = "Request|ProfileGetInfo"; + + public ProfileGetInfoPacket() {} + + @Override + public Enum getType() { + return EnumRequestPacket.ProfileGetInfo; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException {} + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + if(!ConfigMain.ProfilesEnabled) + return; + + sendProfileInfo(player); + } + + public static void sendProfileInfo(EntityPlayer player){ + NBTTagCompound compound = new NBTTagCompound(); + compound.setBoolean("PROFILE_INFO", true); + NBTTagList slotList = new NBTTagList(); + Profile profile = ProfileController.Instance.getProfile(player); + if(profile != null){ + for(ISlot slot : profile.getSlots().values()){ + NBTTagCompound slotCompound = new NBTTagCompound(); + NBTTagList infoList = new NBTTagList(); + slotCompound.setInteger("ID", slot.getId()); + List profileInfo = ProfileController.Instance.getProfileInfo(player, slot.getId()); + for(InfoEntry infoEntry : profileInfo){ + infoList.appendTag(infoEntry.writeToNBT()); + } + slotCompound.setTag("INFO", infoList); + slotList.appendTag(slotCompound); + } + compound.setTag("SLOTS", slotList); + } + GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound); + } + + public static HashMap> readProfileInfo(NBTTagCompound compound) { + HashMap> slotInfoMap = new HashMap<>(); + + if (!compound.getBoolean("PROFILE_INFO")) return slotInfoMap; + + NBTTagList slotList = compound.getTagList("SLOTS", Constants.NBT.TAG_COMPOUND); + + for (int i = 0; i < slotList.tagCount(); i++) { + NBTTagCompound slotCompound = slotList.getCompoundTagAt(i); + + int slotId = slotCompound.getInteger("ID"); + NBTTagList infoList = slotCompound.getTagList("INFO", Constants.NBT.TAG_COMPOUND); + + List infoEntries = new ArrayList<>(); + for (int j = 0; j < infoList.tagCount(); j++) { + NBTTagCompound infoTag = infoList.getCompoundTagAt(j); + infoEntries.add(InfoEntry.readFromNBT(infoTag)); // Convert back to InfoEntry + } + + slotInfoMap.put(slotId, infoEntries); + } + + return slotInfoMap; + } + +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileGetPacket.java new file mode 100644 index 000000000..ffbdb4997 --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileGetPacket.java @@ -0,0 +1,56 @@ +package kamkeel.npcs.network.packets.request.profile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.Profile; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.network.packets.data.large.GuiDataPacket; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.config.ConfigMain; + +import java.io.IOException; + +public final class ProfileGetPacket extends AbstractPacket { + public static String packetName = "Request|ProfileGet"; + + public ProfileGetPacket() {} + + @Override + public Enum getType() { + return EnumRequestPacket.ProfileGet; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException {} + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + if(!ConfigMain.ProfilesEnabled) + return; + + sendProfileNBT(player); + } + + public static void sendProfileNBT(EntityPlayer player){ + Profile profile = ProfileController.Instance.getProfile(player); + NBTTagCompound compound = profile.writeToNBT(); + compound.setBoolean("PROFILE", true); + GuiDataPacket.sendGuiData((EntityPlayerMP) player, compound); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileRemovePacket.java b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileRemovePacket.java new file mode 100644 index 000000000..c762b435b --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileRemovePacket.java @@ -0,0 +1,66 @@ +package kamkeel.npcs.network.packets.request.profile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.ProfileOperation; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.network.packets.data.ChatAlertPacket; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.CustomNpcsPermissions; +import noppes.npcs.config.ConfigMain; + +import java.io.IOException; + +public final class ProfileRemovePacket extends AbstractPacket { + public static String packetName = "Request|ProfileRemove"; + + private int slotID; + + public ProfileRemovePacket() {} + + public ProfileRemovePacket(int slotID) { + this.slotID = slotID; + } + + @Override + public Enum getType() { + return EnumRequestPacket.ProfileRemove; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public CustomNpcsPermissions.Permission getPermission() { + return CustomNpcsPermissions.PROFILE_DELETE; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException { + out.writeInt(this.slotID); + } + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + if(!ConfigMain.ProfilesEnabled) + return; + + int slot = in.readInt(); + ProfileOperation operation = ProfileController.Instance.removeSlot(player, slot); + ProfileGetPacket.sendProfileNBT(player); + ProfileGetInfoPacket.sendProfileInfo(player); + ChatAlertPacket.sendChatAlert((EntityPlayerMP) player, operation.getMessage()); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileRenamePacket.java b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileRenamePacket.java new file mode 100644 index 000000000..d692e1ed9 --- /dev/null +++ b/src/main/java/kamkeel/npcs/network/packets/request/profile/ProfileRenamePacket.java @@ -0,0 +1,79 @@ +package kamkeel.npcs.network.packets.request.profile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.Profile; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.enums.EnumRequestPacket; +import kamkeel.npcs.network.packets.data.ChatAlertPacket; +import kamkeel.npcs.util.ByteBufUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import noppes.npcs.CustomNpcsPermissions; +import noppes.npcs.config.ConfigMain; + +import java.io.IOException; + +public final class ProfileRenamePacket extends AbstractPacket { + public static String packetName = "Request|ProfileRename"; + + private int slotID; + private String name; + + public ProfileRenamePacket() {} + + public ProfileRenamePacket(int slotID, String name) { + this.slotID = slotID; + this.name = name; + } + + @Override + public Enum getType() { + return EnumRequestPacket.ProfileRename; + } + + @Override + public PacketChannel getChannel() { + return PacketHandler.REQUEST_PACKET; + } + + @Override + public CustomNpcsPermissions.Permission getPermission() { + return CustomNpcsPermissions.PROFILE_RENAME; + } + + @SideOnly(Side.CLIENT) + @Override + public void sendData(ByteBuf out) throws IOException { + out.writeInt(this.slotID); + ByteBufUtils.writeString(out, this.name); + } + + @Override + public void receiveData(ByteBuf in, EntityPlayer player) throws IOException { + if (!(player instanceof EntityPlayerMP)) + return; + + if(!ConfigMain.ProfilesEnabled) + return; + + int slot = in.readInt(); + String newName = ByteBufUtils.readString(in); + + Profile profile = ProfileController.Instance.getProfile(player); + if(!profile.getSlots().containsKey(slot)) { + ChatAlertPacket.sendChatAlert((EntityPlayerMP) player, "No slot found"); + return; + } + + ProfileController.Instance.getProfile(player).getSlots().get(slot).setName(newName); + ProfileController.Instance.save(player, ProfileController.Instance.getProfile(player)); + + ProfileGetPacket.sendProfileNBT(player); + ProfileGetInfoPacket.sendProfileInfo(player); + } +} diff --git a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestCategoriesGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestCategoriesGetPacket.java index 12ed56a54..c276bfb1f 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestCategoriesGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestCategoriesGetPacket.java @@ -9,11 +9,9 @@ import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; -import kamkeel.npcs.network.packets.data.large.ScrollDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import noppes.npcs.NoppesUtilServer; -import noppes.npcs.controllers.DialogController; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestGetPacket.java index e3f9119d4..bb236af33 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestGetPacket.java @@ -10,9 +10,7 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.controllers.DialogController; import noppes.npcs.controllers.QuestController; -import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.Quest; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestRemovePacket.java b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestRemovePacket.java index 55ca84f39..199be0063 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestRemovePacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestRemovePacket.java @@ -13,9 +13,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.NoppesUtilServer; -import noppes.npcs.controllers.DialogController; import noppes.npcs.controllers.QuestController; -import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.Quest; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestsGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestsGetPacket.java index 29fc59194..500be2d03 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestsGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/quest/QuestsGetPacket.java @@ -12,7 +12,6 @@ import kamkeel.npcs.network.enums.EnumRequestPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import noppes.npcs.NoppesUtilServer; -import noppes.npcs.controllers.DialogController; import noppes.npcs.controllers.QuestController; import noppes.npcs.controllers.data.QuestCategory; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/role/RoleGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/role/RoleGetPacket.java index 11f6e0037..c7bb7da2d 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/role/RoleGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/role/RoleGetPacket.java @@ -13,7 +13,6 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.CustomNpcsPermissions; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/BlockScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/BlockScriptPacket.java index 1b9fcb81d..e354a611c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/BlockScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/BlockScriptPacket.java @@ -18,9 +18,6 @@ import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.blocks.tiles.TileScripted; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ScriptController; -import noppes.npcs.controllers.data.PlayerDataScript; -import noppes.npcs.scripted.NpcAPI; -import noppes.npcs.scripted.item.ScriptCustomItem; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/ForgeScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/ForgeScriptPacket.java index 02ab27097..cb0fe7894 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/ForgeScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/ForgeScriptPacket.java @@ -15,7 +15,6 @@ import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.data.ForgeDataScript; import noppes.npcs.controllers.data.IScriptHandler; -import noppes.npcs.controllers.data.PlayerDataScript; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/GlobalNPCScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/GlobalNPCScriptPacket.java index a34cbb1fa..70ecfecd4 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/GlobalNPCScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/GlobalNPCScriptPacket.java @@ -13,7 +13,6 @@ import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ScriptController; -import noppes.npcs.controllers.data.ForgeDataScript; import noppes.npcs.controllers.data.GlobalNPCDataScript; import noppes.npcs.controllers.data.IScriptHandler; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/NPCScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/NPCScriptPacket.java index fc6073fbb..31eb1768e 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/NPCScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/NPCScriptPacket.java @@ -17,8 +17,6 @@ import noppes.npcs.LogWriter; import noppes.npcs.config.ConfigDebug; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ScriptController; -import noppes.npcs.controllers.data.GlobalNPCDataScript; -import noppes.npcs.controllers.data.IScriptHandler; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/PlayerScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/PlayerScriptPacket.java index ec57a2d25..eadaab2b1 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/PlayerScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/PlayerScriptPacket.java @@ -1,6 +1,5 @@ package kamkeel.npcs.network.packets.request.script; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; @@ -12,11 +11,8 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.CustomNpcsPermissions; -import noppes.npcs.LogWriter; -import noppes.npcs.config.ConfigDebug; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ScriptController; -import noppes.npcs.controllers.data.DataScript; import noppes.npcs.controllers.data.IScriptHandler; import noppes.npcs.controllers.data.PlayerDataScript; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/ScriptInfoPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/ScriptInfoPacket.java index c4bfbfa8b..d97ee13b8 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/ScriptInfoPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/ScriptInfoPacket.java @@ -1,6 +1,5 @@ package kamkeel.npcs.network.packets.request.script; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; @@ -13,10 +12,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.CustomNpcsPermissions; -import noppes.npcs.LogWriter; -import noppes.npcs.config.ConfigDebug; import noppes.npcs.config.ConfigScript; -import noppes.npcs.controllers.ScriptController; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptErrorPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptErrorPacket.java index c40417a41..697e54f87 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptErrorPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptErrorPacket.java @@ -9,17 +9,14 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumRequestPacket; import kamkeel.npcs.network.packets.data.large.GuiDataPacket; -import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.NBTTags; import noppes.npcs.api.item.IItemStack; -import noppes.npcs.client.gui.script.GuiScriptItem; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.ScriptContainer; -import noppes.npcs.controllers.ScriptController; import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.item.ScriptCustomItem; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptPacket.java index bc66d732f..aa60d90b1 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/item/ItemScriptPacket.java @@ -3,7 +3,10 @@ package kamkeel.npcs.network.packets.request.script.item; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; -import kamkeel.npcs.network.*; +import kamkeel.npcs.network.AbstractPacket; +import kamkeel.npcs.network.PacketChannel; +import kamkeel.npcs.network.PacketClient; +import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumRequestPacket; import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import kamkeel.npcs.util.ByteBufUtils; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/script/item/LinkedItemScriptPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/script/item/LinkedItemScriptPacket.java index b01f2adc5..98a1927f6 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/script/item/LinkedItemScriptPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/script/item/LinkedItemScriptPacket.java @@ -15,7 +15,9 @@ import noppes.npcs.LogWriter; import noppes.npcs.config.ConfigDebug; import noppes.npcs.config.ConfigScript; import noppes.npcs.controllers.LinkedItemController; -import noppes.npcs.controllers.data.*; +import noppes.npcs.controllers.data.IScriptHandler; +import noppes.npcs.controllers.data.LinkedItem; +import noppes.npcs.controllers.data.LinkedItemScript; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/tags/TagGetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/tags/TagGetPacket.java index 74a2561dc..29bfce39c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/tags/TagGetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/tags/TagGetPacket.java @@ -13,7 +13,6 @@ import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.NoppesUtilServer; import noppes.npcs.controllers.TagController; import noppes.npcs.controllers.data.Tag; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/tags/TagSetPacket.java b/src/main/java/kamkeel/npcs/network/packets/request/tags/TagSetPacket.java index e28190fa1..2c49aae9c 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/tags/TagSetPacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/tags/TagSetPacket.java @@ -16,7 +16,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.controllers.TagController; -import noppes.npcs.controllers.data.Tag; import noppes.npcs.entity.EntityNPCInterface; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/network/packets/request/transport/TransportSavePacket.java b/src/main/java/kamkeel/npcs/network/packets/request/transport/TransportSavePacket.java index 6fe84ed05..119145e72 100644 --- a/src/main/java/kamkeel/npcs/network/packets/request/transport/TransportSavePacket.java +++ b/src/main/java/kamkeel/npcs/network/packets/request/transport/TransportSavePacket.java @@ -9,18 +9,14 @@ import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.PacketUtil; import kamkeel.npcs.network.enums.EnumItemPacketType; import kamkeel.npcs.network.enums.EnumRequestPacket; -import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.CustomNpcsPermissions; -import noppes.npcs.constants.EnumJobType; import noppes.npcs.constants.EnumRoleType; -import noppes.npcs.controllers.ServerCloneController; import noppes.npcs.controllers.TransportController; import noppes.npcs.controllers.data.TransportLocation; -import noppes.npcs.roles.JobSpawner; import noppes.npcs.roles.RoleTransporter; import java.io.IOException; diff --git a/src/main/java/kamkeel/npcs/util/ByteBufUtils.java b/src/main/java/kamkeel/npcs/util/ByteBufUtils.java index f470e17c0..86ad378d8 100644 --- a/src/main/java/kamkeel/npcs/util/ByteBufUtils.java +++ b/src/main/java/kamkeel/npcs/util/ByteBufUtils.java @@ -7,10 +7,8 @@ import net.minecraft.nbt.NBTSizeTracker; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.village.MerchantRecipeList; -import noppes.npcs.LogWriter; import java.io.IOException; -import java.util.Arrays; import java.util.List; import java.util.Map; @@ -102,7 +100,7 @@ public class ByteBufUtils extends cpw.mods.fml.common.network.ByteBufUtils { int length = buffer.readInt(); byte[] bytes = new byte[length]; buffer.readBytes(bytes); - return CompressedStreamTools.func_152457_a(bytes, new NBTSizeTracker(15728640L)); + return CompressedStreamTools.func_152457_a(bytes, new NBTSizeTracker(31457280L)); } public static void writeString(ByteBuf buffer, String s){ diff --git a/src/main/java/kamkeel/npcs/util/ColorUtil.java b/src/main/java/kamkeel/npcs/util/ColorUtil.java index 2fd9997f0..1c72fc103 100644 --- a/src/main/java/kamkeel/npcs/util/ColorUtil.java +++ b/src/main/java/kamkeel/npcs/util/ColorUtil.java @@ -1,5 +1,11 @@ package kamkeel.npcs.util; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; + public class ColorUtil { @@ -28,4 +34,133 @@ public class ColorUtil { float b = (hex & 0xFF) / 255.0F; return new float[]{r, g, b}; } + + + /** + * Helper method that retrieves the EnumChatFormatting associated with a given formatting code character. + * + * @param c The formatting code character (e.g., '6' or 'l'). + * @return The matching EnumChatFormatting, or null if not found. + */ + public static EnumChatFormatting getFormattingByChar(char c) { + for (EnumChatFormatting format : EnumChatFormatting.values()) { + if (format.getFormattingCode() == c) { + return format; + } + } + return null; + } + + /** + * Assembles a composite IChatComponent from a raw text string with formatting codes (using §). + * Each time the formatting changes, a new component is created and appended as a sibling. + * + * @param text The raw text with formatting codes. + * @return A composite IChatComponent reflecting the formatting changes. + */ + public static IChatComponent assembleComponent(String text) { + // Final composite component + ChatComponentText composite = new ChatComponentText(""); + // Accumulates text until a formatting code change + ChatComponentText current = new ChatComponentText(""); + // Start with a fresh ChatStyle + ChatStyle currentStyle = new ChatStyle(); + + int i = 0; + while (i < text.length()) { + char c = text.charAt(i); + if (c == '\u00A7' && i + 1 < text.length()) { + // When a formatting code is encountered, first add any accumulated text as a sibling. + if (current.getUnformattedText().length() > 0) { + current.setChatStyle(currentStyle.createDeepCopy()); + composite.appendSibling(current); + current = new ChatComponentText(""); + } + char code = text.charAt(i + 1); + EnumChatFormatting formatting = getFormattingByChar(code); + if (formatting != null) { + // If it’s a color code (0-9, a-f), then it resets previous formatting. + if ("0123456789abcdef".indexOf(Character.toLowerCase(code)) >= 0) { + currentStyle = new ChatStyle().setColor(formatting); + } else { + // For modifiers (BOLD, ITALIC, etc.) + if (formatting == EnumChatFormatting.RESET) { + currentStyle = new ChatStyle(); + } else { + switch (formatting) { + case BOLD: + currentStyle = currentStyle.setBold(Boolean.TRUE); + break; + case ITALIC: + currentStyle = currentStyle.setItalic(Boolean.TRUE); + break; + case UNDERLINE: + currentStyle = currentStyle.setUnderlined(Boolean.TRUE); + break; + case STRIKETHROUGH: + currentStyle = currentStyle.setStrikethrough(Boolean.TRUE); + break; + case OBFUSCATED: + currentStyle = currentStyle.setObfuscated(Boolean.TRUE); + break; + default: + break; + } + } + } + } + i += 2; // Skip the § and the code character. + } else { + // Accumulate normal characters. + current.appendText(String.valueOf(c)); + i++; + } + } + // Append any trailing text. + if (current.getUnformattedText().length() > 0) { + current.setChatStyle(currentStyle.createDeepCopy()); + composite.appendSibling(current); + } + return composite; + } + + private static String LABEL = "\u00A76[\u00A7eCNPC+\u00A76] "; + + /** + * Assembles a composite chat component from a raw text string with formatting codes, + * and immediately sends it to the specified ICommandSender. + * + * @param sender The ICommandSender to send the message to. + * @param text The raw text (with § codes) to be assembled and sent. + */ + public static void sendMessage(ICommandSender sender, String text) { + text = "\u00A77" + text; + IChatComponent component = assembleComponent(text); + sender.addChatMessage(component); + } + + public static void sendMessage(ICommandSender sender, String format, Object... obs) { + sendMessage(sender, String.format(format, obs)); + } + + public static void sendResult(ICommandSender sender, String text) { + text = LABEL + "\u00A7a" + text; + IChatComponent component = assembleComponent(text); + sender.addChatMessage(component); + } + + public static void sendResult(ICommandSender sender, String format, Object... obs) { + sendResult(sender, String.format(format, obs)); + } + + public static void sendError(ICommandSender sender, String text) { + text = LABEL + "\u00A74Error: \u00A7c" + text; + IChatComponent component = assembleComponent(text); + sender.addChatMessage(component); + } + + public static void sendError(ICommandSender sender, String format, Object... obs) { + sendError(sender, String.format(format, obs)); + } + } diff --git a/src/main/java/noppes/npcs/CustomNpcs.java b/src/main/java/noppes/npcs/CustomNpcs.java index 69463d914..699117a03 100644 --- a/src/main/java/noppes/npcs/CustomNpcs.java +++ b/src/main/java/noppes/npcs/CustomNpcs.java @@ -267,7 +267,8 @@ public class CustomNpcs { public void serverstart(FMLServerStartingEvent event) { event.registerServerCommand(new CommandNoppes()); event.registerServerCommand(new CommandKamkeel()); - event.registerServerCommand(new CommandProfile()); + if(ConfigMain.ProfilesEnabled) + event.registerServerCommand(new CommandProfile()); } private void registerNpc(Class cl, String name) { diff --git a/src/main/java/noppes/npcs/CustomNpcsPermissions.java b/src/main/java/noppes/npcs/CustomNpcsPermissions.java index f494ddb9a..71419fada 100644 --- a/src/main/java/noppes/npcs/CustomNpcsPermissions.java +++ b/src/main/java/noppes/npcs/CustomNpcsPermissions.java @@ -88,6 +88,15 @@ public class CustomNpcsPermissions{ public static final Permission SCRIPT_ITEM = new Permission("customnpcs.script.item"); public static final Permission SCRIPT_BLOCK = new Permission("customnpcs.script.block"); + // Profiles + public static final Permission PROFILE_ADMIN = new Permission("customnpcs.profile.admin"); + public static final Permission PROFILE_CREATE = new Permission("customnpcs.profile.create"); + public static final Permission PROFILE_DELETE = new Permission("customnpcs.profile.delete"); + public static final Permission PROFILE_RENAME = new Permission("customnpcs.profile.rename"); + public static final Permission PROFILE_CHANGE = new Permission("customnpcs.profile.change"); + public static final Permission PROFILE_REGION_BYPASS = new Permission("customnpcs.profile.region-bypass"); + public static final Permission PROFILE_MAX = new Permission("customnpcs.profile.max.*"); + public static CustomNpcsPermissions Instance; private Class bukkit; private Method getPlayer; diff --git a/src/main/java/noppes/npcs/EventHooks.java b/src/main/java/noppes/npcs/EventHooks.java index 913a2a5a0..465fa1f47 100644 --- a/src/main/java/noppes/npcs/EventHooks.java +++ b/src/main/java/noppes/npcs/EventHooks.java @@ -17,7 +17,6 @@ import net.minecraftforge.event.world.WorldEvent; import noppes.npcs.api.IWorld; import noppes.npcs.api.entity.*; import noppes.npcs.api.event.IAnimationEvent; -import noppes.npcs.api.event.IItemEvent; import noppes.npcs.api.gui.ICustomGui; import noppes.npcs.api.gui.IItemSlot; import noppes.npcs.api.handler.data.IAnimation; diff --git a/src/main/java/noppes/npcs/NoppesUtilPlayer.java b/src/main/java/noppes/npcs/NoppesUtilPlayer.java index 2f364de8f..26b5f5f73 100644 --- a/src/main/java/noppes/npcs/NoppesUtilPlayer.java +++ b/src/main/java/noppes/npcs/NoppesUtilPlayer.java @@ -1,8 +1,6 @@ package noppes.npcs; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.enums.EnumSoundOperation; import kamkeel.npcs.network.packets.data.*; diff --git a/src/main/java/noppes/npcs/NoppesUtilServer.java b/src/main/java/noppes/npcs/NoppesUtilServer.java index cbda4ae2d..41ae71b34 100644 --- a/src/main/java/noppes/npcs/NoppesUtilServer.java +++ b/src/main/java/noppes/npcs/NoppesUtilServer.java @@ -3,19 +3,20 @@ package noppes.npcs; import io.netty.buffer.ByteBuf; import kamkeel.npcs.controllers.SyncController; import kamkeel.npcs.network.PacketHandler; +import kamkeel.npcs.network.packets.data.ParticlePacket; +import kamkeel.npcs.network.packets.data.PlayerDataInfoPacket; import kamkeel.npcs.network.packets.data.gui.GuiClosePacket; import kamkeel.npcs.network.packets.data.gui.GuiErrorPacket; import kamkeel.npcs.network.packets.data.gui.GuiOpenPacket; +import kamkeel.npcs.network.packets.data.gui.GuiTeleporterPacket; import kamkeel.npcs.network.packets.data.large.GuiDataPacket; import kamkeel.npcs.network.packets.data.large.ScrollDataPacket; import kamkeel.npcs.network.packets.data.large.ScrollListPacket; -import kamkeel.npcs.network.packets.data.npc.DialogPacket; -import kamkeel.npcs.network.packets.data.ParticlePacket; -import kamkeel.npcs.network.packets.data.script.ScriptedParticlePacket; import kamkeel.npcs.network.packets.data.npc.DeleteNpcPacket; +import kamkeel.npcs.network.packets.data.npc.DialogPacket; import kamkeel.npcs.network.packets.data.npc.EditNpcPacket; import kamkeel.npcs.network.packets.data.npc.RolePacket; -import kamkeel.npcs.network.packets.data.gui.GuiTeleporterPacket; +import kamkeel.npcs.network.packets.data.script.ScriptedParticlePacket; import kamkeel.npcs.util.ByteBufUtils; import net.minecraft.command.server.CommandBlockLogic; import net.minecraft.entity.Entity; @@ -975,4 +976,142 @@ public class NoppesUtilServer { sb.append(seconds).append(" second").append(seconds == 1 ? "" : "s"); return sb.toString(); } + + /** + * Retrieves the player's data from the existing PlayerDataController and sends + * a large packet to the client containing all the maps, including categories. + */ + public static void sendPlayerDataInfo(String playerName, EntityPlayerMP player) { + PlayerData playerdata; + EntityPlayer pl = MinecraftServer.getServer().getConfigurationManager().func_152612_a(playerName); + if(pl == null) + playerdata = PlayerDataController.Instance.getDataFromUsername(playerName); + else + playerdata = PlayerDataController.Instance.getPlayerData(pl); + + // Assemble quest maps: + Map questActiveMap = new HashMap<>(); + Map questFinishedMap = new HashMap<>(); + Map questCategoriesMap = new HashMap<>(); + QuestController qc = QuestController.Instance; + PlayerQuestData qData = playerdata.questData; + for (Integer questId : qData.activeQuests.keySet()) { + if(!qc.quests.containsKey(questId)) + continue; + Quest quest = qc.quests.get(questId); + questActiveMap.put(quest.category.title + ": " + quest.title, questId); + if (!questCategoriesMap.containsKey(quest.category.title)) + questCategoriesMap.put(quest.category.title, quest.category.id); + } + for (Integer questId : qData.finishedQuests.keySet()) { + if(!qc.quests.containsKey(questId)) + continue; + Quest quest = qc.quests.get(questId); + questFinishedMap.put(quest.category.title + ": " + quest.title, questId); + if (!questCategoriesMap.containsKey(quest.category.title)) + questCategoriesMap.put(quest.category.title, quest.category.id); + } + + // Assemble dialog maps: + Map dialogReadMap = new HashMap<>(); + Map dialogCategoriesMap = new HashMap<>(); + PlayerDialogData dData = playerdata.dialogData; + for (Integer dialogId : dData.dialogsRead) { + if(!DialogController.Instance.dialogs.containsKey(dialogId)) + continue; + Dialog dialog = DialogController.Instance.dialogs.get(dialogId); + dialogReadMap.put(dialog.category.title + ": " + dialog.title, dialogId); + if (!dialogCategoriesMap.containsKey(dialog.category.title)) + dialogCategoriesMap.put(dialog.category.title, dialog.category.id); + } + + // Assemble transport maps: + Map transportLocationsMap = new HashMap<>(); + Map transportCategoriesMap = new HashMap<>(); + PlayerTransportData tData = playerdata.transportData; + TransportController tc = TransportController.getInstance(); + for (Integer id : tData.transports) { + TransportLocation location = tc.getTransport(id); + if(location == null) + continue; + transportLocationsMap.put(location.category.title + ": " + location.name, id); + if (!transportCategoriesMap.containsKey(location.category.title)) + transportCategoriesMap.put(location.category.title, location.category.id); + } + + // Assemble bank map: + Map bankMap = new HashMap<>(); + PlayerBankData bData = playerdata.bankData; + BankController bc = BankController.getInstance(); + for (Integer bankId : bData.banks.keySet()) { + if(!bc.banks.containsKey(bankId)) + continue; + Bank bank = bc.banks.get(bankId); + bankMap.put(bank.name, bankId); + } + + // Assemble faction map: + Map factionMap = new HashMap<>(); + PlayerFactionData fData = playerdata.factionData; + FactionController fc = FactionController.getInstance(); + for (Integer factionId : fData.factionData.keySet()) { + if(!fc.factions.containsKey(factionId)) + continue; + Faction faction = fc.factions.get(factionId); + factionMap.put(faction.name + "(" + fData.getFactionPoints(factionId) + ")", factionId); + } + + // Send the full packet with categories, active/finished data, dialogs, transports, banks, and factions. + PlayerDataInfoPacket packet = new PlayerDataInfoPacket(playerName, + questCategoriesMap, questActiveMap, questFinishedMap, + dialogCategoriesMap, dialogReadMap, + transportCategoriesMap, transportLocationsMap, + bankMap, factionMap); + PacketHandler.Instance.sendToPlayer(packet, player); + } + + /** + * Removes a specific data entry from the player's data. + * + * The tabType parameter is used as follows: + * 0: Quest – remove from both activeQuests and finishedQuests. + * 1: Dialog – remove from dialogsRead. + * 2: Transport – remove from transports. + * 3: Bank – remove from banks. + * 4: Factions – remove from factionData. + * + * The selectedKey is expected to be the string representation of the entry's ID. + */ + public static void removePlayerDataInfo(String playerName, int tabType, int value, EntityPlayerMP player) { + EntityPlayer pl = MinecraftServer.getServer().getConfigurationManager().func_152612_a(playerName); + PlayerData playerdata; + + EnumPlayerData enumPlayerData = EnumPlayerData.values()[tabType]; + if(pl == null) + playerdata = PlayerDataController.Instance.getDataFromUsername(playerName); + else + playerdata = PlayerDataController.Instance.getPlayerData(pl); + + if(enumPlayerData == EnumPlayerData.Quest) { // Quest removal + playerdata.questData.activeQuests.remove(value); + playerdata.questData.finishedQuests.remove(value); + } + if(enumPlayerData == EnumPlayerData.Dialog){ // Dialog removal + playerdata.dialogData.dialogsRead.remove(value); + } + if(enumPlayerData == EnumPlayerData.Transport) { // Transport removal + playerdata.transportData.transports.remove(value); + } + if(enumPlayerData == EnumPlayerData.Bank) { // Bank removal + playerdata.bankData.banks.remove(value); + } + if(enumPlayerData == EnumPlayerData.Factions) { // Faction removal + playerdata.factionData.factionData.remove(value); + } + playerdata.save(); + + if(pl != null) { + SyncController.syncPlayer((EntityPlayerMP) pl); + } + } } diff --git a/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java b/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java index 0c4dab046..2247d4448 100644 --- a/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java +++ b/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java @@ -23,6 +23,7 @@ import net.minecraftforge.event.entity.player.*; import net.minecraftforge.event.world.BlockEvent; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.item.IItemCustomizable; +import noppes.npcs.attribute.PlayerAttributeManager; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.CustomEffectController; import noppes.npcs.controllers.PartyController; @@ -30,9 +31,9 @@ import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.data.*; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.items.ItemNpcTool; import noppes.npcs.quests.QuestItem; import noppes.npcs.scripted.NpcAPI; -import noppes.npcs.scripted.item.ScriptCustomItem; import static noppes.npcs.config.ConfigMain.TrackedQuestUpdateFrequency; @@ -47,7 +48,7 @@ public class ScriptPlayerEventHandler { if (event.side == Side.SERVER && event.phase == TickEvent.Phase.START) { EntityPlayer player = event.player; - if (player.ticksExisted%10 == 0) { + if (player.ticksExisted % 10 == 0) { PlayerDataScript handler = ScriptController.Instance.playerScripts; IPlayer scriptPlayer = (IPlayer) NpcAPI.Instance().getIEntity(player); EventHooks.onPlayerTick(handler, scriptPlayer); @@ -59,6 +60,8 @@ public class ScriptPlayerEventHandler { EventHooks.onScriptItemUpdate(isw, player); } } + + PlayerAttributeManager.getTracker(player.getUniqueID()).updateIfChanged(player); } if (PlayerDataController.Instance != null) { @@ -155,6 +158,11 @@ public class ScriptPlayerEventHandler { if(event.getPlayer() == null || event.getPlayer().worldObj == null) return; + if(event.getPlayer().getHeldItem() != null && event.getPlayer().getHeldItem().getItem() instanceof ItemNpcTool){ + event.setCanceled(true); + return; + } + if(!event.getPlayer().worldObj.isRemote && event.world instanceof WorldServer) { PlayerDataScript handler = ScriptController.Instance.playerScripts; IPlayer scriptPlayer = (IPlayer) NpcAPI.Instance().getIEntity(event.getPlayer()); diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index 2e61e2624..ebccd424d 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -22,7 +22,6 @@ import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; @@ -41,10 +40,12 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; import net.minecraftforge.event.terraingen.PopulateChunkEvent; import noppes.npcs.blocks.tiles.ITileIcon; -import noppes.npcs.blocks.tiles.TileBanner; import noppes.npcs.config.ConfigDebug; import noppes.npcs.config.ConfigMain; -import noppes.npcs.constants.*; +import noppes.npcs.constants.EnumGuiType; +import noppes.npcs.constants.EnumPartyObjectives; +import noppes.npcs.constants.EnumQuestType; +import noppes.npcs.constants.EnumRoleType; import noppes.npcs.controllers.PartyController; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.ServerCloneController; diff --git a/src/main/java/noppes/npcs/ServerTickHandler.java b/src/main/java/noppes/npcs/ServerTickHandler.java index e793e8db0..95d1332ba 100644 --- a/src/main/java/noppes/npcs/ServerTickHandler.java +++ b/src/main/java/noppes/npcs/ServerTickHandler.java @@ -54,7 +54,7 @@ public class ServerTickHandler { SyncController.syncPlayer(player); SyncController.syncEffects(player); - ProfileController.login(player); + ProfileController.Instance.login(player); } @SubscribeEvent diff --git a/src/main/java/noppes/npcs/attribute/AttributeController.java b/src/main/java/noppes/npcs/attribute/AttributeController.java new file mode 100644 index 000000000..505062895 --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/AttributeController.java @@ -0,0 +1,30 @@ +package noppes.npcs.attribute; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * AttributeController is the central registry for attribute definitions. + * It ensures that keys are unique. + */ +public class AttributeController { + private static final Map definitions = new HashMap<>(); + + public static AttributeDefinition registerAttribute(String key, String displayName, AttributeValueType valueType) { + if (definitions.containsKey(key)) { + throw new IllegalArgumentException("Attribute already registered with key: " + key); + } + AttributeDefinition def = new AttributeDefinition(key, displayName, valueType); + definitions.put(key, def); + return def; + } + + public static AttributeDefinition getAttribute(String key) { + return definitions.get(key); + } + + public static Collection getAllAttributes() { + return definitions.values(); + } +} diff --git a/src/main/java/noppes/npcs/attribute/AttributeDefinition.java b/src/main/java/noppes/npcs/attribute/AttributeDefinition.java new file mode 100644 index 000000000..f68995a0b --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/AttributeDefinition.java @@ -0,0 +1,30 @@ +package noppes.npcs.attribute; + +/** + * Defines a valid attribute – for example, "cnpc:main_attack_flat" (a flat bonus) + * or "cnpc:main_attack_percent" (a percent bonus). These definitions are registered + * once in the AttributeController. + */ +public class AttributeDefinition { + private final String key; // e.g., "rpgcore:main_attack_flat" + private final String displayName; // Human‑readable name + private final AttributeValueType attributeValueType; + + public AttributeDefinition(String key, String displayName, AttributeValueType attributeValueType) { + this.key = key; + this.displayName = displayName; + this.attributeValueType = attributeValueType; + } + + public String getKey() { + return key; + } + + public String getDisplayName() { + return displayName; + } + + public AttributeValueType getOperation() { + return attributeValueType; + } +} diff --git a/src/main/java/noppes/npcs/attribute/AttributeKeys.java b/src/main/java/noppes/npcs/attribute/AttributeKeys.java new file mode 100644 index 000000000..4e50af762 --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/AttributeKeys.java @@ -0,0 +1,17 @@ +package noppes.npcs.attribute; + +public final class AttributeKeys { + public static final String MAIN_ATTACK_FLAT = "rpgcore:main_attack_flat"; + public static final String MAIN_ATTACK_PERCENT = "rpgcore:main_attack_percent"; + public static final String HEALTH = "rpgcore:health"; + public static final String CRITICAL_CHANCE_PERCENT = "rpgcore:critical_chance_percent"; + public static final String CRITICAL_DAMAGE_FLAT = "rpgcore:critical_damage_flat"; + + // Magic–based attribute keys: + public static final String MAGIC_DAMAGE_FLAT = "rpgcore:magic_damage_flat"; + public static final String MAGIC_DAMAGE_PERCENT = "rpgcore:magic_damage_percent"; + public static final String MAGIC_DEFENSE_FLAT = "rpgcore:magic_defense_flat"; + public static final String MAGIC_RESISTANCE_PERCENT = "rpgcore:magic_resistance_percent"; + + private AttributeKeys() { } +} diff --git a/src/main/java/noppes/npcs/attribute/AttributeModifier.java b/src/main/java/noppes/npcs/attribute/AttributeModifier.java new file mode 100644 index 000000000..ccaed7c15 --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/AttributeModifier.java @@ -0,0 +1,37 @@ +package noppes.npcs.attribute; + +import java.util.UUID; + +/** + * An AttributeModifier represents a bonus (or penalty) that is applied to an attribute. + * It carries a UUID, a human–readable name, an amount, and a type (FLAT, PERCENT, etc). + */ +public class AttributeModifier { + private final UUID id; + private final String name; + private final double amount; + private final AttributeValueType valueType; + + public AttributeModifier(UUID id, String name, double amount, AttributeValueType valueType) { + this.id = id; + this.name = name; + this.amount = amount; + this.valueType = valueType; + } + + public UUID getId() { + return id; + } + + public String getName() { + return name; + } + + public double getAmount() { + return amount; + } + + public AttributeValueType getValueType() { + return valueType; + } +} diff --git a/src/main/java/noppes/npcs/attribute/AttributeValueType.java b/src/main/java/noppes/npcs/attribute/AttributeValueType.java new file mode 100644 index 000000000..26c35b6ff --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/AttributeValueType.java @@ -0,0 +1,7 @@ +package noppes.npcs.attribute; + +public enum AttributeValueType { + FLAT, // e.g., +10 Health or +3 Damage + PERCENT, // e.g., +0.25 means +25% bonus + MAGIC // Represents a container of magic–based values (summed up as a double) +} diff --git a/src/main/java/noppes/npcs/attribute/CNPCItemAttributeHelper.java b/src/main/java/noppes/npcs/attribute/CNPCItemAttributeHelper.java new file mode 100644 index 000000000..02a38b4eb --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/CNPCItemAttributeHelper.java @@ -0,0 +1,78 @@ +package noppes.npcs.attribute; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import java.util.Set; +import java.util.HashMap; +import java.util.Map; + +/** + * Provides helper functions to write/read item attributes to/from NBT. + * Non–magic attributes are stored under a compound tag (TAG_ROOT), + * and magic attributes are stored as a compound mapping (by magic ID) under specific keys. + */ +public class CNPCItemAttributeHelper { + public static final String TAG_ROOT = "CNPCAttributes"; + + public static void applyAttribute(ItemStack item, String attributeKey, double value) { + if (item == null) return; + if (item.stackTagCompound == null) { + item.stackTagCompound = new NBTTagCompound(); + } + NBTTagCompound root = item.stackTagCompound; + NBTTagCompound attrTag; + if (root.hasKey(TAG_ROOT)) { + attrTag = root.getCompoundTag(TAG_ROOT); + } else { + attrTag = new NBTTagCompound(); + } + attrTag.setDouble(attributeKey, value); + root.setTag(TAG_ROOT, attrTag); + } + + public static Map readAttributes(ItemStack item) { + Map map = new HashMap<>(); + if (item == null || item.stackTagCompound == null) return map; + NBTTagCompound root = item.stackTagCompound; + if (root.hasKey(TAG_ROOT)) { + NBTTagCompound attrTag = root.getCompoundTag(TAG_ROOT); + Set keys = attrTag.func_150296_c(); + for (String key : keys) { + map.put(key, attrTag.getDouble(key)); + } + } + return map; + } + + public static Map readMagicAttributeMap(ItemStack item, String attributeTag) { + Map map = new HashMap<>(); + if (item == null || item.stackTagCompound == null) return map; + if (item.stackTagCompound.hasKey(attributeTag)) { + NBTTagCompound magicMap = item.stackTagCompound.getCompoundTag(attributeTag); + Set keys = magicMap.func_150296_c(); + for (String key : keys) { + try { + int magicId = Integer.parseInt(key); + map.put(magicId, magicMap.getDouble(key)); + } catch (NumberFormatException e) { + // Skip invalid key. + } + } + } + return map; + } + + public static void writeMagicAttribute(ItemStack item, String attributeTag, int magicId, double value) { + if (item == null) return; + if (item.stackTagCompound == null) + item.stackTagCompound = new NBTTagCompound(); + NBTTagCompound magicMap; + if (item.stackTagCompound.hasKey(attributeTag)) { + magicMap = item.stackTagCompound.getCompoundTag(attributeTag); + } else { + magicMap = new NBTTagCompound(); + } + magicMap.setDouble(String.valueOf(magicId), value); + item.stackTagCompound.setTag(attributeTag, magicMap); + } +} diff --git a/src/main/java/noppes/npcs/attribute/CustomAttributeMap.java b/src/main/java/noppes/npcs/attribute/CustomAttributeMap.java new file mode 100644 index 000000000..be4edecff --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/CustomAttributeMap.java @@ -0,0 +1,29 @@ +package noppes.npcs.attribute; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * CustomAttributeMap holds a set of attribute instances for an entity (or item). + */ +public class CustomAttributeMap { + private final Map map = new HashMap<>(); + + public IAttributeInstance registerAttribute(AttributeDefinition attribute, double baseValue) { + if (map.containsKey(attribute)) { + throw new IllegalArgumentException("Attribute already registered: " + attribute.getKey()); + } + IAttributeInstance instance = new ModifiableAttributeInstance(attribute, baseValue); + map.put(attribute, instance); + return instance; + } + + public IAttributeInstance getAttributeInstance(AttributeDefinition attribute) { + return map.get(attribute); + } + + public Collection getAllAttributes() { + return map.values(); + } +} diff --git a/src/main/java/noppes/npcs/attribute/DamageCalculator.java b/src/main/java/noppes/npcs/attribute/DamageCalculator.java new file mode 100644 index 000000000..d776b1929 --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/DamageCalculator.java @@ -0,0 +1,39 @@ +package noppes.npcs.attribute; + +import java.util.Random; + +/** + * Calculates damage using cached (aggregated) offensive and defensive ratings from players. + * The formula here is simple: baseDamage = attacker.getOffense() - defender.getDefense(), + * then a critical chance is applied (if a random roll is below the attacker's crit chance, + * damage is doubled and a flat crit bonus is added). + */ +public class DamageCalculator { + private static final Random random = new Random(); + + /** + * Calculates damage given attacker and defender attribute trackers. + */ + public static double calculateDamage(PlayerAttributeTracker attacker, PlayerAttributeTracker defender) { + double offense = attacker.getOffense(); + double defense = defender.getDefense(); + double damage = offense - defense; + + // Process critical hit chance from attacker's aggregated non-magic attributes. + double critChance = attacker.getAttributeValue(ModAttributes.CRITICAL_CHANCE_PERCENT); + double critBonus = attacker.getAttributeValue(ModAttributes.CRITICAL_DAMAGE_FLAT); + if (random.nextDouble() < critChance) { + damage = damage * 2 + critBonus; + } + return Math.max(damage, 0); + } + + /** + * Optionally, calculates damage for a specific magic type. + */ + public static double calculateMagicDamage(PlayerAttributeTracker attacker, PlayerAttributeTracker defender, int magicId) { + double offense = attacker.getOffense(magicId); + double defense = defender.getDefense(magicId); + return Math.max(offense - defense, 0); + } +} diff --git a/src/main/java/noppes/npcs/attribute/IAttributeInstance.java b/src/main/java/noppes/npcs/attribute/IAttributeInstance.java new file mode 100644 index 000000000..5aadb8efd --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/IAttributeInstance.java @@ -0,0 +1,16 @@ +package noppes.npcs.attribute; + +import java.util.Collection; + +/** + * IAttributeInstance represents an instance of an attribute (with a base value and applied modifiers). + */ +public interface IAttributeInstance { + AttributeDefinition getAttribute(); + double getBaseValue(); + void setBaseValue(double value); + void applyModifier(AttributeModifier modifier); + void removeModifier(AttributeModifier modifier); + Collection getModifiers(); + double getAttributeValue(); // Final computed value after modifiers +} diff --git a/src/main/java/noppes/npcs/attribute/ModAttributes.java b/src/main/java/noppes/npcs/attribute/ModAttributes.java new file mode 100644 index 000000000..d780b88bf --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/ModAttributes.java @@ -0,0 +1,30 @@ +package noppes.npcs.attribute; + +/** + * ModAttributes registers the core attributes (both non–magic and magic–based). + */ +public class ModAttributes { + public static final AttributeDefinition MAIN_ATTACK_FLAT; + public static final AttributeDefinition MAIN_ATTACK_PERCENT; + public static final AttributeDefinition HEALTH; + public static final AttributeDefinition CRITICAL_CHANCE_PERCENT; + public static final AttributeDefinition CRITICAL_DAMAGE_FLAT; + + public static final AttributeDefinition MAGIC_DAMAGE_FLAT; + public static final AttributeDefinition MAGIC_DAMAGE_PERCENT; + public static final AttributeDefinition MAGIC_DEFENSE_FLAT; + public static final AttributeDefinition MAGIC_RESISTANCE_PERCENT; + + static { + MAIN_ATTACK_FLAT = AttributeController.registerAttribute(AttributeKeys.MAIN_ATTACK_FLAT, "Main Attack Damage", AttributeValueType.FLAT); + MAIN_ATTACK_PERCENT = AttributeController.registerAttribute(AttributeKeys.MAIN_ATTACK_PERCENT, "Main Attack Damage (%)", AttributeValueType.PERCENT); + HEALTH = AttributeController.registerAttribute(AttributeKeys.HEALTH, "Health", AttributeValueType.FLAT); + CRITICAL_CHANCE_PERCENT = AttributeController.registerAttribute(AttributeKeys.CRITICAL_CHANCE_PERCENT, "Critical Chance (%)", AttributeValueType.PERCENT); + CRITICAL_DAMAGE_FLAT = AttributeController.registerAttribute(AttributeKeys.CRITICAL_DAMAGE_FLAT, "Critical Damage Bonus", AttributeValueType.FLAT); + + MAGIC_DAMAGE_FLAT = AttributeController.registerAttribute(AttributeKeys.MAGIC_DAMAGE_FLAT, "Magic Damage", AttributeValueType.MAGIC); + MAGIC_DAMAGE_PERCENT = AttributeController.registerAttribute(AttributeKeys.MAGIC_DAMAGE_PERCENT, "Magic Damage (%)", AttributeValueType.MAGIC); + MAGIC_DEFENSE_FLAT = AttributeController.registerAttribute(AttributeKeys.MAGIC_DEFENSE_FLAT, "Magic Defense", AttributeValueType.MAGIC); + MAGIC_RESISTANCE_PERCENT = AttributeController.registerAttribute(AttributeKeys.MAGIC_RESISTANCE_PERCENT, "Magic Resistance (%)", AttributeValueType.MAGIC); + } +} diff --git a/src/main/java/noppes/npcs/attribute/ModifiableAttributeInstance.java b/src/main/java/noppes/npcs/attribute/ModifiableAttributeInstance.java new file mode 100644 index 000000000..5645165c3 --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/ModifiableAttributeInstance.java @@ -0,0 +1,66 @@ +package noppes.npcs.attribute; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class ModifiableAttributeInstance implements IAttributeInstance { + private final AttributeDefinition attribute; + private double baseValue; + private final Set modifiers = new HashSet<>(); + + public ModifiableAttributeInstance(AttributeDefinition attribute, double baseValue) { + this.attribute = attribute; + this.baseValue = baseValue; + } + + @Override + public AttributeDefinition getAttribute() { + return attribute; + } + + @Override + public double getBaseValue() { + return baseValue; + } + + @Override + public void setBaseValue(double value) { + this.baseValue = value; + } + + @Override + public void applyModifier(AttributeModifier modifier) { + modifiers.add(modifier); + } + + @Override + public void removeModifier(AttributeModifier modifier) { + modifiers.remove(modifier); + } + + @Override + public Collection getModifiers() { + return modifiers; + } + + @Override + public double getAttributeValue() { + double finalValue = baseValue; + // Apply FLAT modifiers + for (AttributeModifier mod : modifiers) { + if (mod.getValueType() == AttributeValueType.FLAT) { + finalValue += mod.getAmount(); + } + } + // Apply PERCENT modifiers additively. + double percentSum = 0.0; + for (AttributeModifier mod : modifiers) { + if (mod.getValueType() == AttributeValueType.PERCENT) { + percentSum += mod.getAmount(); + } + } + finalValue *= (1 + percentSum); + return finalValue; + } +} diff --git a/src/main/java/noppes/npcs/attribute/PlayerAttributeManager.java b/src/main/java/noppes/npcs/attribute/PlayerAttributeManager.java new file mode 100644 index 000000000..9b6a3dbef --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/PlayerAttributeManager.java @@ -0,0 +1,31 @@ +package noppes.npcs.attribute; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import net.minecraft.entity.player.EntityPlayer; + +/** + * PlayerAttributeManager maps player UUIDs to their attribute trackers. + */ +public class PlayerAttributeManager { + private static final Map trackers = new HashMap<>(); + + public static PlayerAttributeTracker getTracker(UUID playerId) { + return trackers.computeIfAbsent(playerId, id -> new PlayerAttributeTracker(id)); + } + + public static void removeTracker(UUID playerId) { + trackers.remove(playerId); + } + + /** + * Update all trackers (e.g. called every 10 ticks for all online players). + */ + public static void updateAllTrackers(Iterable players) { + for (EntityPlayer player : players) { + PlayerAttributeTracker tracker = getTracker(player.getUniqueID()); + tracker.updateIfChanged(player); + } + } +} diff --git a/src/main/java/noppes/npcs/attribute/PlayerAttributeTracker.java b/src/main/java/noppes/npcs/attribute/PlayerAttributeTracker.java new file mode 100644 index 000000000..b4aae36bb --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/PlayerAttributeTracker.java @@ -0,0 +1,202 @@ +package noppes.npcs.attribute; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import java.util.Map.Entry; + +/** + * Aggregates a player's attributes based on the attributes found on their held item and armor. + * Non–magic attributes are stored in a CustomAttributeMap (using string keys via AttributeController). + * Magic attributes (offense and defense) are aggregated as maps, keyed by magic type. + * This tracker uses a PlayerEquipmentTracker to keep track of the player's equipment, + * and recalculates only when the player's held item or armor changes. + */ +public class PlayerAttributeTracker { + private final UUID playerId; + private CustomAttributeMap aggregatedAttributes = new CustomAttributeMap(); + + // Aggregated magic offensive values: + private final Map aggregatedMagicDamageFlat = new HashMap<>(); + private final Map aggregatedMagicDamagePercent = new HashMap<>(); + // Aggregated magic defensive values: + private final Map aggregatedMagicDefenseFlat = new HashMap<>(); + private final Map aggregatedMagicResistancePercent = new HashMap<>(); + + // Stores the last-known equipment. + private PlayerEquipmentTracker equipmentTracker = new PlayerEquipmentTracker(); + + public PlayerAttributeTracker(UUID playerId) { + this.playerId = playerId; + // Initialize equipmentTracker from a null player (will be updated on first tick). + recalcAttributes(null); + } + + public CustomAttributeMap getAggregatedAttributes() { + return aggregatedAttributes; + } + + /** + * Recalculates the aggregated attributes from the player's equipment. + * Non–magic attributes are read from each item's CNPCAttributes, and magic attributes + * are aggregated by summing values from their NBT maps. + */ + public void recalcAttributes(EntityPlayer player) { + aggregatedAttributes = new CustomAttributeMap(); + + // Reset magic aggregates. + aggregatedMagicDamageFlat.clear(); + aggregatedMagicDamagePercent.clear(); + aggregatedMagicDefenseFlat.clear(); + aggregatedMagicResistancePercent.clear(); + + if (player != null) { + // Update equipmentTracker with the player's current equipment. + PlayerEquipmentTracker currentEquip = new PlayerEquipmentTracker(); + currentEquip.updateFrom(player); + + // Process held item (offense). + ItemStack held = currentEquip.heldItem; + if (held != null) { + // Process non-magic attributes. + for (Entry entry : CNPCItemAttributeHelper.readAttributes(held).entrySet()) { + String key = entry.getKey(); + double value = entry.getValue(); + AttributeDefinition def = AttributeController.getAttribute(key); + if (def != null) { + IAttributeInstance inst = aggregatedAttributes.getAttributeInstance(def); + if (inst == null) { + inst = aggregatedAttributes.registerAttribute(def, 0.0); + } + inst.setBaseValue(inst.getBaseValue() + value); + } + } + // Process magic offense. + Map magicFlat = CNPCItemAttributeHelper.readMagicAttributeMap(held, AttributeKeys.MAGIC_DAMAGE_FLAT); + for (Entry entry : magicFlat.entrySet()) { + int magicId = entry.getKey(); + double value = entry.getValue(); + aggregatedMagicDamageFlat.put(magicId, aggregatedMagicDamageFlat.getOrDefault(magicId, 0.0) + value); + } + Map magicPercent = CNPCItemAttributeHelper.readMagicAttributeMap(held, AttributeKeys.MAGIC_DAMAGE_PERCENT); + for (Entry entry : magicPercent.entrySet()) { + int magicId = entry.getKey(); + double value = entry.getValue(); + aggregatedMagicDamagePercent.put(magicId, aggregatedMagicDamagePercent.getOrDefault(magicId, 0.0) + value); + } + } + // Process armor (defense). + // Assuming armor order: 0: boots, 1: leggings, 2: chestplate, 3: helmet. + ItemStack[] armor = new ItemStack[] { currentEquip.boots, currentEquip.leggings, currentEquip.chestplate, currentEquip.helmet }; + for (ItemStack piece : armor) { + if (piece != null) { + // Process non-magic attributes. + for (Entry entry : CNPCItemAttributeHelper.readAttributes(piece).entrySet()) { + String key = entry.getKey(); + double value = entry.getValue(); + AttributeDefinition def = AttributeController.getAttribute(key); + if (def != null) { + IAttributeInstance inst = aggregatedAttributes.getAttributeInstance(def); + if (inst == null) { + inst = aggregatedAttributes.registerAttribute(def, 0.0); + } + inst.setBaseValue(inst.getBaseValue() + value); + } + } + // Process magic defense. + Map magicDefFlat = CNPCItemAttributeHelper.readMagicAttributeMap(piece, AttributeKeys.MAGIC_DEFENSE_FLAT); + for (Entry entry : magicDefFlat.entrySet()) { + int magicId = entry.getKey(); + double value = entry.getValue(); + aggregatedMagicDefenseFlat.put(magicId, aggregatedMagicDefenseFlat.getOrDefault(magicId, 0.0) + value); + } + Map magicResist = CNPCItemAttributeHelper.readMagicAttributeMap(piece, AttributeKeys.MAGIC_RESISTANCE_PERCENT); + for (Entry entry : magicResist.entrySet()) { + int magicId = entry.getKey(); + double value = entry.getValue(); + aggregatedMagicResistancePercent.put(magicId, aggregatedMagicResistancePercent.getOrDefault(magicId, 0.0) + value); + } + } + } + // Update our stored equipment. + equipmentTracker = currentEquip; + } + } + + /** + * Checks if the player's equipment has changed by comparing stored equipment with the current equipment. + * This should be called periodically (e.g., every 10 ticks). + */ + public void updateIfChanged(EntityPlayer player) { + PlayerEquipmentTracker currentEquip = new PlayerEquipmentTracker(); + currentEquip.updateFrom(player); + if (!equipmentTracker.equals(player)) { + recalcAttributes(player); + } + } + + /** + * Returns the aggregated non-magic value for a given attribute definition. + */ + public double getAttributeValue(AttributeDefinition def) { + IAttributeInstance inst = aggregatedAttributes.getAttributeInstance(def); + return inst != null ? inst.getAttributeValue() : 0.0; + } + + /** + * Overall offense is calculated as: + * Non-magic offense (MAIN_ATTACK_FLAT*(1+MAIN_ATTACK_PERCENT)) + * plus the sum over all magic offense: for each magic type, flat*(1+percent). + */ + public double getOffense() { + double nonMagic = 0.0; + AttributeDefinition atkFlat = AttributeController.getAttribute(AttributeKeys.MAIN_ATTACK_FLAT); + AttributeDefinition atkPercent = AttributeController.getAttribute(AttributeKeys.MAIN_ATTACK_PERCENT); + if (atkFlat != null && atkPercent != null) { + nonMagic = getAttributeValue(atkFlat) * (1 + getAttributeValue(atkPercent)); + } + double magicOffense = 0.0; + for (Entry entry : aggregatedMagicDamageFlat.entrySet()) { + int magicId = entry.getKey(); + double flat = entry.getValue(); + double percent = aggregatedMagicDamagePercent.getOrDefault(magicId, 0.0); + magicOffense += flat * (1 + percent); + } + return nonMagic + magicOffense; + } + + /** + * Returns offense for a specific magic type. + */ + public double getOffense(int magicId) { + double flat = aggregatedMagicDamageFlat.getOrDefault(magicId, 0.0); + double percent = aggregatedMagicDamagePercent.getOrDefault(magicId, 0.0); + return flat * (1 + percent); + } + + /** + * Overall defense is calculated solely from magic defensive attributes. + * (HEALTH is managed separately.) + */ + public double getDefense() { + double magicDefense = 0.0; + for (Entry entry : aggregatedMagicDefenseFlat.entrySet()) { + int magicId = entry.getKey(); + double flat = entry.getValue(); + double percent = aggregatedMagicResistancePercent.getOrDefault(magicId, 0.0); + magicDefense += flat * (1 + percent); + } + return magicDefense; + } + + /** + * Returns defense for a specific magic type. + */ + public double getDefense(int magicId) { + double flat = aggregatedMagicDefenseFlat.getOrDefault(magicId, 0.0); + double percent = aggregatedMagicResistancePercent.getOrDefault(magicId, 0.0); + return flat * (1 + percent); + } +} diff --git a/src/main/java/noppes/npcs/attribute/PlayerEquipmentTracker.java b/src/main/java/noppes/npcs/attribute/PlayerEquipmentTracker.java new file mode 100644 index 000000000..83372f690 --- /dev/null +++ b/src/main/java/noppes/npcs/attribute/PlayerEquipmentTracker.java @@ -0,0 +1,65 @@ +package noppes.npcs.attribute; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +public class PlayerEquipmentTracker { + public ItemStack heldItem; + public ItemStack helmet; + public ItemStack chestplate; + public ItemStack leggings; + public ItemStack boots; + + /** + * Updates the stored equipment based on the player's current held item and armor. + */ + public void updateFrom(EntityPlayer player) { + heldItem = copyIfNotNull(player.getHeldItem()); + ItemStack[] armor = player.inventory.armorInventory; + // Armor inventory order: 0=boots, 1=leggings, 2=chestplate, 3=helmet. + boots = copyIfNotNull(armor[0]); + leggings = copyIfNotNull(armor[1]); + chestplate = copyIfNotNull(armor[2]); + helmet = copyIfNotNull(armor[3]); + } + + /** + * Compares the stored equipment with the player's current equipment. + * Ignores changes like durability by comparing the item and the CNPCAttributes NBT only. + */ + public boolean equals(EntityPlayer player) { + if (player == null) return false; + if (!areItemStacksEquivalent(heldItem, player.getHeldItem())) return false; + ItemStack[] armor = player.inventory.armorInventory; + if (!areItemStacksEquivalent(boots, armor[0])) return false; + if (!areItemStacksEquivalent(leggings, armor[1])) return false; + if (!areItemStacksEquivalent(chestplate, armor[2])) return false; + if (!areItemStacksEquivalent(helmet, armor[3])) return false; + return true; + } + + /** + * Returns a copy of the given ItemStack, or null if it is null. + */ + private ItemStack copyIfNotNull(ItemStack stack) { + return (stack == null) ? null : stack.copy(); + } + + /** + * Compares two ItemStacks for equivalence, ignoring durability differences. + * It checks if the items are the same and if the "CNPCAttributes" NBT compound is equal. + */ + private boolean areItemStacksEquivalent(ItemStack a, ItemStack b) { + if (a == b) return true; + if (a == null || b == null) return false; + if (a.getItem() != b.getItem()) return false; + NBTTagCompound tagA = a.stackTagCompound; + NBTTagCompound tagB = b.stackTagCompound; + String attrA = (tagA != null && tagA.hasKey(CNPCItemAttributeHelper.TAG_ROOT)) + ? tagA.getCompoundTag(CNPCItemAttributeHelper.TAG_ROOT).toString() : ""; + String attrB = (tagB != null && tagB.hasKey(CNPCItemAttributeHelper.TAG_ROOT)) + ? tagB.getCompoundTag(CNPCItemAttributeHelper.TAG_ROOT).toString() : ""; + return attrA.equals(attrB); + } +} diff --git a/src/main/java/noppes/npcs/blocks/BlockLantern.java b/src/main/java/noppes/npcs/blocks/BlockLantern.java index 6be362b7c..fa7db3c4f 100644 --- a/src/main/java/noppes/npcs/blocks/BlockLantern.java +++ b/src/main/java/noppes/npcs/blocks/BlockLantern.java @@ -10,8 +10,8 @@ import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import noppes.npcs.CustomItems; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileLamp; +import noppes.npcs.blocks.tiles.TileVariant; public class BlockLantern extends BlockLightable{ diff --git a/src/main/java/noppes/npcs/blocks/BlockPedestal.java b/src/main/java/noppes/npcs/blocks/BlockPedestal.java index 03ba7bd1e..06b907a09 100644 --- a/src/main/java/noppes/npcs/blocks/BlockPedestal.java +++ b/src/main/java/noppes/npcs/blocks/BlockPedestal.java @@ -14,9 +14,9 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileNpcContainer; import noppes.npcs.blocks.tiles.TilePedestal; +import noppes.npcs.blocks.tiles.TileVariant; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockShelf.java b/src/main/java/noppes/npcs/blocks/BlockShelf.java index ee0a8e4ca..1fda4c516 100644 --- a/src/main/java/noppes/npcs/blocks/BlockShelf.java +++ b/src/main/java/noppes/npcs/blocks/BlockShelf.java @@ -9,8 +9,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileShelf; +import noppes.npcs.blocks.tiles.TileVariant; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockShortLamp.java b/src/main/java/noppes/npcs/blocks/BlockShortLamp.java index f1a483610..0e2a8480b 100644 --- a/src/main/java/noppes/npcs/blocks/BlockShortLamp.java +++ b/src/main/java/noppes/npcs/blocks/BlockShortLamp.java @@ -23,7 +23,6 @@ import net.minecraft.world.World; import noppes.npcs.NoppesUtilServer; import noppes.npcs.blocks.tiles.TileColorable; import noppes.npcs.blocks.tiles.TileShortLamp; -import noppes.npcs.blocks.tiles.TileTallLamp; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockSign.java b/src/main/java/noppes/npcs/blocks/BlockSign.java index 8d5af1e2d..2233f6bc1 100644 --- a/src/main/java/noppes/npcs/blocks/BlockSign.java +++ b/src/main/java/noppes/npcs/blocks/BlockSign.java @@ -12,8 +12,8 @@ import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import noppes.npcs.blocks.tiles.TileBanner; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileSign; +import noppes.npcs.blocks.tiles.TileVariant; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockStool.java b/src/main/java/noppes/npcs/blocks/BlockStool.java index a5d426200..45314103f 100644 --- a/src/main/java/noppes/npcs/blocks/BlockStool.java +++ b/src/main/java/noppes/npcs/blocks/BlockStool.java @@ -16,8 +16,8 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileStool; +import noppes.npcs.blocks.tiles.TileVariant; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockTable.java b/src/main/java/noppes/npcs/blocks/BlockTable.java index 2c49f08a5..1169bc49b 100644 --- a/src/main/java/noppes/npcs/blocks/BlockTable.java +++ b/src/main/java/noppes/npcs/blocks/BlockTable.java @@ -1,13 +1,11 @@ package noppes.npcs.blocks; -import net.minecraft.block.Block; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import noppes.npcs.blocks.tiles.TileTable; diff --git a/src/main/java/noppes/npcs/blocks/BlockTallLamp.java b/src/main/java/noppes/npcs/blocks/BlockTallLamp.java index 9c5badea1..96bb0314a 100644 --- a/src/main/java/noppes/npcs/blocks/BlockTallLamp.java +++ b/src/main/java/noppes/npcs/blocks/BlockTallLamp.java @@ -21,7 +21,6 @@ import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import noppes.npcs.NoppesUtilServer; -import noppes.npcs.blocks.tiles.TileBanner; import noppes.npcs.blocks.tiles.TileColorable; import noppes.npcs.blocks.tiles.TileTallLamp; diff --git a/src/main/java/noppes/npcs/blocks/BlockTombstone.java b/src/main/java/noppes/npcs/blocks/BlockTombstone.java index 58ef784c1..987761666 100644 --- a/src/main/java/noppes/npcs/blocks/BlockTombstone.java +++ b/src/main/java/noppes/npcs/blocks/BlockTombstone.java @@ -22,8 +22,8 @@ import noppes.npcs.CustomNpcs; import noppes.npcs.CustomNpcsPermissions; import noppes.npcs.NoppesUtilServer; import noppes.npcs.blocks.tiles.TileBigSign; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileTombstone; +import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.constants.EnumGuiType; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockWallBanner.java b/src/main/java/noppes/npcs/blocks/BlockWallBanner.java index 165524e60..f219da7b2 100644 --- a/src/main/java/noppes/npcs/blocks/BlockWallBanner.java +++ b/src/main/java/noppes/npcs/blocks/BlockWallBanner.java @@ -18,7 +18,6 @@ import net.minecraft.util.*; import net.minecraft.world.World; import noppes.npcs.NoppesUtilServer; import noppes.npcs.blocks.tiles.TileColorable; -import noppes.npcs.blocks.tiles.TileCouchWool; import noppes.npcs.blocks.tiles.TileWallBanner; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/BlockWeaponRack.java b/src/main/java/noppes/npcs/blocks/BlockWeaponRack.java index b18efc5a5..41554f83a 100644 --- a/src/main/java/noppes/npcs/blocks/BlockWeaponRack.java +++ b/src/main/java/noppes/npcs/blocks/BlockWeaponRack.java @@ -13,8 +13,8 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileNpcContainer; +import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileWeaponRack; import java.util.List; diff --git a/src/main/java/noppes/npcs/blocks/tiles/TileColorable.java b/src/main/java/noppes/npcs/blocks/tiles/TileColorable.java index 2f1d7f978..e85efd0b5 100644 --- a/src/main/java/noppes/npcs/blocks/tiles/TileColorable.java +++ b/src/main/java/noppes/npcs/blocks/tiles/TileColorable.java @@ -1,11 +1,8 @@ package noppes.npcs.blocks.tiles; -import net.minecraft.block.BlockColored; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.NoppesUtilServer; import noppes.npcs.items.ItemNpcTool; import static noppes.npcs.items.ItemNpcTool.BRUSH_COLOR_TAG; diff --git a/src/main/java/noppes/npcs/client/ClientCacheHandler.java b/src/main/java/noppes/npcs/client/ClientCacheHandler.java index 0661b7505..abfc0993e 100644 --- a/src/main/java/noppes/npcs/client/ClientCacheHandler.java +++ b/src/main/java/noppes/npcs/client/ClientCacheHandler.java @@ -1,13 +1,15 @@ package noppes.npcs.client; import net.minecraft.util.ResourceLocation; -import noppes.npcs.client.gui.OverlayQuestTracking; import noppes.npcs.client.gui.customoverlay.OverlayCustom; import noppes.npcs.client.gui.select.GuiSoundSelection; import noppes.npcs.client.gui.select.GuiTextureSelection; import noppes.npcs.client.renderer.ImageData; import noppes.npcs.config.ConfigClient; -import noppes.npcs.controllers.data.*; +import noppes.npcs.controllers.data.AnimationData; +import noppes.npcs.controllers.data.Party; +import noppes.npcs.controllers.data.PlayerData; +import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.util.CacheHashMap; import java.util.HashMap; @@ -16,13 +18,16 @@ import java.util.UUID; public class ClientCacheHandler { private static final CacheHashMap> imageDataCache = new CacheHashMap<>((long) ConfigClient.CacheLife * 60 * 1000); public static PlayerData playerData = new PlayerData(); - public static OverlayQuestTracking questTrackingOverlay = null; public static HashMap customOverlays = new HashMap<>(); public static HashMap> skinOverlays = new HashMap<>(); public static HashMap playerAnimations = new HashMap<>(); public static Party party; + public static boolean allowProfiles = true; + public static boolean allowParties = true; + + public static ImageData getImageData(String directory) { synchronized (imageDataCache) { if (!imageDataCache.containsKey(directory)) { @@ -49,7 +54,6 @@ public class ClientCacheHandler { public static void clearCache() { ClientCacheHandler.imageDataCache.clear(); - ClientCacheHandler.questTrackingOverlay = null; ClientCacheHandler.customOverlays.clear(); ClientCacheHandler.skinOverlays.clear(); ClientCacheHandler.playerAnimations.clear(); diff --git a/src/main/java/noppes/npcs/client/ClientEventHandler.java b/src/main/java/noppes/npcs/client/ClientEventHandler.java index 359745ac6..b82e19e32 100644 --- a/src/main/java/noppes/npcs/client/ClientEventHandler.java +++ b/src/main/java/noppes/npcs/client/ClientEventHandler.java @@ -1,9 +1,7 @@ package noppes.npcs.client; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.relauncher.Side; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.EntityClientPlayerMP; @@ -17,13 +15,18 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.*; -import net.minecraftforge.event.entity.living.LivingEvent; import noppes.npcs.client.gui.customoverlay.OverlayCustom; +import noppes.npcs.client.gui.hud.ClientHudManager; +import noppes.npcs.client.gui.hud.CompassHudComponent; +import noppes.npcs.client.gui.hud.EnumHudComponent; +import noppes.npcs.client.gui.hud.QuestTrackingComponent; import noppes.npcs.client.renderer.MarkRenderer; import noppes.npcs.client.renderer.RenderCNPCPlayer; import noppes.npcs.constants.EnumAnimationPart; import noppes.npcs.constants.MarkType; -import noppes.npcs.controllers.data.*; +import noppes.npcs.controllers.data.FramePart; +import noppes.npcs.controllers.data.MarkData; +import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; import java.lang.reflect.Field; @@ -91,9 +94,16 @@ public class ClientEventHandler { overlayCustom.renderGameOverlay(event.partialTicks); } - if (ClientCacheHandler.questTrackingOverlay != null) { - ClientCacheHandler.questTrackingOverlay.renderGameOverlay(event.partialTicks); + if(ClientHudManager.getInstance().getHudComponents().isEmpty()){ + ClientHudManager.getInstance().registerHud(EnumHudComponent.QuestTracker, new QuestTrackingComponent(Minecraft.getMinecraft())); + ClientHudManager.getInstance().registerHud(EnumHudComponent.QuestCompass, new CompassHudComponent(Minecraft.getMinecraft())); } + + ClientHudManager.getInstance().renderAllHUDs(event.partialTicks); + +// if (ClientCacheHandler.questTrackingOverlay != null) { +// ClientCacheHandler.questTrackingOverlay.renderOverlay(event.partialTicks); +// } } } diff --git a/src/main/java/noppes/npcs/client/ClientProxy.java b/src/main/java/noppes/npcs/client/ClientProxy.java index 1e8b73d6b..c7dfa9a66 100644 --- a/src/main/java/noppes/npcs/client/ClientProxy.java +++ b/src/main/java/noppes/npcs/client/ClientProxy.java @@ -21,7 +21,6 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.item.Item; -import net.minecraft.item.ItemTool; import net.minecraft.stats.Achievement; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ReportedException; @@ -69,8 +68,8 @@ import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.*; import noppes.npcs.entity.data.ModelData; import noppes.npcs.entity.data.ModelPartData; -import noppes.npcs.items.ItemNpcTool; import noppes.npcs.items.ItemLinked; +import noppes.npcs.items.ItemNpcTool; import noppes.npcs.items.ItemScripted; import org.lwjgl.input.Keyboard; import tconstruct.client.tabs.InventoryTabCustomNpc; @@ -146,7 +145,7 @@ public class ClientProxy extends CommonProxy { } Minecraft mc = Minecraft.getMinecraft(); - NPCButton = new KeyBinding("NPC Inventory", Keyboard.KEY_L, "key.categories.customnpc"); + NPCButton = new KeyBinding("NPC Inventory", Keyboard.KEY_N, "key.categories.customnpc"); ClientRegistry.registerKeyBinding(NPCButton); mc.gameSettings.loadOptions(); @@ -534,9 +533,9 @@ public class ClientProxy extends CommonProxy { @Override public void registerItem(Item item) { if (item instanceof ItemScripted || item instanceof ItemLinked) { - MinecraftForgeClient.registerItemRenderer(item, new CustomItemRenderer()); + MinecraftForgeClient.registerItemRenderer(item, new ItemCustomRenderer()); } else if (item instanceof ItemNpcTool) { - MinecraftForgeClient.registerItemRenderer(item, new NpcItemToolRenderer()); + MinecraftForgeClient.registerItemRenderer(item, new ItemToolRenderer()); }else { MinecraftForgeClient.registerItemRenderer(item, new NpcItemRenderer()); } @@ -598,7 +597,7 @@ public class ClientProxy extends CommonProxy { } public static class FontContainer { - private StringCache textFont = null; + public StringCache textFont = null; public boolean useCustomFont = true; private FontContainer(){ diff --git a/src/main/java/noppes/npcs/client/ClientTickHandler.java b/src/main/java/noppes/npcs/client/ClientTickHandler.java index 038ea5177..65e06bf6b 100644 --- a/src/main/java/noppes/npcs/client/ClientTickHandler.java +++ b/src/main/java/noppes/npcs/client/ClientTickHandler.java @@ -5,24 +5,32 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.InputEvent; import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.gameevent.TickEvent.Phase; -import kamkeel.npcs.addon.client.DBCClient; import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.player.CheckPlayerValue; import kamkeel.npcs.network.packets.player.InputDevicePacket; import kamkeel.npcs.network.packets.player.ScreenSizePacket; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ContainerPlayer; import net.minecraft.world.World; import noppes.npcs.CustomNpcs; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.controllers.MusicController; import noppes.npcs.client.controllers.ScriptSoundController; -import noppes.npcs.client.gui.player.inventory.*; +import noppes.npcs.client.gui.hud.ClientHudManager; +import noppes.npcs.client.gui.hud.CompassHudComponent; +import noppes.npcs.client.gui.hud.EnumHudComponent; +import noppes.npcs.client.gui.hud.HudComponent; +import noppes.npcs.client.gui.player.inventory.GuiCNPCInventory; import noppes.npcs.client.renderer.RenderNPCInterface; -import noppes.npcs.constants.EnumPlayerPacket; +import noppes.npcs.constants.MarkType; +import noppes.npcs.controllers.data.MarkData; +import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; +import tconstruct.client.tabs.InventoryTabCustomNpc; + +import java.util.ArrayList; import static noppes.npcs.client.ClientEventHandler.renderCNPCPlayer; @@ -79,6 +87,13 @@ public class ClientTickHandler{ prevHeight = mc.displayHeight; PacketClient.sendClient(new ScreenSizePacket(mc.displayWidth,mc.displayHeight)); } + + if(mc.theWorld == null) + return; + + if(mc.theWorld.getTotalWorldTime() % 20 == 0) { // Update every second + updateCompassMarks(); + } } @SubscribeEvent @@ -94,23 +109,7 @@ public class ClientTickHandler{ if(ClientProxy.NPCButton.isPressed()){ Minecraft mc = Minecraft.getMinecraft(); if(mc.currentScreen == null){ - switch (GuiCNPCInventory.activeTab){ - case 0: - NoppesUtil.openGUI(mc.thePlayer, new GuiQuestLog()); - break; - case 1: - NoppesUtil.openGUI(mc.thePlayer, new GuiParty()); - break; - case 2: - NoppesUtil.openGUI(mc.thePlayer, new GuiFaction()); - break; - case 3: - NoppesUtil.openGUI(mc.thePlayer, new GuiSettings()); - break; - case 4: - NoppesUtil.openGUI(mc.thePlayer, DBCClient.Instance.inventoryGUI()); - break; - } + InventoryTabCustomNpc.tabHelper(); } else if(mc.currentScreen instanceof GuiCNPCInventory) mc.setIngameFocus(); @@ -137,4 +136,50 @@ public class ClientTickHandler{ return false; } + + private final int SCAN_RANGE = 128; + private void updateCompassMarks() { + Minecraft mc = Minecraft.getMinecraft(); + EntityPlayer player = mc.thePlayer; + + // Update compass + HudComponent compass = ClientHudManager.getInstance() + .getHudComponents().get(EnumHudComponent.QuestCompass); + + if(!compass.enabled || mc.thePlayer == null) + return; + + ArrayList marks = new ArrayList<>(); + + // Scan entities in loaded chunks + for(Object entity : mc.theWorld.loadedEntityList) { + if(entity instanceof EntityNPCInterface) { + EntityNPCInterface npc = (EntityNPCInterface) entity; + + if(npc.dimension != player.dimension) + continue; + + // Check distance + if(player.getDistanceToEntity(npc) > SCAN_RANGE) + continue; + + // Get marks + MarkData markData = MarkData.get(npc); + for(MarkData.Mark mark : markData.marks) { + if(mark.getType() != MarkType.NONE && + mark.availability.isAvailable(player)) { + marks.add(new CompassHudComponent.MarkTargetEntry( + (int)npc.posX, + (int)npc.posZ, + mark.getType(), + mark.color + )); + break; // Only show first valid mark per NPC + } + } + } + } + + ((CompassHudComponent) compass).updateMarkTargets(marks); + } } diff --git a/src/main/java/noppes/npcs/client/NoppesUtil.java b/src/main/java/noppes/npcs/client/NoppesUtil.java index 2de2178d7..4ac30d82c 100644 --- a/src/main/java/noppes/npcs/client/NoppesUtil.java +++ b/src/main/java/noppes/npcs/client/NoppesUtil.java @@ -17,10 +17,7 @@ import net.minecraft.util.Util; import noppes.npcs.CustomNpcs; import noppes.npcs.client.gui.player.GuiDialogInteract; import noppes.npcs.client.gui.player.GuiQuestCompletion; -import noppes.npcs.client.gui.util.GuiContainerNPCInterface; -import noppes.npcs.client.gui.util.GuiNPCInterface; -import noppes.npcs.client.gui.util.IScrollData; -import noppes.npcs.client.gui.util.IScrollGroup; +import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.Quest; @@ -32,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.net.URI; import java.util.HashMap; +import java.util.Map; import java.util.Vector; public class NoppesUtil { @@ -258,4 +256,60 @@ public class NoppesUtil { public static void isGUIOpen(boolean isGUIOpen) { PacketClient.sendClient(new IsGuiOpenInform(isGUIOpen)); } + + /** + * Handles the incoming large packet with full player data. + * The packet writes: + * - player name (String) + * - questCategories, questActive, questFinished (maps) + * - dialogCategories, dialogRead (maps) + * - transportCategories, transportLocations (maps) + * - bankData, factionData (maps) + * + * The existing PlayerDataController functions are used on the server side; + * here we simply update the active SubGuiPlayerDataNew if present. + */ + public static void handlePlayerData(ByteBuf data, EntityPlayer player) throws IOException { + String playerName = ByteBufUtils.readString(data); + Map questCategories = readMap(data); + Map questActive = readMap(data); + Map questFinished = readMap(data); + Map dialogCategories = readMap(data); + Map dialogRead = readMap(data); + Map transportCategories = readMap(data); + Map transportLocations = readMap(data); + Map bankData = readMap(data); + Map factionData = readMap(data); + + + GuiScreen gui = Minecraft.getMinecraft().currentScreen; + if(gui == null) + return; + if(gui instanceof GuiNPCInterface && ((GuiNPCInterface)gui).hasSubGui()){ + gui = (GuiScreen) ((GuiNPCInterface)gui).getSubGui(); + } + + if(gui instanceof GuiContainerNPCInterface && ((GuiContainerNPCInterface)gui).hasSubGui()){ + gui = (GuiScreen) ((GuiContainerNPCInterface)gui).getSubGui(); + } + if (gui instanceof IPlayerDataInfo) { + IPlayerDataInfo info = (IPlayerDataInfo) gui; + info.setQuestData(questCategories, questActive, questFinished); + info.setDialogData(dialogCategories, dialogRead); + info.setTransportData(transportCategories, transportLocations); + info.setBankData(bankData); + info.setFactionData(factionData); + } + } + + private static Map readMap(ByteBuf data) { + int size = data.readInt(); + Map map = new HashMap<>(); + for (int i = 0; i < size; i++) { + String key = ByteBufUtils.readString(data); + int value = data.readInt(); + map.put(key, value); + } + return map; + } } diff --git a/src/main/java/noppes/npcs/client/controllers/ClientCloneController.java b/src/main/java/noppes/npcs/client/controllers/ClientCloneController.java index 505c02173..bfce34457 100644 --- a/src/main/java/noppes/npcs/client/controllers/ClientCloneController.java +++ b/src/main/java/noppes/npcs/client/controllers/ClientCloneController.java @@ -4,7 +4,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import noppes.npcs.CustomNpcs; import noppes.npcs.controllers.ServerCloneController; -import noppes.npcs.controllers.ServerTagMapController; import noppes.npcs.controllers.data.TagMap; import java.io.File; diff --git a/src/main/java/noppes/npcs/client/fx/EntityBigSmokeFX.java b/src/main/java/noppes/npcs/client/fx/EntityBigSmokeFX.java index c645c637e..18942eee7 100644 --- a/src/main/java/noppes/npcs/client/fx/EntityBigSmokeFX.java +++ b/src/main/java/noppes/npcs/client/fx/EntityBigSmokeFX.java @@ -1,7 +1,5 @@ package noppes.npcs.client.fx; -import org.lwjgl.opengl.GL11; - import cpw.mods.fml.common.eventhandler.Cancelable; import cpw.mods.fml.relauncher.Side; import net.minecraft.client.Minecraft; @@ -10,12 +8,12 @@ import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.Blocks; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityEvent.EntityConstructing; +import org.lwjgl.opengl.GL11; public class EntityBigSmokeFX extends EntityFX { diff --git a/src/main/java/noppes/npcs/client/gui/GuiBorderBlock.java b/src/main/java/noppes/npcs/client/gui/GuiBorderBlock.java index 290385537..d9c4d1717 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiBorderBlock.java +++ b/src/main/java/noppes/npcs/client/gui/GuiBorderBlock.java @@ -6,7 +6,6 @@ import kamkeel.npcs.network.packets.request.TileEntitySavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.blocks.tiles.TileBorder; - import noppes.npcs.client.gui.util.*; public class GuiBorderBlock extends GuiNPCInterface implements IGuiData{ diff --git a/src/main/java/noppes/npcs/client/gui/GuiMagicMap.java b/src/main/java/noppes/npcs/client/gui/GuiMagicMap.java index d12695ada..34d5a3d21 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiMagicMap.java +++ b/src/main/java/noppes/npcs/client/gui/GuiMagicMap.java @@ -1,13 +1,5 @@ package noppes.npcs.client.gui; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import noppes.npcs.client.gui.util.GuiDiagram; -import noppes.npcs.client.gui.util.GuiNPCInterface; -import noppes.npcs.controllers.MagicController; -import noppes.npcs.controllers.data.Magic; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.RenderHelper; @@ -15,8 +7,16 @@ import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.gui.util.GuiDiagram; +import noppes.npcs.client.gui.util.GuiNPCInterface; +import noppes.npcs.controllers.MagicController; +import noppes.npcs.controllers.data.Magic; import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + public class GuiMagicMap extends GuiDiagram { private List magics; diff --git a/src/main/java/noppes/npcs/client/gui/GuiMerchantAdd.java b/src/main/java/noppes/npcs/client/gui/GuiMerchantAdd.java index 9979ecf1f..d39a6531a 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiMerchantAdd.java +++ b/src/main/java/noppes/npcs/client/gui/GuiMerchantAdd.java @@ -18,10 +18,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.village.MerchantRecipe; import net.minecraft.village.MerchantRecipeList; import noppes.npcs.ServerEventsHandler; - import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.GuiNpcButton; - import noppes.npcs.containers.ContainerMerchantAdd; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNPCFactionSelection.java b/src/main/java/noppes/npcs/client/gui/GuiNPCFactionSelection.java index b3ba50227..01eef3728 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNPCFactionSelection.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNPCFactionSelection.java @@ -4,11 +4,8 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.faction.FactionsGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; - -import noppes.npcs.controllers.data.Quest; import noppes.npcs.entity.EntityNPCInterface; import java.util.HashMap; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNPCLinesEdit.java b/src/main/java/noppes/npcs/client/gui/GuiNPCLinesEdit.java index ea0bffc3e..d97a33a13 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNPCLinesEdit.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNPCLinesEdit.java @@ -5,10 +5,8 @@ import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedGetPacket; import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiSoundSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Line; import noppes.npcs.controllers.data.Lines; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNPCTransportCategoryEdit.java b/src/main/java/noppes/npcs/client/gui/GuiNPCTransportCategoryEdit.java index c25e59dbf..129f4bd0b 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNPCTransportCategoryEdit.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNPCTransportCategoryEdit.java @@ -5,13 +5,11 @@ import kamkeel.npcs.network.packets.request.transport.TransportCategoriesGetPack import kamkeel.npcs.network.packets.request.transport.TransportCategorySavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.GuiNpcTextField; - import noppes.npcs.entity.EntityNPCInterface; public class GuiNPCTransportCategoryEdit extends GuiNPCInterface diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcDimension.java b/src/main/java/noppes/npcs/client/gui/GuiNpcDimension.java index 2aa64b412..ce7b8d3e1 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcDimension.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcDimension.java @@ -6,11 +6,9 @@ import kamkeel.npcs.network.packets.request.feather.DimensionTeleportPacket; import kamkeel.npcs.network.packets.request.npc.RemoteDeletePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.util.StatCollector; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; - import java.util.HashMap; import java.util.Vector; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java index b467640dc..8393eefa6 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawner.java @@ -11,11 +11,9 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.StatCollector; import net.minecraft.world.World; - import noppes.npcs.client.controllers.ClientCloneController; import noppes.npcs.client.controllers.ClientTagMapController; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Tag; import noppes.npcs.controllers.data.TagMap; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java index 4215e59d3..66ae14499 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerAdd.java @@ -1,7 +1,6 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.packets.request.clone.CloneAllTagsShortPacket; import kamkeel.npcs.network.packets.request.clone.ClonePreSavePacket; import kamkeel.npcs.network.packets.request.clone.CloneSavePacket; @@ -14,11 +13,8 @@ import net.minecraft.entity.EntityList; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; - import noppes.npcs.client.controllers.ClientCloneController; import noppes.npcs.client.gui.util.*; - -import noppes.npcs.controllers.TagController; import noppes.npcs.controllers.data.Tag; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerMounter.java b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerMounter.java index fff76deda..d1157b1cc 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerMounter.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerMounter.java @@ -12,11 +12,9 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagDouble; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; - import noppes.npcs.client.controllers.ClientCloneController; import noppes.npcs.client.gui.util.*; - import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerSelector.java b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerSelector.java index 16d58c93d..cc9cff0c2 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerSelector.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcMobSpawnerSelector.java @@ -6,11 +6,9 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagDouble; import net.minecraft.nbt.NBTTagList; - import noppes.npcs.client.controllers.ClientCloneController; import noppes.npcs.client.gui.util.*; - import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcPather.java b/src/main/java/noppes/npcs/client/gui/GuiNpcPather.java index 916748f08..7bb61e1c3 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcPather.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcPather.java @@ -7,12 +7,10 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.DataAI; import noppes.npcs.NBTTags; - import noppes.npcs.client.gui.util.GuiCustomScroll; import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.IGuiData; - import noppes.npcs.entity.EntityNPCInterface; import java.util.ArrayList; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcRedstoneBlock.java b/src/main/java/noppes/npcs/client/gui/GuiNpcRedstoneBlock.java index 114af0fb6..9c81a1286 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcRedstoneBlock.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcRedstoneBlock.java @@ -6,7 +6,6 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; import noppes.npcs.blocks.tiles.TileRedstoneBlock; - import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcRemoteEditor.java b/src/main/java/noppes/npcs/client/gui/GuiNpcRemoteEditor.java index a35484e1b..ecf243d6d 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcRemoteEditor.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcRemoteEditor.java @@ -7,10 +7,8 @@ import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.entity.Entity; import net.minecraft.util.StatCollector; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import java.util.ArrayList; diff --git a/src/main/java/noppes/npcs/client/gui/GuiNpcWaypoint.java b/src/main/java/noppes/npcs/client/gui/GuiNpcWaypoint.java index c8fdc959d..c0afa6aaf 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiNpcWaypoint.java +++ b/src/main/java/noppes/npcs/client/gui/GuiNpcWaypoint.java @@ -5,7 +5,6 @@ import kamkeel.npcs.network.packets.request.TileEntitySavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.blocks.tiles.TileWaypoint; - import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; diff --git a/src/main/java/noppes/npcs/client/gui/GuiScript.java b/src/main/java/noppes/npcs/client/gui/GuiScript.java index cd444d038..d5025d87b 100644 --- a/src/main/java/noppes/npcs/client/gui/GuiScript.java +++ b/src/main/java/noppes/npcs/client/gui/GuiScript.java @@ -10,15 +10,12 @@ import net.minecraft.nbt.NBTTagList; import net.minecraft.server.MinecraftServer; import net.minecraft.util.StatCollector; import noppes.npcs.NoppesStringUtils; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.script.GuiNPCEventScripts; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.data.DataScript; -import noppes.npcs.controllers.data.Quest; import noppes.npcs.entity.EntityNPCInterface; import java.util.*; diff --git a/src/main/java/noppes/npcs/client/gui/OverlayQuestTracking.java b/src/main/java/noppes/npcs/client/gui/OverlayQuestTracking.java deleted file mode 100644 index 33818aeff..000000000 --- a/src/main/java/noppes/npcs/client/gui/OverlayQuestTracking.java +++ /dev/null @@ -1,703 +0,0 @@ -package noppes.npcs.client.gui; - -import com.ibm.icu.text.ArabicShaping; -import com.ibm.icu.text.ArabicShapingException; -import com.ibm.icu.text.Bidi; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.ResourceLocation; -import noppes.npcs.config.ConfigClient; -import noppes.npcs.controllers.data.Quest; -import org.lwjgl.opengl.GL11; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -public class OverlayQuestTracking extends Gui { - public Minecraft mc; - - private ScaledResolution res = null; - public static int scaledWidth = 0; - public static int scaledHeight = 0; - - int color = 0xFFFFFF; - float alpha = 1.0F; - - private boolean randomStyle = false; - private boolean boldStyle = false; - private boolean italicStyle = false; - private boolean underlineStyle = false; - private boolean strikethroughStyle = false; - private boolean bidiFlag = false; - private boolean unicodeFlag = false; - - private static final ResourceLocation[] unicodePageLocations = new ResourceLocation[256]; - private final FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; - protected final ResourceLocation locationFontTexture = new ResourceLocation("textures/font/ascii.png");; - protected int[] charWidth = new int[256]; - protected byte[] glyphWidth = new byte[65536]; - private final int[] colorCode = new int[32]; - - private float red; - private float green; - private float blue; - - private float posX; - private float posY; - - private float renderOffsetY; - private final int overlayWidth = 120; - - public ArrayList trackedQuestLines = new ArrayList<>(); - public ArrayList categoryNameLines = new ArrayList<>(); - public ArrayList objectiveLines = new ArrayList<>(); - public ArrayList turnInText = new ArrayList<>(); - - public OverlayQuestTracking(Minecraft mc) { - this.mc = mc; - readFontTexture(); - readGlyphSizes(); - for (int i = 0; i < 32; ++i) - { - int j = (i >> 3 & 1) * 85; - int k = (i >> 2 & 1) * 170 + j; - int l = (i >> 1 & 1) * 170 + j; - int i1 = (i >> 0 & 1) * 170 + j; - - if (i == 6) - { - k += 85; - } - - if (Minecraft.getMinecraft().gameSettings.anaglyph) - { - int j1 = (k * 30 + l * 59 + i1 * 11) / 100; - int k1 = (k * 30 + l * 70) / 100; - int l1 = (k * 30 + i1 * 70) / 100; - k = j1; - l = k1; - i1 = l1; - } - - if (i >= 16) - { - k /= 4; - l /= 4; - i1 /= 4; - } - - this.colorCode[i] = (k & 255) << 16 | (l & 255) << 8 | i1 & 255; - } - } - - public void initOverlay() { - res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - scaledWidth = res.getScaledWidth(); - scaledHeight = res.getScaledHeight(); - } - - public void setOverlayData(NBTTagCompound compound) { - Quest trackedQuest = new Quest(); - trackedQuest.readNBT(compound.getCompoundTag("Quest")); - - trackedQuestLines = getLineList(trackedQuest.getName()); - categoryNameLines = getLineList(compound.getString("CategoryName")); - - NBTTagList nbtTagList = compound.getTagList("ObjectiveList",8); - for (int i = 0; i < nbtTagList.tagCount(); i++) { - String objective = nbtTagList.getStringTagAt(i); - - String[] split = objective.split(":"); - split = split[split.length-1].split("/"); - - boolean completed = false; - - try { - if(split.length < 2) - throw new NumberFormatException("catch"); - - int killed = Integer.parseInt(split[0].trim()); - int total = Integer.parseInt(split[1].trim()); - - if (killed/total == 1) { - completed = true; - } - } catch (NumberFormatException e) { - if (objective.endsWith("(Done)") || objective.endsWith("(read)") || (objective.endsWith("Found") && !objective.endsWith("Not Found"))) { - completed = true; - } - } - - if (completed) { - objective = "&a&o&m" + objective; - } else { - objective = "&o" + objective; - } - - objectiveLines.add(objective); - } - - boolean instantComplete = compound.getBoolean("Instant"); - if(instantComplete){ - turnInText.add("Completed automatically"); - } - else { - String npcName = compound.getString("TurnInNPC"); - if (!npcName.isEmpty()) { - turnInText.add("Complete with " + npcName); - } - } - - this.initOverlay(); - } - - public ArrayList getLineList(String string) { - String[] split = string.split(" "); - - ArrayList lines = new ArrayList<>(); - lines.add(split[0]); - - for (int i = 1; i < split.length; i++) { - String s = split[i]; - if (this.fontRenderer.getStringWidth(lines.get(lines.size() - 1) + " " + s) > 100) { - lines.add(s); - } else { - lines.set(lines.size() - 1, lines.get(lines.size() - 1) + " " + s); - } - } - - return lines; - } - - public void renderGameOverlay(float partialTicks){ - res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - - float overallScale = (float) ConfigClient.TrackingScale / 100; - - scaledWidth = (int) (res.getScaledWidth()); - scaledHeight = (int) (res.getScaledHeight()); - - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); - GL11.glDisable(GL11.GL_ALPHA_TEST); - - GL11.glPushMatrix(); - GL11.glTranslatef(ConfigClient.TrackingInfoAlignment%3*((float)(scaledWidth)/2), (float) (Math.floor((float)(ConfigClient.TrackingInfoAlignment/3))*((float)(scaledHeight)/2)),0.0F); - - float offsetX = ConfigClient.TrackingInfoAlignment%3 == 0 ? 5 : -5; - - float offsetY = ConfigClient.TrackingInfoAlignment < 3 ? 5 : 0; - offsetY = ConfigClient.TrackingInfoAlignment > 5 ? -5 : offsetY; - - GL11.glTranslatef(ConfigClient.TrackingInfoX + offsetX, ConfigClient.TrackingInfoY + offsetY, 0.0F); - - red = (color >> 16 & 255) / 255f; - green = (color >> 8 & 255) / 255f; - blue = (color & 255) / 255f; - - float centerX = (float) -overlayWidth /2 * overallScale; - if (ConfigClient.TrackingInfoAlignment % 3 == 1) { // For Center alignment - centerX = 0; - } else { - centerX *= ConfigClient.TrackingInfoAlignment % 3 == 0 ? -1 : 1; - } - - float questTitleTop; - this.renderOffsetY = -40 * overallScale; - GL11.glPushMatrix(); - GL11.glTranslatef(centerX, 0.0F, 0.0F); - this.renderStringLines(trackedQuestLines,1.2F * overallScale, false, true, 0); - GL11.glPopMatrix(); - questTitleTop = this.renderOffsetY; - this.renderOffsetY -= 10 * overallScale; - GL11.glPushMatrix(); - GL11.glTranslatef(centerX, 0.0F, 0.0F); - this.renderStringLines(categoryNameLines,0.85F * overallScale, false, false, 0); - GL11.glPopMatrix(); - - this.renderOffsetY = -10 * overallScale; - GL11.glPushMatrix(); - this.renderStringLines(objectiveLines, 1F * overallScale, true, false, ConfigClient.TrackingInfoAlignment % 3 == 0 ? 1 : (ConfigClient.TrackingInfoAlignment % 3 == 2 ? 2 : 0)); - GL11.glPopMatrix(); - - this.renderOffsetY += 10 * overallScale; - GL11.glPushMatrix(); - this.renderStringLines(turnInText, 1F * overallScale, true, false, ConfigClient.TrackingInfoAlignment % 3 == 0 ? 1 : (ConfigClient.TrackingInfoAlignment % 3 == 2 ? 2 : 0)); - GL11.glPopMatrix(); - - this.renderOffsetY = -20 * overallScale; - GL11.glPushMatrix(); - if(overallScale < 0.6){ - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY)), 0xFFFFFFFF); - } else if (overallScale < 0.8){ - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY)), 0xFFA8A8A8); - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY + 1)), 0xFFFFFFFF); - } else { - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) (this.renderOffsetY), 0xFF777777); - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY + 1)), 0xFFA8A8A8); - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY + 2)), 0xFFFFFFFF); - } - GL11.glPopMatrix(); - this.renderOffsetY = questTitleTop + 2; - GL11.glPushMatrix(); - - if(overallScale < 0.6){ - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) (this.renderOffsetY - 2), 0xFFFFFFFF); - } else if (overallScale < 0.8){ - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY)), 0xFFA8A8A8); - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) (this.renderOffsetY - 1), 0xFFFFFFFF); - } else { - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY)), 0xFF777777); - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) ((this.renderOffsetY -1)), 0xFFA8A8A8); - this.drawHorizontalLine((int) (centerX - (overlayWidth / 2 * overallScale)), (int) (centerX + (overlayWidth / 2 * overallScale)), (int) (this.renderOffsetY - 2), 0xFFFFFFFF); - } - GL11.glPopMatrix(); - GL11.glPopMatrix(); - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_ALPHA_TEST); - } - - public void renderStringLines(ArrayList lines, float scale, boolean downwards, boolean bold, int facing) { - for (int i = 0; i < lines.size(); i++) { - String s = lines.get(i); - if (!downwards) { - s = lines.get(lines.size()-1 - i); - } - - int stringWidth = this.fontRenderer.getStringWidth(s.replace("&o","")); - if (s.startsWith("&a&o&m")) { - stringWidth = this.fontRenderer.getStringWidth(s.replace("&a&o&m","")); - } - - float overallScale = (float) ConfigClient.TrackingScale / 100; - - GL11.glPushMatrix(); - switch (facing) { - case 0://center - GL11.glTranslatef(scale * (-stringWidth / 2.0F), this.renderOffsetY, 0.0F); - break; - case 1://left - GL11.glTranslatef(0, this.renderOffsetY, 0.0F); - break; - case 2://right - GL11.glTranslatef(scale * (-stringWidth), this.renderOffsetY, 0.0F); - break; - } - - GL11.glScalef(scale, scale, scale); - this.drawString(s, 0, 0, this.color, true); - if (bold) { - GL11.glTranslatef(0.2F, 0.2F, 0.0F); - this.drawString(s, 0, 0, this.color, false); - } - this.renderOffsetY += (downwards ? 10 : -10) * overallScale; - GL11.glPopMatrix(); - } - } - - public int drawString(String p_85187_1_, int p_85187_2_, int p_85187_3_, int p_85187_4_, boolean p_85187_5_) - { - this.resetStyles(); - int l; - - if (p_85187_5_) - { - l = this.renderString(p_85187_1_, p_85187_2_ + 1, p_85187_3_ + 1, p_85187_4_, true); - l = Math.max(l, this.renderString(p_85187_1_, p_85187_2_, p_85187_3_, p_85187_4_, false)); - } - else - { - l = this.renderString(p_85187_1_, p_85187_2_, p_85187_3_, p_85187_4_, false); - } - - return l; - } - - private void resetStyles() - { - this.randomStyle = false; - this.boldStyle = false; - this.italicStyle = false; - this.underlineStyle = false; - this.strikethroughStyle = false; - } - - private int renderString(String p_78258_1_, int p_78258_2_, int p_78258_3_, int p_78258_4_, boolean p_78258_5_) - { - if (p_78258_1_ == null) - { - return 0; - } - else - { - if (this.bidiFlag) - { - p_78258_1_ = this.bidiReorder(p_78258_1_); - } - - setColor(this.red, this.green, this.blue, this.alpha); - if (p_78258_5_) { - setColor(0,0,0,1.0F); - } - this.posX = (float)p_78258_2_; - this.posY = (float)p_78258_3_; - this.renderStringAtPos(p_78258_1_, p_78258_5_); - return (int)this.posX; - } - } - - private void renderStringAtPos(String p_78255_1_, boolean p_78255_2_) - { - for (int i = 0; i < p_78255_1_.length(); ++i) - { - char c0 = p_78255_1_.charAt(i); - int j; - int k; - - if (c0 == 38 && i + 1 < p_78255_1_.length()) - { - j = "0123456789abcdefklmnor".indexOf(p_78255_1_.toLowerCase().charAt(i + 1)); - - if(j < 16){ - this.randomStyle = false; - this.boldStyle = false; - this.strikethroughStyle = false; - this.underlineStyle = false; - this.italicStyle = false; - - if (j < 0 || j > 15) - { - j = 15; - } - - if (p_78255_2_) - { - j += 16; - } - - k = this.colorCode[j]; - setColor((float)(k >> 16) / 255.0F, (float)(k >> 8 & 255) / 255.0F, (float)(k & 255) / 255.0F, this.alpha); - } - else if (j == 16) - { - this.randomStyle = true; - } - else if (j == 17) - { - this.boldStyle = true; - } - else if (j == 18) - { - this.strikethroughStyle = true; - } - else if (j == 19) - { - this.underlineStyle = true; - } - else if (j == 20) - { - this.italicStyle = true; - } - else if (j == 21) - { - this.randomStyle = false; - this.boldStyle = false; - this.strikethroughStyle = false; - this.underlineStyle = false; - this.italicStyle = false; - } - - ++i; - } - else - { - j = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000".indexOf(c0); - - if (this.randomStyle && j != -1) - { - do - { - k = Minecraft.getMinecraft().fontRenderer.fontRandom.nextInt(this.charWidth.length); - } - while (this.charWidth[j] != this.charWidth[k]); - - j = k; - } - - float f1 = this.unicodeFlag ? 0.5F : 1.0F; - boolean flag1 = (c0 == 0 || j == -1 || this.unicodeFlag) && p_78255_2_; - - if (flag1) - { - this.posX -= f1; - this.posY -= f1; - } - - float f = this.renderCharAtPos(j, c0, this.italicStyle); - - if (flag1) - { - this.posX += f1; - this.posY += f1; - } - - if (this.boldStyle) - { - this.posX += f1; - - if (flag1) - { - this.posX -= f1; - this.posY -= f1; - } - - this.renderCharAtPos(j, c0, this.italicStyle); - this.posX -= f1; - - if (flag1) - { - this.posX += f1; - this.posY += f1; - } - - ++f; - } - - doDraw(f); - } - } - } - - protected void doDraw(float f) - { - { - { - Tessellator tessellator; - - if (this.strikethroughStyle) - { - tessellator = Tessellator.instance; - GL11.glDisable(GL11.GL_TEXTURE_2D); - tessellator.startDrawingQuads(); - tessellator.addVertex((double)this.posX, (double)(this.posY + (float)(Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT / 2)), 0.0D); - tessellator.addVertex((double)(this.posX + f), (double)(this.posY + (float)(Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT / 2)), 0.0D); - tessellator.addVertex((double)(this.posX + f), (double)(this.posY + (float)(Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT / 2) - 1.0F), 0.0D); - tessellator.addVertex((double)this.posX, (double)(this.posY + (float)(Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT / 2) - 1.0F), 0.0D); - tessellator.draw(); - GL11.glEnable(GL11.GL_TEXTURE_2D); - } - - if (this.underlineStyle) - { - tessellator = Tessellator.instance; - GL11.glDisable(GL11.GL_TEXTURE_2D); - tessellator.startDrawingQuads(); - int l = this.underlineStyle ? -1 : 0; - tessellator.addVertex((double)(this.posX + (float)l), (double)(this.posY + (float)Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT), 0.0D); - tessellator.addVertex((double)(this.posX + f), (double)(this.posY + (float)Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT), 0.0D); - tessellator.addVertex((double)(this.posX + f), (double)(this.posY + (float)Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT - 1.0F), 0.0D); - tessellator.addVertex((double)(this.posX + (float)l), (double)(this.posY + (float)Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT - 1.0F), 0.0D); - tessellator.draw(); - GL11.glEnable(GL11.GL_TEXTURE_2D); - } - - this.posX += (float)((int)f); - } - } - } - - private float renderCharAtPos(int p_78278_1_, char p_78278_2_, boolean p_78278_3_) - { - return p_78278_2_ == 32 ? 4.0F : ("\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000".indexOf(p_78278_2_) != -1 && !this.unicodeFlag ? this.renderDefaultChar(p_78278_1_, p_78278_3_) : this.renderUnicodeChar(p_78278_2_, p_78278_3_)); - } - - protected float renderDefaultChar(int p_78266_1_, boolean p_78266_2_) - { - float f = (float)(p_78266_1_ % 16 * 8); - float f1 = (float)(p_78266_1_ / 16 * 8); - float f2 = p_78266_2_ ? 1.0F : 0.0F; - bindTexture(this.locationFontTexture); - float f3 = (float)this.charWidth[p_78266_1_] - 0.01F; - GL11.glBegin(GL11.GL_TRIANGLE_STRIP); - GL11.glTexCoord2f(f / 128.0F, f1 / 128.0F); - GL11.glVertex3f(this.posX + f2, this.posY, 0.0F); - GL11.glTexCoord2f(f / 128.0F, (f1 + 7.99F) / 128.0F); - GL11.glVertex3f(this.posX - f2, this.posY + 7.99F, 0.0F); - GL11.glTexCoord2f((f + f3 - 1.0F) / 128.0F, f1 / 128.0F); - GL11.glVertex3f(this.posX + f3 - 1.0F + f2, this.posY, 0.0F); - GL11.glTexCoord2f((f + f3 - 1.0F) / 128.0F, (f1 + 7.99F) / 128.0F); - GL11.glVertex3f(this.posX + f3 - 1.0F - f2, this.posY + 7.99F, 0.0F); - GL11.glEnd(); - return (float)this.charWidth[p_78266_1_]; - } - - private ResourceLocation getUnicodePageLocation(int p_111271_1_) - { - if (unicodePageLocations[p_111271_1_] == null) - { - unicodePageLocations[p_111271_1_] = new ResourceLocation(String.format("textures/font/unicode_page_%02x.png", new Object[] {Integer.valueOf(p_111271_1_)})); - } - - return unicodePageLocations[p_111271_1_]; - } - - private void loadGlyphTexture(int p_78257_1_) - { - bindTexture(this.getUnicodePageLocation(p_78257_1_)); - } - - /** - * Render a single Unicode character at current (posX,posY) location using one of the /font/glyph_XX.png files... - */ - protected float renderUnicodeChar(char p_78277_1_, boolean p_78277_2_) - { - if (this.glyphWidth[p_78277_1_] == 0) - { - return 0.0F; - } - else - { - int i = p_78277_1_ / 256; - this.loadGlyphTexture(i); - int j = this.glyphWidth[p_78277_1_] >>> 4; - int k = this.glyphWidth[p_78277_1_] & 15; - float f = (float)j; - float f1 = (float)(k + 1); - float f2 = (float)(p_78277_1_ % 16 * 16) + f; - float f3 = (float)((p_78277_1_ & 255) / 16 * 16); - float f4 = f1 - f - 0.02F; - float f5 = p_78277_2_ ? 1.0F : 0.0F; - GL11.glBegin(GL11.GL_TRIANGLE_STRIP); - GL11.glTexCoord2f(f2 / 256.0F, f3 / 256.0F); - GL11.glVertex3f(this.posX + f5, this.posY, 0.0F); - GL11.glTexCoord2f(f2 / 256.0F, (f3 + 15.98F) / 256.0F); - GL11.glVertex3f(this.posX - f5, this.posY + 7.99F, 0.0F); - GL11.glTexCoord2f((f2 + f4) / 256.0F, f3 / 256.0F); - GL11.glVertex3f(this.posX + f4 / 2.0F + f5, this.posY, 0.0F); - GL11.glTexCoord2f((f2 + f4) / 256.0F, (f3 + 15.98F) / 256.0F); - GL11.glVertex3f(this.posX + f4 / 2.0F - f5, this.posY + 7.99F, 0.0F); - GL11.glEnd(); - return (f1 - f) / 2.0F + 1.0F; - } - } - - protected void setColor(float r, float g, float b, float a) - { - GL11.glColor4f(r, g, b, a); - } - - protected void bindTexture(ResourceLocation location) - { - Minecraft.getMinecraft().renderEngine.bindTexture(location); - } - - private void readFontTexture() - { - BufferedImage bufferedimage; - - try - { - bufferedimage = ImageIO.read(getResourceInputStream(this.locationFontTexture)); - } - catch (IOException ioexception) - { - throw new RuntimeException(ioexception); - } - - int i = bufferedimage.getWidth(); - int j = bufferedimage.getHeight(); - int[] aint = new int[i * j]; - bufferedimage.getRGB(0, 0, i, j, aint, 0, i); - int k = j / 16; - int l = i / 16; - byte b0 = 1; - float f = 8.0F / (float)l; - int i1 = 0; - - while (i1 < 256) - { - int j1 = i1 % 16; - int k1 = i1 / 16; - - if (i1 == 32) - { - this.charWidth[i1] = 3 + b0; - } - - int l1 = l - 1; - - while (true) - { - if (l1 >= 0) - { - int i2 = j1 * l + l1; - boolean flag = true; - - for (int j2 = 0; j2 < k && flag; ++j2) - { - int k2 = (k1 * l + j2) * i; - - if ((aint[i2 + k2] >> 24 & 255) != 0) - { - flag = false; - } - } - - if (flag) - { - --l1; - continue; - } - } - - ++l1; - this.charWidth[i1] = (int)(0.5D + (double)((float)l1 * f)) + b0; - ++i1; - break; - } - } - } - - private void readGlyphSizes() - { - try - { - InputStream inputstream = getResourceInputStream(new ResourceLocation("font/glyph_sizes.bin")); - inputstream.read(this.glyphWidth); - } - catch (IOException ioexception) - { - throw new RuntimeException(ioexception); - } - } - - protected InputStream getResourceInputStream(ResourceLocation location) throws IOException - { - return Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream(); - } - - private String bidiReorder(String p_147647_1_) - { - try - { - Bidi bidi = new Bidi((new ArabicShaping(8)).shape(p_147647_1_), 127); - bidi.setReorderingMode(0); - return bidi.writeReordered(2); - } - catch (ArabicShapingException arabicshapingexception) - { - return p_147647_1_; - } - } -} diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java b/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java index d8512eba9..22b0dfff1 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiClonerNPCTags.java @@ -1,9 +1,9 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.PacketClient; +import kamkeel.npcs.network.packets.request.tags.TagSetPacket; import kamkeel.npcs.network.packets.request.tags.TagsGetPacket; import kamkeel.npcs.network.packets.request.tags.TagsNpcGetPacket; -import kamkeel.npcs.network.packets.request.tags.TagSetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiEffectGeneral.java b/src/main/java/noppes/npcs/client/gui/SubGuiEffectGeneral.java index a5f8f0418..ea9152189 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiEffectGeneral.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiEffectGeneral.java @@ -16,6 +16,8 @@ import org.lwjgl.opengl.GL11; import java.util.ArrayList; import java.util.List; +import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons; + public class SubGuiEffectGeneral extends SubGuiInterface implements ITextfieldListener { private final GuiNPCManageEffects parent; public CustomEffect effect; @@ -128,10 +130,8 @@ public class SubGuiEffectGeneral extends SubGuiInterface implements ITextfieldLi func_152125_a(x, y, 0, 0, 1, 1, iconRenderSize, iconRenderSize, 1, 1); } GL11.glDisable(GL11.GL_DEPTH_TEST); - - // TODO: FIX TEXTURE - // textureManager.bindTexture(new ResourceLocation(CustomNpcPlusDBC.ID + ":textures/gui/icons.png")); - // func_152125_a(x, y, 0, 240, 16, 16, iconRenderSize, iconRenderSize, 256, 256); + textureManager.bindTexture(specialIcons); + func_152125_a(x, y, 0, 224, 16, 16, iconRenderSize, iconRenderSize, 256, 256); GL11.glEnable(GL11.GL_DEPTH_TEST); } }; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiMailmanSendSetup.java b/src/main/java/noppes/npcs/client/gui/SubGuiMailmanSendSetup.java index 0dadea474..2f0f5dfeb 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiMailmanSendSetup.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiMailmanSendSetup.java @@ -5,11 +5,9 @@ import kamkeel.npcs.network.packets.request.MailOpenSetupPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.player.GuiMailmanWrite; import noppes.npcs.client.gui.select.GuiQuestSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.containers.ContainerMail; import noppes.npcs.controllers.data.PlayerMail; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailability.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailability.java index 6d4b5bc4a..2d59d80a8 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailability.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailability.java @@ -3,12 +3,10 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.packets.request.faction.FactionGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumAvailabilityFactionType; import noppes.npcs.constants.EnumDayTime; - import noppes.npcs.controllers.data.Availability; import noppes.npcs.controllers.data.Faction; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityDialog.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityDialog.java index 35ee2158f..c55f040c5 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityDialog.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityDialog.java @@ -3,11 +3,9 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.packets.request.dialog.DialogGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiDialogSelection; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumAvailabilityDialog; - import noppes.npcs.controllers.data.Availability; import noppes.npcs.controllers.data.Dialog; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityQuest.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityQuest.java index c993936db..5d333ba3a 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityQuest.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcAvailabilityQuest.java @@ -3,11 +3,9 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.packets.request.quest.QuestGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiQuestSelection; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumAvailabilityQuest; - import noppes.npcs.controllers.data.Availability; import noppes.npcs.controllers.data.Quest; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialog.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialog.java index 0e09356c3..f1efa4716 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialog.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialog.java @@ -4,7 +4,6 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.dialog.DialogSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.EntityUtil; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.global.GuiNPCManageDialogs; @@ -12,7 +11,6 @@ import noppes.npcs.client.gui.player.GuiDialogInteract; import noppes.npcs.client.gui.select.GuiQuestSelection; import noppes.npcs.client.gui.select.GuiSoundSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.PlayerMail; import noppes.npcs.entity.EntityDialogNpc; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogOption.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogOption.java index f5565e43f..b47e71794 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogOption.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogOption.java @@ -3,11 +3,9 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.packets.request.dialog.DialogGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiDialogSelection; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumOptionType; - import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.DialogOption; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogVisual.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogVisual.java index bd7092d50..81da655e8 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogVisual.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDialogVisual.java @@ -4,11 +4,9 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.dialog.DialogSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; import noppes.npcs.config.ConfigMain; - import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.DialogImage; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDimensions.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDimensions.java index f90cc61b1..066a797f6 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcDimensions.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcDimensions.java @@ -3,9 +3,7 @@ package noppes.npcs.client.gui; import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.DimensionsGetPacket; import net.minecraft.client.gui.GuiButton; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.SpawnData; import java.util.*; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcFactionOptions.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcFactionOptions.java index d3cce58c2..7d1d2fdd9 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcFactionOptions.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcFactionOptions.java @@ -4,9 +4,7 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.faction.FactionsGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.util.StatCollector; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.FactionOptions; import java.util.HashMap; diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcProfileOptions.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcProfileOptions.java new file mode 100644 index 000000000..bc6376bd5 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcProfileOptions.java @@ -0,0 +1,65 @@ +package noppes.npcs.client.gui; + +import net.minecraft.client.gui.GuiButton; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.constants.EnumProfileSync; +import noppes.npcs.controllers.data.ProfileOptions; + +public class SubGuiNpcProfileOptions extends SubGuiInterface +{ + private final ProfileOptions options; + + public SubGuiNpcProfileOptions(ProfileOptions options) + { + this.options = options; + setBackground("menubg.png"); + xSize = 256; + ySize = 216; + closeOnEsc = true; + } + + public void initGui() + { + super.initGui(); + + int y = 0; + //Allow party - T/F button + addButton(new GuiNpcButton(0, guiLeft + 130, guiTop + 10 + y, 60, 20, + new String[]{"gui.no", "gui.yes"}, options.enableOptions ? 1 : 0)); + addLabel(new GuiNpcLabel(1, "profile.enableOptions", guiLeft + 10, guiTop + 17 + y)); + + if (options.enableOptions) { + y += 23; + addButton(new GuiNpcButton(5, guiLeft + 130, guiTop + 10 + y, 60, 20, + EnumProfileSync.values(), options.completeControl.ordinal())); + addLabel(new GuiNpcLabel(5, "profile.completion", guiLeft + 10, guiTop + 17 + y)); + + y += 23; + addButton(new GuiNpcButton(18, guiLeft + 130, guiTop + 10 + y, 60, 20, + EnumProfileSync.values(), options.cooldownControl.ordinal())); + addLabel(new GuiNpcLabel(18, "profile.cooldown", guiLeft + 10, guiTop + 17 + y)); + } + + addButton(new GuiNpcButton(66, guiLeft + 200, guiTop + 192, 50, 20, "gui.done")); + } + + protected void actionPerformed(GuiButton guibutton) + { + int id = guibutton.id; + switch (id) { + case 0: + options.enableOptions = !options.enableOptions; + break; + case 5: + options.completeControl = EnumProfileSync.valueOf(guibutton.displayString); + break; + case 18: + options.cooldownControl = EnumProfileSync.valueOf(guibutton.displayString); + break; + case 66: + close(); + break; + } + initGui(); + } +} diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java b/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java index 8b1b70319..bd8e559c8 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiNpcQuest.java @@ -5,7 +5,6 @@ import kamkeel.npcs.network.packets.request.quest.QuestOpenGuiPacket; import kamkeel.npcs.network.packets.request.quest.QuestSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.global.GuiNPCManageQuest; import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeDialog; import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeKill; @@ -13,7 +12,10 @@ import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeLocation; import noppes.npcs.client.gui.questtypes.GuiNpcQuestTypeManual; import noppes.npcs.client.gui.select.GuiQuestSelection; import noppes.npcs.client.gui.util.*; -import noppes.npcs.constants.*; +import noppes.npcs.constants.EnumGuiType; +import noppes.npcs.constants.EnumQuestCompletion; +import noppes.npcs.constants.EnumQuestRepeat; +import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.data.PlayerMail; import noppes.npcs.controllers.data.Quest; @@ -67,7 +69,10 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, addLabel(new GuiNpcLabel(17, "party.options", guiLeft + 180, guiTop + 135)); addButton(new GuiNpcButton(18, guiLeft + 303, guiTop + 130, 50, 20, "selectServer.edit")); - this.addButton(new GuiNpcButton(9, guiLeft + 7, guiTop + 102,90, 20, new String[]{"quest.npc","quest.instant"},quest.completion.ordinal())); + addLabel(new GuiNpcLabel(33, "quest.profile", guiLeft + 180, guiTop + 159)); + addButton(new GuiNpcButton(33, guiLeft + 303, guiTop + 154, 50, 20, "selectServer.edit")); + + this.addButton(new GuiNpcButton(9, guiLeft + 7, guiTop + 102,90, 20, new String[]{"quest.npc","quest.instant"},quest.completion.ordinal())); if(quest.completerNpc.isEmpty() && npc != null) quest.completerNpc = npc.display.name; this.addTextField(new GuiNpcTextField(2,this, this.fontRendererObj, guiLeft + 104, guiTop + 102, 154, 20, quest.completerNpc)); @@ -83,9 +88,12 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, if(!quest.mail.subject.isEmpty()) getButton(13).setDisplayText(quest.mail.subject); - addLabel(new GuiNpcLabel(8, "quest.repeatable", guiLeft + 7, guiTop + 178 + 5)); - this.addButton(new GuiNpcButton(8, guiLeft + 100, guiTop + 178,70, 20, new String[]{"gui.no","gui.yes","quest.mcdaily","quest.mcweekly","quest.rldaily","quest.rlweekly"}, quest.repeat.ordinal())); - + addLabel(new GuiNpcLabel(8, "quest.repeatable", guiLeft + 7, guiTop + 178 + 5)); + this.addButton(new GuiNpcButton(8, guiLeft + 100, guiTop + 178, 70, 20, + new String[]{"gui.no", "gui.yes", "quest.mcdaily", "quest.mcweekly", "quest.rldaily", "quest.rlweekly", "quest.mccustom", "quest.rlcustom"}, quest.repeat.ordinal())); + if(quest.repeat == EnumQuestRepeat.MCCUSTOM || quest.repeat == EnumQuestRepeat.RLCUSTOM) { + addButton(new GuiNpcButton(19, guiLeft + 175, guiTop + 178, 90, 20, "Set Cooldown")); + } addButton(new GuiNpcButton(16, guiLeft + 303, guiTop + 192, 50, 20, "gui.done")); if(!quest.mail.subject.isEmpty()) @@ -132,6 +140,7 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, if(button.id == 8) { quest.repeat = EnumQuestRepeat.values()[button.getValue()]; + initGui(); } if(button.id == 9) { @@ -159,14 +168,18 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, } if(button.id == 15 && quest.id >= 0){ setSubGui(new GuiQuestSelection(quest.nextQuestid)); -// questSelection = new GuiNPCQuestSelection(npc, getParent(), quest.nextQuestid); -// questSelection.listener = this; -// NoppesUtil.openGUI(player, questSelection); } if(button.id == 18) { setSubGui(new SubGuiNpcPartyOptions(quest.partyOptions)); } + if(button.id == 19) { + boolean isMCCustom = (quest.repeat == EnumQuestRepeat.MCCUSTOM); + setSubGui(new SubGuiNpcCooldownPicker(isMCCustom, quest.customCooldown)); + } + if(button.id == 33){ + setSubGui(new SubGuiNpcProfileOptions(quest.profileOptions)); + } if(button.id == 16){ close(); } @@ -209,7 +222,13 @@ public class SubGuiNpcQuest extends SubGuiInterface implements ISubGuiListener, else if(subgui instanceof SubGuiNpcCommand){ SubGuiNpcCommand sub = (SubGuiNpcCommand) subgui; quest.command = sub.command; - } + initGui(); + + } else if(subgui instanceof SubGuiNpcCooldownPicker){ + SubGuiNpcCooldownPicker cooldownGui = (SubGuiNpcCooldownPicker) subgui; + quest.customCooldown = cooldownGui.cooldownValue; + initGui(); + } else { initGui(); } diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiPlayerData.java b/src/main/java/noppes/npcs/client/gui/SubGuiPlayerData.java new file mode 100644 index 000000000..571009469 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/SubGuiPlayerData.java @@ -0,0 +1,1009 @@ +package noppes.npcs.client.gui; + +import kamkeel.npcs.network.PacketClient; +import kamkeel.npcs.network.packets.request.playerdata.PlayerDataGetInfoPacket; +import kamkeel.npcs.network.packets.request.playerdata.PlayerDataRemoveInfoPacket; +import net.minecraft.client.gui.GuiButton; +import noppes.npcs.client.CustomNpcResourceListener; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.constants.EnumPlayerData; +import org.lwjgl.opengl.GL11; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons; + +public class SubGuiPlayerData extends SubGuiInterface implements IPlayerDataInfo, ICustomScrollListener { + + //////////////////////////////////////////////////////////////////////////////// + // Fields + //////////////////////////////////////////////////////////////////////////////// + + // Current tab (10=Quest, 11=Dialog, 12=Transport, 13=Bank, 14=Faction) + private int currentTab = 10; + // View mode: 0 = Categorical (3 or 2 scrolls), 1 = Compact (2 or 1 scroll) + private int viewMode = 0; + + // ----- Quest Tab Components ----- + protected GuiCustomScroll questCatScroll, questActiveScroll, questFinishedScroll; + private String questCatSearch = "", questActiveSearch = "", questFinishedSearch = ""; + private HashMap questCatData = new HashMap<>(); + private HashMap questActiveData = new HashMap<>(); + private HashMap questFinishedData = new HashMap<>(); + private String selectedQuestCategory = ""; + + // ----- Dialog Tab Components ----- + protected GuiCustomScroll dialogCatScroll, dialogReadScroll, dialogCompactScroll; + private String dialogCatSearch = "", dialogReadSearch = "", dialogCompactSearch = ""; + private HashMap dialogCatData = new HashMap<>(); + private HashMap dialogReadData = new HashMap<>(); + private String selectedDialogCategory = ""; + + // ----- Transport Tab Components ----- + protected GuiCustomScroll transCatScroll, transLocScroll, transCompactScroll; + private String transCatSearch = "", transLocSearch = "", transCompactSearch = ""; + private HashMap transCatData = new HashMap<>(); + private HashMap transLocData = new HashMap<>(); + private String selectedTransCategory = ""; + + // ----- Bank and Faction (Single Scroll) ----- + protected GuiCustomScroll singleScroll; + private String singleSearch = ""; + private HashMap bankData = new HashMap<>(); + private HashMap factionData = new HashMap<>(); + + // ----- Divider & Resizing Variables ----- + // In categorical mode for Quest: two dividers (3 scrolls). + // In compact mode for Quest: one divider between two scrolls. + private int dividerOffset1 = 0; // In categorical: width of left scroll; in compact for quests: width of left scroll. + private int dividerOffset2 = 0; // Only used for Quest categorical mode. + private final int dividerWidth = 5; + private final int minScrollWidth = 50; + private boolean isResizing = false; + private int resizingDivider = 0; + private int initialDragX = 0; + + // ----- Layout Constants ----- + private final int leftPadding = 6; + private final int rightPadding = 6; + private final int scrollTopOffset = 30; + private final int verticalGapAboveTF = 3; + private final int textFieldHeight = 20; + private final int verticalGapBelowTF = 3; + + // ----- Other ----- + private String playerName; + + //////////////////////////////////////////////////////////////////////////////// + // Constructor + //////////////////////////////////////////////////////////////////////////////// + public SubGuiPlayerData(String playerName) { + this.playerName = playerName; + xSize = 420; + ySize = 215; + setBackground("menubg.png"); + closeOnEsc = true; + PacketClient.sendClient(new PlayerDataGetInfoPacket(playerName)); + } + + //////////////////////////////////////////////////////////////////////////////// + // Layout Helpers + //////////////////////////////////////////////////////////////////////////////// + + private int getPaddedLeft() { + return guiLeft + leftPadding; + } + + private int getPaddedRight() { + return guiLeft + xSize - rightPadding; + } + + private int getAvailableWidth() { + return getPaddedRight() - getPaddedLeft(); + } + + // Height available for scroll windows. + private int getScrollHeight() { + return ySize - (scrollTopOffset + verticalGapAboveTF + textFieldHeight + verticalGapBelowTF); + } + + // Y coordinate for textfields. + private int getTextFieldY() { + return guiTop + scrollTopOffset + getScrollHeight() + verticalGapAboveTF; + } + + //////////////////////////////////////////////////////////////////////////////// + // Component Setup Helpers + //////////////////////////////////////////////////////////////////////////////// + + // Create top buttons. + private void setupTopButtons() { + + // Show General Display Information + GuiMenuTopButton playerTab = new GuiMenuTopButton(-10, guiLeft + 4, guiTop - 10, playerName); + + GuiMenuTopButton btnQuest = new GuiMenuTopButton(10, playerTab.xPosition + playerTab.getButtonWidth(), guiTop - 10, "quest.quests"); + GuiMenuTopButton btnDialog = new GuiMenuTopButton(11, btnQuest.xPosition + btnQuest.getWidth(), guiTop - 10, "dialog.dialogs"); + GuiMenuTopButton btnTransport = new GuiMenuTopButton(12, btnDialog.xPosition + btnDialog.getWidth(), guiTop - 10, "global.transport"); + GuiMenuTopButton btnBank = new GuiMenuTopButton(13, btnTransport.xPosition + btnTransport.getWidth(), guiTop - 10, "global.banks"); + GuiMenuTopButton btnFaction = new GuiMenuTopButton(14, btnBank.xPosition + btnBank.getWidth(), guiTop - 10, "menu.factions"); + // Close button. + GuiMenuTopButton close = new GuiMenuTopButton(-5, guiLeft + xSize - 22, guiTop - 10, "X"); + + playerTab.active = (currentTab == -10); + btnQuest.active = (currentTab == 10); + btnDialog.active = (currentTab == 11); + btnTransport.active = (currentTab == 12); + btnBank.active = (currentTab == 13); + btnFaction.active = (currentTab == 14); + + addTopButton(playerTab); + addTopButton(btnQuest); + addTopButton(btnDialog); + addTopButton(btnTransport); + addTopButton(btnBank); + addTopButton(btnFaction); + addTopButton(close); + } + + // Helper to ensure scroll exists. + private GuiCustomScroll ensureScroll(GuiCustomScroll scroll, int id) { + if (scroll == null) { + scroll = new GuiCustomScroll(this, id, 0); + } + return scroll; + } + + // Helper to update a text field's position and width. + private void updateComponentPosition(int fieldId, int newX, int newWidth) { + GuiNpcTextField tf = getTextField(fieldId); + if (tf != null) { + tf.xPosition = newX; + tf.width = newWidth; + } + } + + // Helper to update a label's x position. + private void updateLabelPosition(int labelId, int newX) { + GuiNpcLabel lbl = getLabel(labelId); + if (lbl != null) { + lbl.x = newX; + } + } + + //////////////////////////////////////////////////////////////////////////////// + // initGui() & Tab Initialization + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void initGui() { + super.initGui(); + setupTopButtons(); + + if (currentTab == 10 || currentTab == 11 || currentTab == 12) { + addButton(new GuiToggleButton(20, guiLeft + xSize - 102, guiTop + 10, viewMode == 0)); + ((GuiToggleButton) getButton(20)).setTextureOff(specialIcons).setTextureOffPos( 16, 0); + ((GuiToggleButton) getButton(20)).setIconTexture(specialIcons).setIconPos( 16, 16, 16, 0 ); + } + + guiTop += 7; + // Initialize components based on current tab. + switch (currentTab) { + case 10: + initQuestTab(); + break; + case 11: + initDialogTab(); + break; + case 12: + initTransportTab(); + break; + case 13: + case 14: + initSingleTab(); + break; + } + // Delete button. + addButton(new GuiNpcButton(30, guiLeft + xSize - 60, guiTop + 10 - 7, 50, 20, "gui.remove")); + } + + // ----- Quest Tab Initialization ----- + private void initQuestTab() { + int paddedLeft = getPaddedLeft(); + int paddedRight = getPaddedRight(); + int availableWidth = getAvailableWidth(); + int scrollHeight = getScrollHeight(); + + if (viewMode == 0) { // Categorical: 3 scrolls. + if (!isResizing) { + dividerOffset1 = (availableWidth - 2 * dividerWidth) / 3; + dividerOffset2 = dividerOffset1 + dividerWidth + (availableWidth - 2 * dividerWidth) / 3; + } + // Quest Category Scroll. + questCatScroll = ensureScroll(questCatScroll, 0); + questCatScroll.guiLeft = paddedLeft; + questCatScroll.guiTop = guiTop + scrollTopOffset; + questCatScroll.setSize(dividerOffset1, scrollHeight); + questCatScroll.setList(new ArrayList<>(questCatData.keySet())); + questCatScroll.selected = -1; + questCatSearch = ""; + addScroll(questCatScroll); + addLabel(new GuiNpcLabel(1000, "Categories", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + // Quest Finished Scroll. + questFinishedScroll = ensureScroll(questFinishedScroll, 1); + questFinishedScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + questFinishedScroll.guiTop = guiTop + scrollTopOffset; + questFinishedScroll.setSize(dividerOffset2 - dividerOffset1 - dividerWidth, scrollHeight); + questFinishedScroll.setList(new ArrayList<>()); + questFinishedScroll.selected = -1; + questFinishedSearch = ""; + addScroll(questFinishedScroll); + addLabel(new GuiNpcLabel(1001, "Finished", paddedLeft + dividerOffset1 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + // Quest Active Scroll. + questActiveScroll = ensureScroll(questActiveScroll, 2); + questActiveScroll.guiLeft = paddedLeft + dividerOffset2 + dividerWidth; + questActiveScroll.guiTop = guiTop + scrollTopOffset; + questActiveScroll.setSize(paddedRight - (paddedLeft + dividerOffset2 + dividerWidth), scrollHeight); + questActiveScroll.setList(new ArrayList<>()); + questActiveScroll.selected = -1; + questActiveSearch = ""; + addScroll(questActiveScroll); + addLabel(new GuiNpcLabel(1002, "Active", paddedLeft + dividerOffset2 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + // Text Fields. + addTextField(new GuiNpcTextField(55, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, questCatSearch)); + addTextField(new GuiNpcTextField(56, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), dividerOffset2 - dividerOffset1 - dividerWidth, textFieldHeight, questFinishedSearch)); + addTextField(new GuiNpcTextField(57, this, fontRendererObj, paddedLeft + dividerOffset2 + dividerWidth, getTextFieldY(), paddedRight - (paddedLeft + dividerOffset2 + dividerWidth), textFieldHeight, questActiveSearch)); + } else { // Compact: 2 scrolls with resizable divider. + if (!isResizing) { + dividerOffset1 = (availableWidth - dividerWidth) / 2; + } + questFinishedScroll = ensureScroll(questFinishedScroll, 1); + questFinishedScroll.guiLeft = paddedLeft; + questFinishedScroll.guiTop = guiTop + scrollTopOffset; + questFinishedScroll.setSize(dividerOffset1, scrollHeight); + questFinishedScroll.setList(new ArrayList<>(questFinishedData.keySet())); + questFinishedSearch = ""; + addScroll(questFinishedScroll); + addLabel(new GuiNpcLabel(1003, "Finished", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + questActiveScroll = ensureScroll(questActiveScroll, 2); + questActiveScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + questActiveScroll.guiTop = guiTop + scrollTopOffset; + questActiveScroll.setSize(availableWidth - dividerOffset1 - dividerWidth, scrollHeight); + questActiveScroll.setList(new ArrayList<>(questActiveData.keySet())); + questActiveSearch = ""; + addScroll(questActiveScroll); + addLabel(new GuiNpcLabel(1004, "Active", paddedLeft + dividerOffset1 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + addTextField(new GuiNpcTextField(55, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, questFinishedSearch)); + addTextField(new GuiNpcTextField(56, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), availableWidth - dividerOffset1 - dividerWidth, textFieldHeight, questActiveSearch)); + } + } + + // ----- Dialog Tab Initialization ----- + private void initDialogTab() { + int paddedLeft = getPaddedLeft(); + int availableWidth = getAvailableWidth(); + int scrollHeight = getScrollHeight(); + + if (viewMode == 0) { // Categorical: 2 scrolls. + if (!isResizing) { + dividerOffset1 = (availableWidth - dividerWidth) / 2; + } + dialogCatScroll = ensureScroll(dialogCatScroll, 0); + dialogCatScroll.guiLeft = paddedLeft; + dialogCatScroll.guiTop = guiTop + scrollTopOffset; + dialogCatScroll.setSize(dividerOffset1, scrollHeight); + dialogCatScroll.selected = -1; + dialogCatScroll.setList(new ArrayList<>(dialogCatData.keySet())); + addScroll(dialogCatScroll); + addLabel(new GuiNpcLabel(2000, "Categories", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + dialogReadScroll = ensureScroll(dialogReadScroll, 1); + dialogReadScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + dialogReadScroll.guiTop = guiTop + scrollTopOffset; + dialogReadScroll.setSize(availableWidth - dividerOffset1 - dividerWidth, scrollHeight); + dialogReadScroll.selected = -1; + dialogReadScroll.setList(new ArrayList<>()); + addScroll(dialogReadScroll); + addLabel(new GuiNpcLabel(2001, "Read", paddedLeft + dividerOffset1 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + addTextField(new GuiNpcTextField(55, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, dialogCatSearch)); + addTextField(new GuiNpcTextField(56, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), availableWidth - dividerOffset1 - dividerWidth, textFieldHeight, dialogReadSearch)); + } else { // Compact: 1 scroll (no divider). + dialogCompactScroll = ensureScroll(dialogCompactScroll, 5); + dialogCompactScroll.guiLeft = paddedLeft; + dialogCompactScroll.guiTop = guiTop + scrollTopOffset; + dialogCompactScroll.setSize(availableWidth, getScrollHeight()); + dialogCompactScroll.setList(new ArrayList<>(dialogReadData.keySet())); + dialogCompactScroll.selected = -1; + addScroll(dialogCompactScroll); + addLabel(new GuiNpcLabel(2002, "All", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + addTextField(new GuiNpcTextField(55, this, fontRendererObj, paddedLeft, getTextFieldY(), availableWidth, textFieldHeight, dialogCompactSearch)); + } + } + + // ----- Transport Tab Initialization ----- + private void initTransportTab() { + int paddedLeft = getPaddedLeft(); + int availableWidth = getAvailableWidth(); + int scrollHeight = getScrollHeight(); + + if (viewMode == 0) { // Categorical: 2 scrolls. + if (!isResizing) { + dividerOffset1 = (availableWidth - dividerWidth) / 2; + } + transCatScroll = ensureScroll(transCatScroll, 3); + transCatScroll.guiLeft = paddedLeft; + transCatScroll.guiTop = guiTop + scrollTopOffset; + transCatScroll.setSize(dividerOffset1, scrollHeight); + transCatScroll.selected = -1; + transCatScroll.setList(new ArrayList<>(transCatData.keySet())); + addScroll(transCatScroll); + addLabel(new GuiNpcLabel(3000, "Categories", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + transLocScroll = ensureScroll(transLocScroll, 4); + transLocScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + transLocScroll.guiTop = guiTop + scrollTopOffset; + transLocScroll.setSize(availableWidth - dividerOffset1 - dividerWidth, scrollHeight); + transLocScroll.selected = -1; + transLocScroll.setList(new ArrayList<>()); + addScroll(transLocScroll); + addLabel(new GuiNpcLabel(3001, "Locations", paddedLeft + dividerOffset1 + dividerWidth, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + + addTextField(new GuiNpcTextField(60, this, fontRendererObj, paddedLeft, getTextFieldY(), dividerOffset1, textFieldHeight, transCatSearch)); + addTextField(new GuiNpcTextField(61, this, fontRendererObj, paddedLeft + dividerOffset1 + dividerWidth, getTextFieldY(), availableWidth - dividerOffset1 - dividerWidth, textFieldHeight, transLocSearch)); + } else { // Compact: 1 scroll (no divider). + transCompactScroll = ensureScroll(transCompactScroll, 5); + transCompactScroll.guiLeft = paddedLeft; + transCompactScroll.guiTop = guiTop + scrollTopOffset; + transCompactScroll.selected = -1; + transCompactScroll.setSize(availableWidth, getScrollHeight()); + transCompactScroll.setList(new ArrayList<>(transLocData.keySet())); + addScroll(transCompactScroll); + addLabel(new GuiNpcLabel(3002, "All", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + addTextField(new GuiNpcTextField(60, this, fontRendererObj, paddedLeft, getTextFieldY(), availableWidth, textFieldHeight, transCompactSearch)); + } + } + + // ----- Single Tab Initialization (Bank/Faction) ----- + private void initSingleTab() { + int paddedLeft = getPaddedLeft(); + int availableWidth = getAvailableWidth(); + int scrollHeight = getScrollHeight(); + singleScroll = ensureScroll(singleScroll, 0); + singleScroll.guiLeft = paddedLeft; + singleScroll.guiTop = guiTop + scrollTopOffset; + if (currentTab == 13) { + singleScroll.setSize(availableWidth, scrollHeight); + singleScroll.setList(new ArrayList<>(bankData.keySet())); + singleScroll.selected = -1; + addLabel(new GuiNpcLabel(4000, "Bank", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + } else { + singleScroll.setSize(availableWidth, scrollHeight); + singleScroll.setList(new ArrayList<>(factionData.keySet())); + singleScroll.selected = -1; + addLabel(new GuiNpcLabel(4000, "Faction", paddedLeft, guiTop + 15, CustomNpcResourceListener.DefaultTextColor)); + } + addScroll(singleScroll); + addTextField(new GuiNpcTextField(70, this, fontRendererObj, paddedLeft, getTextFieldY(), availableWidth, textFieldHeight, singleSearch)); + } + + //////////////////////////////////////////////////////////////////////////////// + // Drawing Helpers + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public void drawBackground() { + super.drawBackground(); + + int paddingTopBottom = 25; + int scrollHeight = getScrollHeight(); + int paddedLeft = getPaddedLeft(); + int widthPadding = 1; + + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + GL11.glEnable(GL11.GL_DEPTH_TEST); + // In compact mode for Quests, draw divider between the two scrolls. + if (currentTab == 10 && viewMode != 0 && !hasSubGui()) { + int dividerX = paddedLeft + dividerOffset1; + drawRect(dividerX + widthPadding, guiTop + scrollTopOffset + paddingTopBottom, dividerX + dividerWidth - widthPadding, guiTop + scrollTopOffset + scrollHeight - paddingTopBottom, 0xFF707070); + } + // In categorical mode for Quest, draw both dividers. + if (currentTab == 10 && viewMode == 0 && !hasSubGui()) { + int dividerX1 = paddedLeft + dividerOffset1; + int dividerX2 = paddedLeft + dividerOffset2; + drawRect(dividerX1 + widthPadding, guiTop + scrollTopOffset + paddingTopBottom, dividerX1 + dividerWidth - widthPadding, guiTop + scrollTopOffset + scrollHeight - paddingTopBottom, 0xFF707070); + drawRect(dividerX2 + widthPadding, guiTop + scrollTopOffset + paddingTopBottom, dividerX2 + dividerWidth - widthPadding, guiTop + scrollTopOffset + scrollHeight - paddingTopBottom, 0xFF707070); + } else if ((currentTab == 11 || currentTab == 12) && viewMode == 0 && !hasSubGui()) { + int dividerX = paddedLeft + dividerOffset1; + drawRect(dividerX + widthPadding, guiTop + scrollTopOffset + paddingTopBottom, dividerX + dividerWidth - widthPadding, guiTop + scrollTopOffset + scrollHeight - paddingTopBottom, 0xFF707070); + } + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glPopAttrib(); + } + + //////////////////////////////////////////////////////////////////////////////// + // Mouse & Resizing Handlers + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void mouseClicked(int mouseX, int mouseY, int mouseButton) { + int hitMargin = 3; + int regionTop = guiTop + scrollTopOffset; + int regionBottom = regionTop + getScrollHeight(); + int paddedLeft = getPaddedLeft(); + int availableWidth = getAvailableWidth(); + if (!hasSubGui() && mouseY >= regionTop && mouseY <= regionBottom) { + if (viewMode == 0) { + if (currentTab == 10) { // Quest categorical: 3 scrolls. + int dividerX1 = paddedLeft + dividerOffset1; + int dividerX2 = paddedLeft + dividerOffset2; + if (mouseX >= dividerX1 - hitMargin && mouseX <= dividerX1 + dividerWidth + hitMargin) { + isResizing = true; + resizingDivider = 1; + initialDragX = mouseX; + return; + } else if (mouseX >= dividerX2 - hitMargin && mouseX <= dividerX2 + dividerWidth + hitMargin) { + isResizing = true; + resizingDivider = 2; + initialDragX = mouseX; + return; + } + } else if (currentTab == 11 || currentTab == 12) { + int dividerX = paddedLeft + dividerOffset1; + if (mouseX >= dividerX - hitMargin && mouseX <= dividerX + dividerWidth + hitMargin) { + isResizing = true; + resizingDivider = 1; + initialDragX = mouseX; + return; + } + } + } else { // Compact mode. + if (currentTab == 10) { // Quest compact: 2 scrolls. + int defaultWidth = (availableWidth - dividerWidth) / 2; + if (!isResizing) dividerOffset1 = defaultWidth; + int dividerX = paddedLeft + dividerOffset1; + if (mouseX >= dividerX - hitMargin && mouseX <= dividerX + dividerWidth + hitMargin) { + isResizing = true; + resizingDivider = 1; + initialDragX = mouseX; + return; + } + } + // Dialog/Transport compact have only one scroll => no divider. + } + } + super.mouseClicked(mouseX, mouseY, mouseButton); + } + + @Override + public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + int paddedLeft = getPaddedLeft(); + int paddedRight = getPaddedRight(); + int availableWidth = getAvailableWidth(); + if (isResizing) { + int dx = mouseX - initialDragX; + initialDragX = mouseX; + // Handle Quest tab resizing. + if (currentTab == 10) { + if (viewMode == 0) { // Categorical (3 scrolls) + if (resizingDivider == 1) { + dividerOffset1 += dx; + int maxOffset = dividerOffset2 - dividerWidth - minScrollWidth; + dividerOffset1 = clamp(dividerOffset1, minScrollWidth, maxOffset); + questCatScroll.setSize(dividerOffset1, getScrollHeight()); + questFinishedScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + questFinishedScroll.setSize(dividerOffset2 - dividerOffset1 - dividerWidth, getScrollHeight()); + questActiveScroll.guiLeft = paddedLeft + dividerOffset2 + dividerWidth; + questActiveScroll.setSize(availableWidth - (dividerOffset2 + dividerWidth), getScrollHeight()); + updateComponentPosition(55, paddedLeft, dividerOffset1); + updateComponentPosition(56, paddedLeft + dividerOffset1 + dividerWidth, dividerOffset2 - dividerOffset1 - dividerWidth); + updateComponentPosition(57, paddedLeft + dividerOffset2 + dividerWidth, availableWidth - (dividerOffset2 + dividerWidth)); + updateLabelPosition(1000, paddedLeft); + updateLabelPosition(1001, paddedLeft + dividerOffset1 + dividerWidth); + updateLabelPosition(1002, paddedLeft + dividerOffset2 + dividerWidth); + } else if (resizingDivider == 2) { + dividerOffset2 += dx; + int minOffset = dividerOffset1 + dividerWidth + minScrollWidth; + int maxOffset = availableWidth - minScrollWidth; + dividerOffset2 = clamp(dividerOffset2, minOffset, maxOffset); + questFinishedScroll.setSize(dividerOffset2 - dividerOffset1 - dividerWidth, getScrollHeight()); + questActiveScroll.guiLeft = paddedLeft + dividerOffset2 + dividerWidth; + questActiveScroll.setSize(availableWidth - (dividerOffset2 + dividerWidth), getScrollHeight()); + updateComponentPosition(56, paddedLeft + dividerOffset1 + dividerWidth, dividerOffset2 - dividerOffset1 - dividerWidth); + updateComponentPosition(57, paddedLeft + dividerOffset2 + dividerWidth, availableWidth - (dividerOffset2 + dividerWidth)); + updateLabelPosition(1001, paddedLeft + dividerOffset1 + dividerWidth); + updateLabelPosition(1002, paddedLeft + dividerOffset2 + dividerWidth); + } + } else { // Compact mode for Quests (2 scrolls) + if (resizingDivider == 1) { + dividerOffset1 += dx; + dividerOffset1 = clamp(dividerOffset1, minScrollWidth, availableWidth - dividerWidth - minScrollWidth); + questFinishedScroll.setSize(dividerOffset1, getScrollHeight()); + questActiveScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + questActiveScroll.setSize(availableWidth - dividerOffset1 - dividerWidth, getScrollHeight()); + updateComponentPosition(55, paddedLeft, dividerOffset1); + updateComponentPosition(56, paddedLeft + dividerOffset1 + dividerWidth, availableWidth - dividerOffset1 - dividerWidth); + updateLabelPosition(1003, paddedLeft); + updateLabelPosition(1004, paddedLeft + dividerOffset1 + dividerWidth); + } + } + } else if ((currentTab == 11 || currentTab == 12) && viewMode == 0) { + // For Dialog and Transport in categorical mode. + dividerOffset1 += dx; + dividerOffset1 = clamp(dividerOffset1, minScrollWidth, availableWidth - minScrollWidth); + if (currentTab == 11) { + dialogCatScroll.setSize(dividerOffset1, getScrollHeight()); + dialogReadScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + dialogReadScroll.setSize(availableWidth - dividerOffset1 - dividerWidth, getScrollHeight()); + updateComponentPosition(55, paddedLeft, dividerOffset1); + updateComponentPosition(56, paddedLeft + dividerOffset1 + dividerWidth, availableWidth - dividerOffset1 - dividerWidth); + updateLabelPosition(2000, paddedLeft); + updateLabelPosition(2001, paddedLeft + dividerOffset1 + dividerWidth); + } else if (currentTab == 12) { + transCatScroll.setSize(dividerOffset1, getScrollHeight()); + transLocScroll.guiLeft = paddedLeft + dividerOffset1 + dividerWidth; + transLocScroll.setSize(availableWidth - dividerOffset1 - dividerWidth, getScrollHeight()); + updateComponentPosition(60, paddedLeft, dividerOffset1); + updateComponentPosition(61, paddedLeft + dividerOffset1 + dividerWidth, availableWidth - dividerOffset1 - dividerWidth); + updateLabelPosition(3000, paddedLeft); + updateLabelPosition(3001, paddedLeft + dividerOffset1 + dividerWidth); + } + } + return; + } + super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + } + + @Override + protected void mouseMovedOrUp(int mouseX, int mouseY, int state) { + if (isResizing) { + isResizing = false; + resizingDivider = 0; + return; + } + super.mouseMovedOrUp(mouseX, mouseY, state); + } + + // Simple clamp helper. + private int clamp(int value, int min, int max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + } + + //////////////////////////////////////////////////////////////////////////////// + // Key & Search Field Handling + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void keyTyped(char c, int i) { + super.keyTyped(c, i); + if (currentTab == 10) { + if (viewMode == 0) { + updateQuestSearchField(55, 56, 57); + } else { + updateQuestSearchFieldCompact(55, 56); + } + } else if (currentTab == 11) { + if (viewMode == 0) { + updateDialogSearchField(55, 56); + } else { + updateDialogSearchFieldCompact(55); + } + } else if (currentTab == 12) { + if (viewMode == 0) { + updateTransportSearchField(60, 61); + } else { + updateTransportSearchFieldCompact(60); + } + } else if (currentTab == 13 || currentTab == 14) { + updateSingleSearchField(70); + } + } + + // Update quest search fields (categorical mode). + private void updateQuestSearchField(int catFieldId, int finishedFieldId, int activeFieldId) { + GuiNpcTextField tf = getTextField(catFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!questCatSearch.equals(newText)) { + questCatSearch = newText; + if (questCatScroll != null) { + if (selectedQuestCategory.isEmpty()) + questCatScroll.setList(new ArrayList<>()); + else + questCatScroll.setList(filterList(questCatData, questCatSearch)); + } + } + } + tf = getTextField(finishedFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!questFinishedSearch.equals(newText)) { + questFinishedSearch = newText; + if (questFinishedScroll != null) + questFinishedScroll.setList( + selectedQuestCategory.isEmpty() ? + new ArrayList<>() : + filterAndTrimListByCategory(questFinishedData, selectedQuestCategory, questFinishedSearch) + ); + } + } + tf = getTextField(activeFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!questActiveSearch.equals(newText)) { + questActiveSearch = newText; + if (questActiveScroll != null) + questActiveScroll.setList( + selectedQuestCategory.isEmpty() ? + new ArrayList<>() : + filterAndTrimListByCategory(questActiveData, selectedQuestCategory, questActiveSearch) + ); + } + } + } + + // Update quest search fields in compact mode. + private void updateQuestSearchFieldCompact(int finishedFieldId, int activeFieldId) { + GuiNpcTextField tf = getTextField(finishedFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!questFinishedSearch.equals(newText)) { + questFinishedSearch = newText; + if (questFinishedScroll != null) + questFinishedScroll.setList(filterList(questFinishedData, questFinishedSearch)); + } + } + tf = getTextField(activeFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!questActiveSearch.equals(newText)) { + questActiveSearch = newText; + if (questActiveScroll != null) + questActiveScroll.setList(filterList(questActiveData, questActiveSearch)); + } + } + } + + // Update dialog search fields (categorical). + private void updateDialogSearchField(int catFieldId, int readFieldId) { + GuiNpcTextField tf = getTextField(catFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!dialogCatSearch.equals(newText)) { + dialogCatSearch = newText; + if (dialogCatScroll != null) + dialogCatScroll.setList( + selectedDialogCategory.isEmpty() ? + new ArrayList<>() : + filterList(dialogCatData, dialogCatSearch) + ); + } + } + tf = getTextField(readFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!dialogReadSearch.equals(newText)) { + dialogReadSearch = newText; + if (dialogReadScroll != null) + dialogReadScroll.setList( + selectedDialogCategory.isEmpty() ? + new ArrayList<>() : + filterAndTrimListByCategory(dialogReadData, selectedDialogCategory, dialogReadSearch) + ); + } + } + } + + // Update dialog search fields (compact). + private void updateDialogSearchFieldCompact(int fieldId) { + GuiNpcTextField tf = getTextField(fieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!dialogCompactSearch.equals(newText)) { + dialogCompactSearch = newText; + if (dialogCompactScroll != null) + dialogCompactScroll.setList(filterList(dialogReadData, dialogCompactSearch)); + } + } + } + + // Update transport search fields (categorical). + private void updateTransportSearchField(int catFieldId, int locFieldId) { + GuiNpcTextField tf = getTextField(catFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!transCatSearch.equals(newText)) { + transCatSearch = newText; + if (transCatScroll != null) + transCatScroll.setList( + selectedTransCategory.isEmpty() ? + new ArrayList<>() : + filterList(transCatData, transCatSearch) + ); + } + } + tf = getTextField(locFieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!transLocSearch.equals(newText)) { + transLocSearch = newText; + if (transLocScroll != null) + transLocScroll.setList( + selectedTransCategory.isEmpty() ? + new ArrayList<>() : + filterAndTrimListByCategory(transLocData, selectedTransCategory, transLocSearch) + ); + } + } + } + + // Update transport search fields (compact). + private void updateTransportSearchFieldCompact(int fieldId) { + GuiNpcTextField tf = getTextField(fieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!transCompactSearch.equals(newText)) { + transCompactSearch = newText; + if (transCompactScroll != null) + transCompactScroll.setList(filterList(transLocData, transCompactSearch)); + } + } + } + + // Update search field for single scroll (Bank/Faction). + private void updateSingleSearchField(int fieldId) { + GuiNpcTextField tf = getTextField(fieldId); + if (tf != null && tf.isFocused()) { + String newText = tf.getText().toLowerCase(); + if (!singleSearch.equals(newText)) { + singleSearch = newText; + if (singleScroll != null) + singleScroll.setList(filterList(currentTab == 13 ? bankData : factionData, singleSearch)); + } + } + } + + // Standard filtering helpers. + private List filterList(HashMap data, String search) { + List list = new ArrayList<>(); + for (String key : data.keySet()) { + if (key.toLowerCase().contains(search)) { + list.add(key); + } + } + return list; + } + + private List filterAndTrimListByCategory(HashMap data, String category, String search) { + List list = new ArrayList<>(); + String prefix = category + ":"; + for (String key : data.keySet()) { + if (key.startsWith(prefix)) { + String trimmed = key.substring(prefix.length()).trim(); + if (trimmed.toLowerCase().contains(search)) { + list.add(trimmed); + } + } + } + return list; + } + + //////////////////////////////////////////////////////////////////////////////// + // Action Handling + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void actionPerformed(GuiButton button) { + // Close if the "X" button was clicked. + if (button.id == -5) { + close(); + return; + } + // Tab switching. + if (button.id >= 10 && button.id <= 14) { + currentTab = button.id; + initGui(); // Reinitialize components using stored data. + return; + } + // Mode toggle. + if (button.id == 20) { + viewMode = (viewMode == 0) ? 1 : 0; + initGui(); + return; + } + // Delete button. + if (button.id == 30) { + Integer selectedID = null; + EnumPlayerData tabType = null; + // Quest tab + if (currentTab == 10) { + if (viewMode == 0) { // Categorical mode + if (questCatScroll.getSelected() == null) + return; + // Use category + selection key. + if (questActiveScroll.getSelected() != null) { + selectedID = removeSelection(questActiveScroll, questActiveData, questCatScroll.getSelected()); + } else if (questFinishedScroll.getSelected() != null) { + selectedID = removeSelection(questFinishedScroll, questFinishedData, questCatScroll.getSelected()); + } + } else { // Compact mode: key is just the selection. + if (questActiveScroll.getSelected() != null) { + selectedID = removeSelection(questActiveScroll, questActiveData, null); + } else if (questFinishedScroll.getSelected() != null) { + selectedID = removeSelection(questFinishedScroll, questFinishedData, null); + } + } + tabType = EnumPlayerData.Quest; + } + // Dialog tab + else if (currentTab == 11) { + if (viewMode == 0) { + if (dialogReadScroll.getSelected() != null && dialogCatScroll.getSelected() != null) { + selectedID = removeSelection(dialogReadScroll, dialogReadData, dialogCatScroll.getSelected()); + } + } else { + if (dialogCompactScroll.getSelected() != null) { + selectedID = removeSelection(dialogCompactScroll, dialogReadData, null); + } + } + tabType = EnumPlayerData.Dialog; + } + // Transport tab + else if (currentTab == 12) { + if (viewMode == 0) { + if (transLocScroll.getSelected() != null && transCatScroll.getSelected() != null) { + selectedID = removeSelection(transLocScroll, transLocData, transCatScroll.getSelected()); + } + } else { + if (transCompactScroll.getSelected() != null) { + selectedID = removeSelection(transCompactScroll, transLocData, null); + } + } + tabType = EnumPlayerData.Transport; + } + // Bank tab + else if (currentTab == 13) { + if (singleScroll.getSelected() != null) { + selectedID = removeSelection(singleScroll, bankData, null); + } + tabType = EnumPlayerData.Bank; + } + // Faction tab + else if (currentTab == 14) { + if (singleScroll.getSelected() != null) { + selectedID = removeSelection(singleScroll, factionData, null); + } + tabType = EnumPlayerData.Factions; + } + if (selectedID != null) { + PacketClient.sendClient(new PlayerDataRemoveInfoPacket(playerName, tabType, selectedID)); + } + } + } + + /** + * Helper method that removes the selected entry from a scroll and its backing data. + * + * @param scroll The GuiCustomScroll in question. + * @param data The backing map holding keys and IDs. + * @param prefix If non-null and non-empty, the key is built as "prefix: " + scroll.getSelected(); otherwise, + * scroll.getSelected() is used. + * @return The ID of the removed item, or null if none was found. + */ + private Integer removeSelection(GuiCustomScroll scroll, Map data, String prefix) { + if (scroll.getSelected() == null) return null; + String key = (prefix == null || prefix.isEmpty()) ? scroll.getSelected() : prefix + ": " + scroll.getSelected(); + Integer id = data.get(key); + if (id != null) { + scroll.list.remove(scroll.selected); + scroll.selected = -1; + data.remove(key); + } + return id; + } + + //////////////////////////////////////////////////////////////////////////////// + // Data Setting Methods (IPlayerDataInfo) + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void setQuestData(Map questCategories, Map questActive, Map questFinished) { + this.questCatData = new HashMap<>(questCategories); + this.questActiveData = new HashMap<>(questActive); + this.questFinishedData = new HashMap<>(questFinished); + if (questCatScroll != null) { + questCatScroll.setList(new ArrayList<>(questCatData.keySet())); + } + } + + @Override + public void setDialogData(Map dialogCategories, Map dialogRead) { + this.dialogCatData = new HashMap<>(dialogCategories); + this.dialogReadData = new HashMap<>(dialogRead); + if (dialogCatScroll != null) { + dialogCatScroll.setList(new ArrayList<>(dialogCatData.keySet())); + } + } + + @Override + public void setTransportData(Map transportCategories, Map transportLocations) { + this.transCatData = new HashMap<>(transportCategories); + this.transLocData = new HashMap<>(transportLocations); + if (transCatScroll != null) { + transCatScroll.setList(new ArrayList<>(transCatData.keySet())); + } + } + + @Override + public void setBankData(Map bankData) { + this.bankData = new HashMap<>(bankData); + if (singleScroll != null && currentTab == 13) { + singleScroll.setList(new ArrayList<>(this.bankData.keySet())); + } + } + + @Override + public void setFactionData(Map factionData) { + this.factionData = new HashMap<>(factionData); + if (singleScroll != null && currentTab == 14) { + singleScroll.setList(new ArrayList<>(this.factionData.keySet())); + } + } + + //////////////////////////////////////////////////////////////////////////////// + // Custom Scroll Click Handling + //////////////////////////////////////////////////////////////////////////////// + + @Override + public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) { + if (guiCustomScroll == questCatScroll) { + selectedQuestCategory = questCatScroll.getSelected(); + questFinishedScroll.resetScroll(); + questActiveScroll.resetScroll(); + if (!selectedQuestCategory.isEmpty()) { + questFinishedScroll.setList(filterAndTrimListByCategory(questFinishedData, selectedQuestCategory, questFinishedSearch)); + questActiveScroll.setList(filterAndTrimListByCategory(questActiveData, selectedQuestCategory, questActiveSearch)); + } else { + questFinishedScroll.setList(new ArrayList<>()); + questActiveScroll.setList(new ArrayList<>()); + } + } else if (guiCustomScroll == dialogCatScroll) { + selectedDialogCategory = dialogCatScroll.getSelected(); + dialogReadScroll.resetScroll(); + if (!selectedDialogCategory.isEmpty()) { + dialogReadScroll.setList(filterAndTrimListByCategory(dialogReadData, selectedDialogCategory, dialogReadSearch)); + } else { + dialogReadScroll.setList(new ArrayList<>()); + } + } else if (guiCustomScroll == transCatScroll) { + selectedTransCategory = transCatScroll.getSelected(); + transLocScroll.resetScroll(); + if (!selectedTransCategory.isEmpty()) { + transLocScroll.setList(filterAndTrimListByCategory(transLocData, selectedTransCategory, transLocSearch)); + } else { + transLocScroll.setList(new ArrayList<>()); + } + } else if (guiCustomScroll == questActiveScroll) { + questFinishedScroll.selected = -1; + } else if (guiCustomScroll == questFinishedScroll) { + questActiveScroll.selected = -1; + } + } +} diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAdvancedLinkedNpc.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAdvancedLinkedNpc.java index 6c4c771ae..4d71c789b 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAdvancedLinkedNpc.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCAdvancedLinkedNpc.java @@ -5,9 +5,7 @@ import kamkeel.npcs.network.packets.request.linked.LinkedGetAllPacket; import kamkeel.npcs.network.packets.request.linked.LinkedSetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import java.util.ArrayList; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCDialogNpcOptions.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCDialogNpcOptions.java index 88dd27c92..4db6170b1 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCDialogNpcOptions.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCDialogNpcOptions.java @@ -7,10 +7,8 @@ import kamkeel.npcs.network.packets.request.dialog.DialogNpcSetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiDialogSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.DialogOption; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCFactionSetup.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCFactionSetup.java index e7aab677e..314e2cb92 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCFactionSetup.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCFactionSetup.java @@ -6,10 +6,8 @@ import kamkeel.npcs.network.packets.request.faction.FactionsGetPacket; import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.SubGuiNpcFactionOptions; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import java.util.HashMap; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCLinesMenu.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCLinesMenu.java index 92d5c49dd..3a1b0a0e7 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCLinesMenu.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCLinesMenu.java @@ -4,14 +4,12 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.GuiNPCLinesEdit; import noppes.npcs.client.gui.util.GuiNPCInterface2; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcButtonYesNo; import noppes.npcs.client.gui.util.GuiNpcLabel; - import noppes.npcs.entity.EntityNPCInterface; public class GuiNPCLinesMenu extends GuiNPCInterface2 { diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCMarks.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCMarks.java index bad32b76b..048af68c0 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCMarks.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCMarks.java @@ -1,14 +1,11 @@ package noppes.npcs.client.gui.advanced; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedGetPacket; import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedMarkDataPacket; import net.minecraft.client.gui.GuiButton; - import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.SubGuiNpcAvailability; import noppes.npcs.client.gui.util.*; - import noppes.npcs.constants.MarkType; import noppes.npcs.controllers.data.MarkData; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCNightSetup.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCNightSetup.java index cbe94b524..4ca3755b6 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCNightSetup.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCNightSetup.java @@ -6,12 +6,10 @@ import kamkeel.npcs.network.packets.request.transform.TransformLoadPacket; import kamkeel.npcs.network.packets.request.transform.TransformSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.util.GuiNPCInterface2; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.IGuiData; - import noppes.npcs.controllers.data.DataTransform; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCSoundsMenu.java b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCSoundsMenu.java index efd0e5d0b..352b9044c 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCSoundsMenu.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCSoundsMenu.java @@ -4,10 +4,8 @@ import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAdvancedSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiSoundSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; public class GuiNPCSoundsMenu extends GuiNPCInterface2 implements ITextfieldListener, ISubGuiListener 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 54c5abecf..ad91240de 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCTagSetup.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/GuiNPCTagSetup.java @@ -1,9 +1,9 @@ package noppes.npcs.client.gui.advanced; import kamkeel.npcs.network.PacketClient; +import kamkeel.npcs.network.packets.request.tags.TagSetPacket; import kamkeel.npcs.network.packets.request.tags.TagsGetPacket; import kamkeel.npcs.network.packets.request.tags.TagsNpcGetPacket; -import kamkeel.npcs.network.packets.request.tags.TagSetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; diff --git a/src/main/java/noppes/npcs/client/gui/custom/GuiCustom.java b/src/main/java/noppes/npcs/client/gui/custom/GuiCustom.java index 6bf025ae3..dfa5b928d 100644 --- a/src/main/java/noppes/npcs/client/gui/custom/GuiCustom.java +++ b/src/main/java/noppes/npcs/client/gui/custom/GuiCustom.java @@ -25,7 +25,6 @@ import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import noppes.npcs.api.gui.ICustomGuiComponent; - import noppes.npcs.client.gui.custom.components.*; import noppes.npcs.client.gui.custom.interfaces.IClickListener; import noppes.npcs.client.gui.custom.interfaces.IDataHolder; @@ -33,7 +32,6 @@ import noppes.npcs.client.gui.custom.interfaces.IGuiComponent; import noppes.npcs.client.gui.util.GuiCustomScroll; import noppes.npcs.client.gui.util.ICustomScrollListener; import noppes.npcs.client.gui.util.IGuiData; - import noppes.npcs.containers.ContainerCustomGui; import noppes.npcs.scripted.gui.*; import org.lwjgl.input.Keyboard; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageBanks.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageBanks.java index ec0f581b1..0b0b693f5 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageBanks.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageBanks.java @@ -7,10 +7,8 @@ import kamkeel.npcs.network.packets.request.bank.BankSavePacket; import kamkeel.npcs.network.packets.request.bank.BanksGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.*; - import noppes.npcs.containers.ContainerManageBanks; import noppes.npcs.controllers.data.Bank; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageDialogs.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageDialogs.java index 0dafe3325..dc0e9bfbc 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageDialogs.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageDialogs.java @@ -7,12 +7,10 @@ import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiEditText; import noppes.npcs.client.gui.SubGuiNpcDialog; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.data.DialogCategory; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageEffects.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageEffects.java index b227cc829..d0da71469 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageEffects.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageEffects.java @@ -28,6 +28,8 @@ import java.util.HashMap; import java.util.List; import java.util.Vector; +import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons; + public class GuiNPCManageEffects extends GuiNPCInterface2 implements ICustomScrollListener, IScrollData, IGuiData, ISubGuiListener, GuiYesNoCallback { public GuiCustomScroll scrollEffects; public HashMap data = new HashMap<>(); @@ -170,10 +172,8 @@ public class GuiNPCManageEffects extends GuiNPCInterface2 implements ICustomScro func_152125_a(x, y, 0, 0, 1, 1, iconRenderSize, iconRenderSize, 1, 1); } GL11.glDisable(GL11.GL_DEPTH_TEST); - - // TODO: Fix ICONS - // textureManager.bindTexture(new ResourceLocation(CustomNpcPlusDBC.ID + ":textures/gui/icons.png")); - // func_152125_a(x, y, 0, 240, 16, 16, iconRenderSize, iconRenderSize, 256, 256); + textureManager.bindTexture(specialIcons); + func_152125_a(x, y, 0, 224, 16, 16, iconRenderSize, iconRenderSize, 256, 256); GL11.glEnable(GL11.GL_DEPTH_TEST); x += iconRenderSize + 3; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageFactions.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageFactions.java index c2cc01330..427543a42 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageFactions.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageFactions.java @@ -10,14 +10,11 @@ import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.SubGuiNpcFactionPoints; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Faction; -import noppes.npcs.controllers.data.Quest; import noppes.npcs.entity.EntityNPCInterface; import java.util.*; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageLinked.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageLinked.java index 4c37aa728..4a11ef336 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageLinked.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageLinked.java @@ -1,13 +1,9 @@ package noppes.npcs.client.gui.global; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.packets.request.effects.EffectRemovePacket; -import kamkeel.npcs.network.packets.request.effects.EffectSavePacket; import kamkeel.npcs.network.packets.request.linked.*; -import kamkeel.npcs.network.packets.request.quest.QuestSavePacket; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; - import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.client.renderer.OpenGlHelper; @@ -24,11 +20,8 @@ import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiEditText; import noppes.npcs.client.gui.item.SubGuiLinkedItem; import noppes.npcs.client.gui.util.*; - import noppes.npcs.client.renderer.ImageData; -import noppes.npcs.controllers.data.CustomEffect; import noppes.npcs.controllers.data.LinkedItem; -import noppes.npcs.controllers.data.Quest; import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.input.Mouse; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageMagic.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageMagic.java index b5ccdc8e6..e1b35b31e 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageMagic.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageMagic.java @@ -26,7 +26,7 @@ public class GuiNPCManageMagic extends GuiNPCInterface2 { } @Override - protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { if (magicMap != null) { magicMap.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); } diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageQuest.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageQuest.java index c31792185..d51341fb3 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageQuest.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageQuest.java @@ -8,12 +8,10 @@ import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiEditText; import noppes.npcs.client.gui.SubGuiNpcQuest; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Quest; import noppes.npcs.controllers.data.QuestCategory; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTags.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTags.java index 1d9bc3e13..bd1d2a500 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTags.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTags.java @@ -2,15 +2,13 @@ package noppes.npcs.client.gui.global; import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.tags.TagGetPacket; -import kamkeel.npcs.network.packets.request.tags.TagsGetPacket; import kamkeel.npcs.network.packets.request.tags.TagRemovePacket; import kamkeel.npcs.network.packets.request.tags.TagSavePacket; +import kamkeel.npcs.network.packets.request.tags.TagsGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.SubGuiColorSelector; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.Tag; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTransporters.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTransporters.java index dfec90df5..198248660 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTransporters.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageTransporters.java @@ -6,7 +6,6 @@ import kamkeel.npcs.network.packets.request.transport.TransportCategoryRemovePac import kamkeel.npcs.network.packets.request.transport.TransportRemovePacket; import kamkeel.npcs.network.packets.request.transport.TransportsGetPacket; import net.minecraft.client.gui.GuiButton; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.GuiNPCTransportCategoryEdit; import noppes.npcs.client.gui.mainmenu.GuiNPCGlobalMainMenu; @@ -14,7 +13,6 @@ import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNPCStringSlot; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.IScrollData; - import noppes.npcs.entity.EntityNPCInterface; import java.util.HashMap; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManagePlayerData.java b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManagePlayerData.java index 4b505c9d3..74dd37de2 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManagePlayerData.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManagePlayerData.java @@ -1,15 +1,15 @@ package noppes.npcs.client.gui.global; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.packets.request.playerdata.PlayerDataGetPacket; +import kamkeel.npcs.network.packets.request.playerdata.PlayerDataGetNamesPacket; import kamkeel.npcs.network.packets.request.playerdata.PlayerDataMapRegenPacket; import kamkeel.npcs.network.packets.request.playerdata.PlayerDataRemovePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; - +import net.minecraft.util.StatCollector; +import noppes.npcs.client.gui.SubGuiPlayerData; import noppes.npcs.client.gui.util.*; - import noppes.npcs.constants.EnumPlayerData; import noppes.npcs.entity.EntityNPCInterface; @@ -18,167 +18,136 @@ import java.util.HashMap; import java.util.List; import java.util.Vector; -public class GuiNpcManagePlayerData extends GuiNPCInterface2 implements IScrollData,ICustomScrollListener,GuiYesNoCallback -{ - private GuiCustomScroll scroll; - private String selectedPlayer = null; - private String selected = null; - private HashMap data = new HashMap(); - private EnumPlayerData selection = EnumPlayerData.Players; - private String search = ""; +public class GuiNpcManagePlayerData extends GuiNPCInterface2 implements GuiYesNoCallback, IScrollData, ICustomScrollListener, ISubGuiListener { - public GuiNpcManagePlayerData(EntityNPCInterface npc) - { - super(npc); - PacketClient.sendClient(new PlayerDataGetPacket(selection, "")); + private GuiCustomScroll playerScroll; + private String selectedPlayer = null; + private HashMap playerData = new HashMap<>(); + private String search = ""; + + public GuiNpcManagePlayerData(EntityNPCInterface npcInterface) { + super(npcInterface); + // Request the complete list of players. + PacketClient.sendClient(new PlayerDataGetNamesPacket(EnumPlayerData.Players, "")); } - public void initGui() - { + @Override + public void initGui() { super.initGui(); - scroll = new GuiCustomScroll(this,0, 0); - scroll.setSize(303, 175); - scroll.guiLeft = guiLeft + 4; - scroll.guiTop = guiTop + 16; - addScroll(scroll); + if (playerScroll == null) { + playerScroll = new GuiCustomScroll(this, 0, 0); + } + playerScroll.guiLeft = guiLeft + 4; + playerScroll.guiTop = guiTop + 16; + playerScroll.setSize(303, 175); + addScroll(playerScroll); - addLabel(new GuiNpcLabel(0,"All Players", guiLeft + 10, guiTop + 6)); + addLabel(new GuiNpcLabel(0, StatCollector.translateToLocal("All Players"), guiLeft + 10, guiTop + 6)); - this.addButton(new GuiNpcButton(0, guiLeft + 313, guiTop + 10,98, 20, "selectWorld.deleteButton")); - this.addButton(new GuiNpcButton(1, guiLeft + 313, guiTop + 32,98, 20, "Players")); - this.addButton(new GuiNpcButton(2, guiLeft + 313, guiTop + 54,98, 20, "Quest Data")); - this.addButton(new GuiNpcButton(3, guiLeft + 313, guiTop + 76,98, 20, "Dialog Data")); - this.addButton(new GuiNpcButton(4, guiLeft + 313, guiTop + 98,98, 20, "Transport Data")); - this.addButton(new GuiNpcButton(5, guiLeft + 313, guiTop + 120,98, 20, "Bank Data")); - this.addButton(new GuiNpcButton(6, guiLeft + 313, guiTop + 142,98, 20, "Faction Data")); + addButton(new GuiNpcButton(0, guiLeft + 313, guiTop + 10, 98, 20, "gui.remove")); + addButton(new GuiNpcButton(1, guiLeft + 313, guiTop + 32, 98, 20, "gui.view")); + addButton(new GuiNpcButton(2, guiLeft + 313, guiTop + 54, 98, 20, "gui.playerMap")); - this.addButton(new GuiNpcButton(7, guiLeft + 313, guiTop + 193,98, 20, "Regen PlayerMap")); + addTextField(new GuiNpcTextField(0, this, fontRendererObj, guiLeft + 4, guiTop + 193, 303, 20, search)); - addTextField(new GuiNpcTextField(0, this, fontRendererObj, guiLeft + 4, guiTop + 193, 303, 20, search)); - getTextField(0).enabled = selection == EnumPlayerData.Players; - - initButtons(); + playerScroll.setList(getSearchList()); } - public void initButtons(){ - getButton(1).setEnabled(selection != EnumPlayerData.Players); - getButton(2).setEnabled(selection != EnumPlayerData.Quest); - getButton(3).setEnabled(selection != EnumPlayerData.Dialog); - getButton(4).setEnabled(selection != EnumPlayerData.Transport); - getButton(5).setEnabled(selection != EnumPlayerData.Bank); - getButton(6).setEnabled(selection != EnumPlayerData.Factions); - - if(selection == EnumPlayerData.Players) - getLabel(0).label = "All Players"; - else - getLabel(0).label = "Selected player: " + selectedPlayer; - } - public void drawScreen(int i, int j, float f) - { + @Override + public void drawScreen(int i, int j, float f) { super.drawScreen(i, j, f); - scroll.drawScreen(i, j, f); + playerScroll.drawScreen(i, j, f); } - public void mouseClicked(int i, int j, int k) - { - super.mouseClicked(i, j, k); - if(k == 0 && scroll != null) - scroll.mouseClicked(i, j, k); + @Override + public void mouseClicked(int i, int j, int k) {; + super.mouseClicked(i, j, k); + if (k == 0 && playerScroll != null) + playerScroll.mouseClicked(i, j, k); } - public void keyTyped(char c, int i) - { - super.keyTyped(c, i); + @Override + public void save() {} - if(search.equals(getTextField(0).getText())) - return; - search = getTextField(0).getText().toLowerCase(); - scroll.setList(getSearchList()); - } - private List getSearchList(){ - if(search.isEmpty()) - return new ArrayList(this.data.keySet()); - List list = new ArrayList(); - for(String name : data.keySet()){ - if(name.toLowerCase().contains(search)) - list.add(name); - } - return list; + @Override + public void keyTyped(char c, int i) { + super.keyTyped(c, i); + String newText = getTextField(0).getText(); + if (!search.equals(newText)) { + search = newText.toLowerCase(); + playerScroll.setList(getSearchList()); + } } - protected void actionPerformed(GuiButton guibutton) - { - int id = guibutton.id; - if(id < 7){ - GuiNpcTextField tf = getTextField(0); - if(tf != null){ - tf.setText(""); - } - search = ""; - if(id == 0) - { - if(selected != null){ - if(selection == EnumPlayerData.Players) - PacketClient.sendClient(new PlayerDataRemovePacket(selection, selectedPlayer, selected)); - else - PacketClient.sendClient(new PlayerDataRemovePacket(selection, selectedPlayer, data.get(selected))); - data.clear(); - } - selected = null; - } - if(id >= 1 && id <= 6) - { - if(selectedPlayer == null && id != 1) - return; - selection = EnumPlayerData.values()[id - 1]; - initButtons(); - scroll.clear(); - data.clear(); - - PacketClient.sendClient(new PlayerDataGetPacket(selection, selectedPlayer)); - selected = null; - } - } - if(id == 7){ - displayGuiScreen(new GuiYesNo(this, "Warning", "Do not operate on PlayerData as its regenerating", 1)); - } + private List getSearchList() { + if (search.isEmpty()) + return new ArrayList<>(playerData.keySet()); + List list = new ArrayList<>(); + for (String name : playerData.keySet()) { + if (name.toLowerCase().contains(search)) + list.add(name); + } + return list; } - @Override - public void save() { - } + @Override + public void actionPerformed(GuiButton button) { + int id = button.id; + if (id == 0) { + if (selectedPlayer != null) { + displayGuiScreen(new GuiYesNo(this, selectedPlayer, StatCollector.translateToLocal("gui.deleteconfirm"), 0)); + } + } + if (id == 1) { + if (selectedPlayer != null) { + setSubGui(new SubGuiPlayerData(selectedPlayer)); + } + } + if (id == 2) { + displayGuiScreen(new GuiYesNo(this, StatCollector.translateToLocal("gui.warning"), StatCollector.translateToLocal("gui.regenconfirm"), 1)); + } + } - @Override - public void setData(Vector list, HashMap data) { - this.data.putAll(data); + @Override + public void confirmClicked(boolean confirm, int id) { + if (confirm) { + if (id == 0) { + PacketClient.sendClient(new PlayerDataRemovePacket(EnumPlayerData.Players, selectedPlayer, null)); + playerData.remove(selectedPlayer); + selectedPlayer = null; + playerScroll.setList(getSearchList()); + } + if (id == 1) { + PacketClient.sendClient(new PlayerDataMapRegenPacket()); + close(); + } + } else { + displayGuiScreen(this); + } + } - scroll.setList(getSearchList()); + // IScrollData interface. + @Override + public void setData(Vector list, HashMap data) { + playerData.clear(); + playerData.putAll(data); + playerScroll.setList(getSearchList()); + } - if(selection == EnumPlayerData.Players && selectedPlayer != null){ - scroll.setSelected(selectedPlayer); - selected = selectedPlayer; - } - } + // ICustomScrollListener interface. + @Override + public void setSelected(String selected) { + selectedPlayer = selected; + } - @Override - public void setSelected(String selected) { - } + @Override + public void customScrollClicked(int i, int j, int k, GuiCustomScroll scroll) { + selectedPlayer = scroll.getSelected(); + } - @Override - public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) { - selected = guiCustomScroll.getSelected(); - if(selection == EnumPlayerData.Players) - selectedPlayer = selected; - } + @Override + public void customScrollDoubleClicked(String selection, GuiCustomScroll scroll) {} - @Override - public void confirmClicked(boolean confirm, int id){ - if(confirm){ - PacketClient.sendClient(new PlayerDataMapRegenPacket()); - close(); - } - else - displayGuiScreen(this); - } + public void subGuiClosed(SubGuiInterface subgui) {} } diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java index 76dd1b840..54c048512 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNpcManageRecipes.java @@ -8,14 +8,12 @@ import kamkeel.npcs.network.packets.request.recipe.RecipesGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; - import net.minecraft.util.StatCollector; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiNpcAvailability; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumGuiType; - import noppes.npcs.containers.ContainerManageRecipes; import noppes.npcs.controllers.data.RecipeAnvil; import noppes.npcs.controllers.data.RecipeCarpentry; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java b/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java index bd3b4e9e5..e73b4cdf1 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNpcNaturalSpawns.java @@ -8,13 +8,11 @@ import kamkeel.npcs.network.packets.request.naturalspawns.NaturalSpawnSavePacket import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; - import noppes.npcs.client.gui.GuiNpcMobSpawnerSelector; import noppes.npcs.client.gui.SubGuiNpcBiomes; import noppes.npcs.client.gui.SubGuiNpcDimensions; import noppes.npcs.client.gui.SubGuiSpawningOptions; import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.SpawnData; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/hud/ClientHudManager.java b/src/main/java/noppes/npcs/client/gui/hud/ClientHudManager.java new file mode 100644 index 000000000..362773b63 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/hud/ClientHudManager.java @@ -0,0 +1,36 @@ +package noppes.npcs.client.gui.hud; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ClientHudManager { + private static ClientHudManager instance; + private HashMap hudComponents = new HashMap<>(); + + private ClientHudManager() {} + + public static ClientHudManager getInstance() { + if(instance == null) + instance = new ClientHudManager(); + return instance; + } + + public void registerHud(EnumHudComponent enumHudComponent, HudComponent hud) { + hudComponents.put(enumHudComponent, hud); + } + + public HashMap getHudComponents() { + return hudComponents; + } + + /** + * Renders all enabled HUD components (normal mode). + */ + public void renderAllHUDs(float partialTicks) { + for (HudComponent hud : hudComponents.values()) { + if(hud.enabled) + hud.renderOnScreen(partialTicks); + } + } +} diff --git a/src/main/java/noppes/npcs/client/gui/hud/CompassHudComponent.java b/src/main/java/noppes/npcs/client/gui/hud/CompassHudComponent.java new file mode 100644 index 000000000..f29bd9d18 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/hud/CompassHudComponent.java @@ -0,0 +1,281 @@ +package noppes.npcs.client.gui.hud; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.config.ConfigClient; +import noppes.npcs.constants.MarkType; +import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.List; + +public class CompassHudComponent extends HudComponent { + private final Minecraft mc; + private final List markTargets = new ArrayList<>(); + private final int BAR_HEIGHT = 20; + private final int BASE_ICON_SIZE = 8; + private final int MAX_ICON_SIZE = 16; + private final int SCALE_DISTANCE_MIN = 10; + private final int SCALE_DISTANCE_MAX = 40; + private static final int HANDLE_SIZE = 10; + private static final int WIDTH_BAR_SIZE = 6; // Width adjust bar width + private final int SCAN_RANGE = 128; + + // Flag to indicate if the width bar is being dragged in editing mode. + public boolean resizingWidth = false; + + public static class MarkTargetEntry { + public int x, z; + public int type; + public int color; + + public MarkTargetEntry(int x, int z, int type, int color) { + this.x = x; + this.z = z; + this.type = type; + this.color = color; + } + } + + public CompassHudComponent(Minecraft minecraft) { + mc = minecraft; + overlayWidth = 200; + overlayHeight = BAR_HEIGHT; + load(); + } + + @Override + public void loadData(NBTTagCompound compound) { + markTargets.clear(); + NBTTagList list = compound.getTagList("MarkTargets", 10); + for(int i = 0; i < list.tagCount(); i++) { + NBTTagCompound entry = list.getCompoundTagAt(i); + markTargets.add(new MarkTargetEntry( + entry.getInteger("x"), + entry.getInteger("z"), + entry.getInteger("type"), + entry.getInteger("color") + )); + } + hasData = !markTargets.isEmpty(); + } + + @Override + public void load() { + enabled = ConfigClient.CompassEnabled; + posX = ConfigClient.CompassOverlayX; + posY = ConfigClient.CompassOverlayY; + scale = ConfigClient.CompassOverlayScale; + overlayWidth = ConfigClient.CompassOverlayWidth; + } + + @Override + public void save() { + ConfigClient.CompassEnabled = enabled; + ConfigClient.CompassEnabledProperty.set(ConfigClient.CompassEnabled); + + ConfigClient.CompassOverlayX = posX; + ConfigClient.CompassOverlayXProperty.set(ConfigClient.CompassOverlayX); + + ConfigClient.CompassOverlayY = posY; + ConfigClient.CompassOverlayYProperty.set(ConfigClient.CompassOverlayY); + + ConfigClient.CompassOverlayScale = scale; + ConfigClient.CompassOverlayScaleProperty.set(ConfigClient.CompassOverlayScale); + + ConfigClient.CompassOverlayWidth = overlayWidth; + ConfigClient.CompassOverlayWidthProperty.set(ConfigClient.CompassOverlayWidth); + + if(ConfigClient.config.hasChanged()) + ConfigClient.config.save(); + } + + @Override + public void renderOnScreen(float partialTicks) { + // If no mark data or in edit mode, skip normal rendering. + if (!hasData || isEditting) return; + + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int actualX = (int)(posX / 100F * res.getScaledWidth()); + int actualY = (int)(posY / 100F * res.getScaledHeight()); + float effectiveScale = getEffectiveScale(res); + + GL11.glPushMatrix(); + GL11.glTranslatef(actualX, actualY, 0); + GL11.glScalef(effectiveScale, effectiveScale, effectiveScale); + + // Draw background bar + drawRect(0, 0, overlayWidth, BAR_HEIGHT, 0x80000000); + + // Render all marks + for(MarkTargetEntry mark : markTargets) { + renderMarkIcon(mark); + } + + GL11.glPopMatrix(); + } + + private void renderMarkIcon(MarkTargetEntry mark) { + if (mc.thePlayer == null) return; + + Float iconPos = calculateIconPosition(mark.x, mark.z); + if(iconPos == null) { + // Target is behind the player; don't render. + return; + } + + int barWidth = overlayWidth; + float distance = (float) Math.sqrt( + Math.pow(mark.x - mc.thePlayer.posX, 2) + + Math.pow(mark.z - mc.thePlayer.posZ, 2) + ); + + int iconSize = calculateIconSize(distance); + int iconX = MathHelper.clamp_int((int)iconPos.floatValue(), iconSize/2, barWidth - iconSize/2); + int iconY = (BAR_HEIGHT - iconSize)/2; + + ResourceLocation texture = getTextureForMark(mark.type); + if(texture != null) { + renderTextureIcon(iconX - iconSize/2, iconY, iconSize, texture, mark.color); + } + } + + private ResourceLocation getTextureForMark(int type) { + switch(type) { + case MarkType.EXCLAMATION: return new ResourceLocation("customnpcs", "textures/marks/exclamation.png"); + case MarkType.QUESTION: return new ResourceLocation("customnpcs", "textures/marks/question.png"); + case MarkType.POINTER: return new ResourceLocation("customnpcs", "textures/marks/pointer.png"); + case MarkType.CROSS: return new ResourceLocation("customnpcs", "textures/marks/cross.png"); + case MarkType.SKULL: return new ResourceLocation("customnpcs", "textures/marks/skull.png"); + case MarkType.STAR: return new ResourceLocation("customnpcs", "textures/marks/star.png"); + default: return null; + } + } + + private void renderTextureIcon(int x, int y, int size, ResourceLocation texture, int color) { + float red = (color >> 16 & 255) / 255.0F; + float green = (color >> 8 & 255) / 255.0F; + float blue = (color & 255) / 255.0F; + + GL11.glPushMatrix(); + GL11.glColor4f(red, green, blue, 1); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + mc.getTextureManager().bindTexture(texture); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(x, y + size, 0, 0, 1); + tessellator.addVertexWithUV(x + size, y + size, 0, 1, 1); + tessellator.addVertexWithUV(x + size, y, 0, 1, 0); + tessellator.addVertexWithUV(x, y, 0, 0, 0); + tessellator.draw(); + + GL11.glColor4f(1, 1, 1, 1); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + } + + private Float calculateIconPosition(double targetX, double targetZ) { + double dx = targetX - mc.thePlayer.posX; + double dz = targetZ - mc.thePlayer.posZ; + double angleToTarget = Math.toDegrees(Math.atan2(dz, dx)); + double adjustedPlayerYaw = mc.thePlayer.rotationYaw + 90; + double relativeAngle = angleToTarget - adjustedPlayerYaw; + while(relativeAngle < -180) relativeAngle += 360; + while(relativeAngle > 180) relativeAngle -= 360; + + // Only render if the target is within 90° to either side (180° front) + if (Math.abs(relativeAngle) > 90) { + return null; + } + + // Map -90..90 to 0..overlayWidth so that 0 becomes the left edge and 90 the right edge. + return (float)(overlayWidth / 2.0 + (relativeAngle / 90.0) * (overlayWidth / 2.0)); + } + + private int calculateIconSize(float distance) { + if(distance <= SCALE_DISTANCE_MIN) return MAX_ICON_SIZE; + if(distance >= SCALE_DISTANCE_MAX) return BASE_ICON_SIZE; + + float t = (distance - SCALE_DISTANCE_MIN) / + (SCALE_DISTANCE_MAX - SCALE_DISTANCE_MIN); + return (int)(MAX_ICON_SIZE - (MAX_ICON_SIZE - BASE_ICON_SIZE) * t); + } + + @Override + public void renderEditing() { + isEditting = true; + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int actualX = (int)(posX / 100F * res.getScaledWidth()); + int actualY = (int)(posY / 100F * res.getScaledHeight()); + float effectiveScale = getEffectiveScale(res); + + GL11.glPushMatrix(); + GL11.glTranslatef(actualX, actualY, 0); + GL11.glScalef(effectiveScale, effectiveScale, effectiveScale); + + // Draw background bar and border. + drawRect(0, 0, overlayWidth, overlayHeight, 0x80000000); + drawRectOutline(0, 0, overlayWidth, overlayHeight, 0xFF00FF00); + // Resize handle (bottom-right for scale) + drawRect(overlayWidth - HANDLE_SIZE, overlayHeight - HANDLE_SIZE, + overlayWidth, overlayHeight, 0xFFCCCCCC); + // Width adjust bar on right side (centered vertically) + int margin = 5; + int barX = overlayWidth + margin; + int barY = (overlayHeight - BAR_HEIGHT) / 2; + drawRect(barX, barY, barX + WIDTH_BAR_SIZE, barY + BAR_HEIGHT, 0xFF888888); + + // Demo marks for preview. + renderDemoIcon(overlayWidth * 0.25f, MarkType.EXCLAMATION, 0xFF00FF00); + renderDemoIcon(overlayWidth * 0.75f, MarkType.QUESTION, 0xFFFF0000); + + GL11.glPopMatrix(); + } + + private void renderDemoIcon(float position, int type, int color) { + float pulse = (System.currentTimeMillis() % 1000) / 1000f; + int size = (int)(BASE_ICON_SIZE + (MAX_ICON_SIZE - BASE_ICON_SIZE) * pulse); + ResourceLocation texture = getTextureForMark(type); + + if(texture != null) { + GL11.glPushMatrix(); + GL11.glTranslatef(position - size/2, (BAR_HEIGHT - size)/2, 0); + renderTextureIcon(0, 0, size, texture, color); + GL11.glPopMatrix(); + } + } + + /** + * Updates the mark targets directly. + * (This method assumes external code (CNPC+ mark data) supplies the new marks + * without having to loop through all loaded entities.) + */ + public void updateMarkTargets(List newMarks) { + markTargets.clear(); + markTargets.addAll(newMarks); + hasData = !markTargets.isEmpty(); + } + + // Helper drawing methods + private void drawRect(int left, int top, int right, int bottom, int color) { + net.minecraft.client.gui.Gui.drawRect(left, top, right, bottom, color); + } + + private void drawRectOutline(int left, int top, int right, int bottom, int color) { + drawHorizontalLine(left, right, top, color); + drawHorizontalLine(left, right, bottom - 1, color); + net.minecraft.client.gui.Gui.drawRect(left, top, left + 1, bottom, color); + net.minecraft.client.gui.Gui.drawRect(right - 1, top, right, bottom, color); + } + + private void drawHorizontalLine(int left, int right, int y, int color) { + net.minecraft.client.gui.Gui.drawRect(left, y, right, y + 1, color); + } +} diff --git a/src/main/java/noppes/npcs/client/gui/hud/EnumHudComponent.java b/src/main/java/noppes/npcs/client/gui/hud/EnumHudComponent.java new file mode 100644 index 000000000..fe6eb07b6 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/hud/EnumHudComponent.java @@ -0,0 +1,6 @@ +package noppes.npcs.client.gui.hud; + +public enum EnumHudComponent { + QuestTracker, + QuestCompass +} diff --git a/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java b/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java new file mode 100644 index 000000000..35c2899c0 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java @@ -0,0 +1,248 @@ +package noppes.npcs.client.gui.hud; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import java.util.List; +import java.util.ArrayList; + +public class GuiHudEditor extends GuiScreen { + private GuiScreen parent; + // Currently selected HUD component for moving/resizing. + private HudComponent selectedComponent; + private int dragOffsetX, dragOffsetY; + private boolean dragging = false; + private boolean resizing = false; + // For general scaling resize. + private int initialScale, initialMouseX, initialMouseY; + // For Compass width adjustment. + private boolean resizingWidth = false; + private int initialOverlayWidth, initialWidthMouseX; + + private final int HANDLE_SIZE = 10; + private final int RESET_POSITION_ID = 100; + + public GuiHudEditor(GuiScreen parent) { + this.parent = parent; + // For example, default to QuestTracker if available. + selectedComponent = ClientHudManager.getInstance().getHudComponents().get(EnumHudComponent.QuestTracker); + } + + @Override + public void initGui() { + buttonList.clear(); + // Global "Save and Close" button always visible. + buttonList.add(new GuiButton(0, width / 2 - 60, height - 45, 120, 20, "Save and Close")); + updateCustomButtons(); + } + + /** + * Updates the custom buttons shown on screen. + * Removes all buttons except the global Save button (id 0) + * then adds the selected component's custom buttons plus a Reset Position button. + * Buttons are now arranged in two columns. + */ + private void updateCustomButtons() { + // Remove any buttons that are not the global Save (id 0) + for (int i = buttonList.size() - 1; i >= 0; i--) { + GuiButton btn = (GuiButton) buttonList.get(i); + if (btn.id != 0) { + buttonList.remove(i); + } + } + if (selectedComponent != null) { + List customButtons = new ArrayList<>(); + selectedComponent.addEditorButtons(customButtons); + // Arrange buttons in 2 columns. + int spacingX = 10; + int spacingY = 5; + int buttonWidth = 120; // assuming uniform width + int startXLeft = width / 2 - buttonWidth - spacingX/2; + int startXRight = width / 2 + spacingX/2; + int rowHeight = 0; + int numButtons = customButtons.size(); + for (int i = 0; i < numButtons; i += 2) { + // If two buttons in this row. + if (i + 1 < numButtons) { + GuiButton btnLeft = customButtons.get(i); + GuiButton btnRight = customButtons.get(i+1); + btnLeft.xPosition = startXLeft; + btnRight.xPosition = startXRight; + // Determine row y based on button height. + int rowY = height - 70 - rowHeight; + btnLeft.yPosition = rowY; + btnRight.yPosition = rowY; + rowHeight += btnLeft.height + spacingY; + buttonList.add(btnLeft); + buttonList.add(btnRight); + } else { + // One button: center it. + GuiButton btn = customButtons.get(i); + btn.xPosition = width / 2 - buttonWidth / 2; + btn.yPosition = height - 70 - rowHeight; + buttonList.add(btn); + rowHeight += btn.height + spacingY; + } + } + // Always add the Reset Position button below the custom buttons. + GuiButton resetPos = new GuiButton(RESET_POSITION_ID, width / 2 - buttonWidth / 2, height - 70 - rowHeight, buttonWidth, 20, "Reset Position"); + buttonList.add(resetPos); + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + // Render each HUD in editing mode. + for (HudComponent hud : ClientHudManager.getInstance().getHudComponents().values()) { + hud.renderEditing(); + } + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { + // Iterate over HUD components to check for selection. + // First, check for Compass width adjust hitbox if the mouse is near a CompassHudComponent. + for (HudComponent hud : ClientHudManager.getInstance().getHudComponents().values()) { + if (!(hud instanceof CompassHudComponent)) + continue; + + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + float effectiveScale = hud.getEffectiveScale(res); + int actualX = (int)(hud.posX / 100F * res.getScaledWidth()); + int actualY = (int)(hud.posY / 100F * res.getScaledHeight()); + + // Even if the mouse is outside the hud bounds, we want to check for the floating adjust bar. + int margin = 5; + int barWidth = 6; // same as WIDTH_BAR_SIZE + // The adjust bar is drawn to the right of the component. + int barX = actualX + (int)(hud.overlayWidth * effectiveScale) + margin; + int barY = actualY + (int)(((hud.overlayHeight - 20) / 2.0F) * effectiveScale); // 20 = BAR_HEIGHT + int barHeight = (int)(20 * effectiveScale); + if (mouseX >= barX && mouseX <= barX + barWidth && + mouseY >= barY && mouseY <= barY + barHeight) { + resizingWidth = true; + selectedComponent = hud; + initialOverlayWidth = hud.overlayWidth; + initialWidthMouseX = mouseX; + updateCustomButtons(); + return; + } + } + + // Next, proceed with the normal hit detection for dragging/resizing of the HUD components. + for (HudComponent hud : ClientHudManager.getInstance().getHudComponents().values()) { + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + float effectiveScale = hud.getEffectiveScale(res); + int actualX = (int)(hud.posX / 100F * res.getScaledWidth()); + int actualY = (int)(hud.posY / 100F * res.getScaledHeight()); + int absWidth = (int)(hud.overlayWidth * effectiveScale); + int absHeight = (int)(hud.overlayHeight * effectiveScale); + if (mouseX >= actualX && mouseX <= actualX + absWidth && + mouseY >= actualY && mouseY <= actualY + absHeight) { + // Check if clicking on the resize handle (bottom-right). + if (mouseX >= actualX + absWidth - HANDLE_SIZE && mouseY >= actualY + absHeight - HANDLE_SIZE) { + resizing = true; + selectedComponent = hud; + initialScale = hud.scale; + initialMouseX = mouseX; + initialMouseY = mouseY; + updateCustomButtons(); + return; + } else { + dragging = true; + selectedComponent = hud; + dragOffsetX = mouseX - actualX; + dragOffsetY = mouseY - actualY; + updateCustomButtons(); + return; + } + } + } + super.mouseClicked(mouseX, mouseY, mouseButton); + } + + @Override + protected void mouseMovedOrUp(int mouseX, int mouseY, int state) { + dragging = false; + resizing = false; + resizingWidth = false; + super.mouseMovedOrUp(mouseX, mouseY, state); + } + + @Override + public void updateScreen() { + if (selectedComponent != null) { + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int scaledWidth = res.getScaledWidth(); + int scaledHeight = res.getScaledHeight(); + float effectiveScale = selectedComponent.getEffectiveScale(res); + if (dragging) { + int newX = Mouse.getX() * width / mc.displayWidth - dragOffsetX; + int newY = scaledHeight - (Mouse.getY() * scaledHeight / mc.displayHeight) - dragOffsetY; + if (newX < 0) newX = 0; + if (newY < 0) newY = 0; + if (newX + (int)(selectedComponent.overlayWidth * effectiveScale) > scaledWidth) + newX = scaledWidth - (int)(selectedComponent.overlayWidth * effectiveScale); + if (newY + (int)(selectedComponent.overlayHeight * effectiveScale) > scaledHeight) + newY = scaledHeight - (int)(selectedComponent.overlayHeight * effectiveScale); + selectedComponent.posX = (int)(100F * newX / scaledWidth); + selectedComponent.posY = (int)(100F * newY / scaledHeight); + } + if (resizing) { + int currentMouseX = Mouse.getX() * width / mc.displayWidth; + int deltaX = currentMouseX - initialMouseX; + selectedComponent.scale = initialScale + deltaX; // 1 pixel = 1% change. + if (selectedComponent.scale < 50) selectedComponent.scale = 50; + if (selectedComponent.scale > 300) selectedComponent.scale = 300; + } + if (resizingWidth && (selectedComponent instanceof CompassHudComponent)) { + int currentMouseX = Mouse.getX() * width / mc.displayWidth; + int delta = currentMouseX - initialWidthMouseX; + selectedComponent.overlayWidth = initialOverlayWidth + delta; + if (selectedComponent.overlayWidth < 50) selectedComponent.overlayWidth = 50; + if (selectedComponent.overlayWidth > 500) selectedComponent.overlayWidth = 500; + } + } + super.updateScreen(); + } + + @Override + protected void actionPerformed(GuiButton button) { + if (button.id == 0) { + close(); + } else if (button.id == RESET_POSITION_ID) { + // Reset position for selected HUD. + if (selectedComponent != null) { + selectedComponent.posX = 50; + selectedComponent.posY = 50; + updateCustomButtons(); + } + } else { + // Dispatch other button actions to the selected component. + if (selectedComponent != null) { + selectedComponent.onEditorButtonPressed(button); + updateCustomButtons(); + } + } + } + + @Override + protected void keyTyped(char typedChar, int keyCode) { + if (keyCode == 1) { + close(); + } + } + + public void close() { + for (HudComponent hud : ClientHudManager.getInstance().getHudComponents().values()) { + hud.isEditting = false; + hud.save(); + } + mc.displayGuiScreen(parent); + } +} diff --git a/src/main/java/noppes/npcs/client/gui/hud/HudComponent.java b/src/main/java/noppes/npcs/client/gui/hud/HudComponent.java new file mode 100644 index 000000000..48bfece66 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/hud/HudComponent.java @@ -0,0 +1,70 @@ +package noppes.npcs.client.gui.hud; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.nbt.NBTTagCompound; +import java.util.List; + +public abstract class HudComponent { + // Stored as percentages (0-100) of the current screen resolution. + protected int posX = 50, posY = 50, scale = 100, textAlign = 0; + + public boolean enabled = true; + public boolean hasData = false; + public boolean isEditting = false; + public int overlayWidth = 200, overlayHeight = 120; + + /** + * Loads custom HUD data from an NBT compound. + */ + public abstract void loadData(NBTTagCompound compound); + + /** + * Loads HUD settings from the config. + */ + public abstract void load(); + + /** + * Saves HUD settings to the config. + */ + public abstract void save(); + + /** + * Renders the HUD as it appears during normal gameplay. + */ + public abstract void renderOnScreen(float partialTicks); + + /** + * Renders the HUD in edit mode (with handles, borders, dummy data, etc.). + */ + public abstract void renderEditing(); + + /** + * Allows the component to add its own editor buttons. + * The default implementation adds a toggle button for enabling/disabling the component. + */ + public void addEditorButtons(List buttonList) { + // Toggle enabled/disabled button (id 999 reserved for toggle) + String label = enabled ? "Enabled" : "Disabled"; + buttonList.add(new GuiButton(999, 0, 0, 120, 20, label)); + } + + /** + * Handles editor button actions specific to this HUD component. + * The default implementation toggles the enabled state if button id is 999. + */ + public void onEditorButtonPressed(GuiButton button) { + if(button.id == 999){ + enabled = !enabled; + button.displayString = enabled ? "Enabled" : "Disabled"; + } + } + + /** + * Computes the effective scale factor for rendering and hitbox calculations. + * Uses the current resolution (with 1920 as the base width). + */ + public float getEffectiveScale(ScaledResolution res) { + return (scale / 100.0F) * (res.getScaledWidth() / 1920.0F); + } +} diff --git a/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java b/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java new file mode 100644 index 000000000..a3477a6cf --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java @@ -0,0 +1,280 @@ +package noppes.npcs.client.gui.hud; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.GuiButton; +import noppes.npcs.config.ConfigClient; +import org.lwjgl.opengl.GL11; +import noppes.npcs.controllers.data.Quest; +import java.util.ArrayList; +import java.util.List; + +public class QuestTrackingComponent extends HudComponent { + private Minecraft mc; + private ArrayList questTitleLines = new ArrayList<>(); + private ArrayList questCategoryLines = new ArrayList<>(); + private ArrayList objectiveLines = new ArrayList<>(); + private ArrayList turnInLines = new ArrayList<>(); + + public QuestTrackingComponent(Minecraft mc) { + this.mc = mc; + load(); + } + + /** + * Sets quest data similar to the original OverlayQuestTracking. + */ + public void setQuestData(Quest quest, String category, List objectives, String turnIn) { + questTitleLines = splitLines(convertColorCodes(quest.getName()), overlayWidth - 10); + questCategoryLines = splitLines(convertColorCodes(category), overlayWidth - 10); + objectiveLines.clear(); + for (String obj : objectives) { + objectiveLines.add(convertColorCodes(obj)); + } + turnInLines.clear(); + if (turnIn != null && !turnIn.isEmpty()) { + turnInLines.add(convertColorCodes(turnIn)); + } + } + + /** + * Loads overlay data from an NBT compound. + */ + public void setOverlayData(NBTTagCompound compound) { + Quest quest = new Quest(); + quest.readNBT(compound.getCompoundTag("Quest")); + String category = compound.getString("CategoryName"); + + ArrayList objectives = new ArrayList<>(); + NBTTagList objectiveList = compound.getTagList("ObjectiveList", 8); + for (int i = 0; i < objectiveList.tagCount(); i++) { + String objective = objectiveList.getStringTagAt(i); + objectives.add(objective); + } + String turnIn = ""; + boolean instantComplete = compound.getBoolean("Instant"); + if (instantComplete) { + turnIn = "Completed automatically"; + } else { + String npcName = compound.getString("TurnInNPC"); + if (!npcName.isEmpty()) { + turnIn = "Complete with " + npcName; + } + } + setQuestData(quest, category, objectives, turnIn); + hasData = true; + } + + @Override + public void loadData(NBTTagCompound compound) { + setOverlayData(compound); + } + + @Override + public void load() { + posX = ConfigClient.QuestOverlayX; + posY = ConfigClient.QuestOverlayY; + scale = ConfigClient.QuestOverlayScale; + textAlign = ConfigClient.QuestOverlayTextAlign; + } + + @Override + public void save() { + ConfigClient.QuestOverlayX = posX; + ConfigClient.QuestOverlayXProperty.set(ConfigClient.QuestOverlayX); + + ConfigClient.QuestOverlayY = posY; + ConfigClient.QuestOverlayYProperty.set(ConfigClient.QuestOverlayY); + + ConfigClient.QuestOverlayScale = scale; + ConfigClient.QuestOverlayScaleProperty.set(ConfigClient.QuestOverlayScale); + + ConfigClient.QuestOverlayTextAlign = textAlign; + ConfigClient.QuestOverlayTextAlignProperty.set(ConfigClient.QuestOverlayTextAlign); + + if (ConfigClient.config.hasChanged()) { + ConfigClient.config.save(); + } + } + + @Override + public void renderOnScreen(float partialTicks) { + if (!hasData || isEditting) + return; + + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int actualX = (int)(posX / 100F * res.getScaledWidth()); + int actualY = (int)(posY / 100F * res.getScaledHeight()); + float effectiveScale = getEffectiveScale(res); + + GL11.glPushMatrix(); + GL11.glTranslatef(actualX, actualY, 0); + GL11.glScalef(effectiveScale, effectiveScale, effectiveScale); + + // Draw background (semi-transparent). + drawRect(0, 0, overlayWidth, overlayHeight, 0x40000000); + + int currentY = 5; + currentY = renderTextBlock(questTitleLines, currentY, textAlign, 0xFFFFFF); + drawDecorativeLine(currentY - 1); + currentY += 8; + + currentY = renderTextBlock(questCategoryLines, currentY, textAlign, 0xCCCCCC); + drawDecorativeLine(currentY - 1); + currentY += 8; + + currentY = renderTextBlock(objectiveLines, currentY, textAlign, 0xAAAAAA); + if (!turnInLines.isEmpty()) { + drawDecorativeLine(currentY - 1); + currentY += 8; + } + renderTextBlock(turnInLines, currentY, textAlign, 0xAAAAAA); + + GL11.glPopMatrix(); + } + + @Override + public void renderEditing() { + isEditting = true; + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int actualX = (int)(posX / 100F * res.getScaledWidth()); + int actualY = (int)(posY / 100F * res.getScaledHeight()); + float effectiveScale = getEffectiveScale(res); + + GL11.glPushMatrix(); + GL11.glTranslatef(actualX, actualY, 0); + GL11.glScalef(effectiveScale, effectiveScale, effectiveScale); + + // Draw editing background, border, and resize handle. + drawRect(0, 0, overlayWidth, overlayHeight, 0x40FFFFFF); + drawRectOutline(0, 0, overlayWidth, overlayHeight, 0xFFAAAAAA); + drawRect(overlayWidth - 10, overlayHeight - 10, overlayWidth, overlayHeight, 0xFFCCCCCC); + + int currentY = 5; + currentY = renderDemoTextBlock(new String[] { "Dummy Quest Title" }, currentY, textAlign, 0xFFFFFF); + drawDecorativeLine(currentY - 1); + currentY += 8; + currentY = renderDemoTextBlock(new String[] { "Dummy Category" }, currentY, textAlign, 0xCCCCCC); + drawDecorativeLine(currentY - 1); + currentY += 8; + currentY = renderDemoTextBlock(new String[] { "Objective: Kill 10 mobs", "Objective: Collect 5 items" }, currentY, textAlign, 0xAAAAAA); + drawDecorativeLine(currentY - 1); + currentY += 8; + renderDemoTextBlock(new String[] { "Turn in with NPC" }, currentY, textAlign, 0xAAAAAA); + + GL11.glPopMatrix(); + } + + @Override + public void addEditorButtons(List buttonList) { + // First add the default toggle button. + super.addEditorButtons(buttonList); + // Then add other custom buttons. + buttonList.add(new GuiButton(1, 100, 0, 120, 20, getAlignText())); + buttonList.add(new GuiButton(3, 100, 0, 120, 20, "Reset to Center")); + } + + @Override + public void onEditorButtonPressed(GuiButton button) { + if (button.id == 1) { // Cycle alignment. + textAlign = (textAlign + 1) % 3; + button.displayString = getAlignText(); + } else if (button.id == 3) { // Reset to center. + posX = 50; + posY = 50; + } else { + super.onEditorButtonPressed(button); + } + } + + private String getAlignText() { + switch (textAlign) { + case 0: return "Align: Left"; + case 1: return "Align: Center"; + case 2: return "Align: Right"; + default: return "Align: Unknown"; + } + } + + // ---------- Helper rendering methods ----------- + private int renderTextBlock(List lines, int startY, int align, int color) { + int y = startY; + FontRenderer font = mc.fontRenderer; + for (String line : lines) { + int strWidth = font.getStringWidth(line); + int xOffset = (align == 1) ? (overlayWidth - strWidth) / 2 + : (align == 2) ? overlayWidth - strWidth - 5 : 5; + font.drawStringWithShadow(line, xOffset, y, color); + y += font.FONT_HEIGHT + 4; + } + return y; + } + + private int renderDemoTextBlock(String[] lines, int startY, int align, int color) { + int y = startY; + FontRenderer font = mc.fontRenderer; + for (String line : lines) { + int strWidth = font.getStringWidth(line); + int xOffset = (align == 1) ? (overlayWidth - strWidth) / 2 + : (align == 2) ? overlayWidth - strWidth - 5 : 5; + font.drawStringWithShadow(line, xOffset, y, color); + y += font.FONT_HEIGHT + 4; + } + return y; + } + + private void drawDecorativeLine(int y) { + drawHorizontalLine(5, overlayWidth - 5, y, 0xFF777777); + drawHorizontalLine(5, overlayWidth - 5, y + 1, 0xFFA8A8A8); + drawHorizontalLine(5, overlayWidth - 5, y + 2, 0xFFFFFFFF); + } + + // Simple wrappers for drawing. + private void drawRect(int left, int top, int right, int bottom, int color) { + net.minecraft.client.gui.Gui.drawRect(left, top, right, bottom, color); + } + + private void drawHorizontalLine(int left, int right, int y, int color) { + net.minecraft.client.gui.Gui.drawRect(left, y, right, y + 1, color); + } + + private void drawRectOutline(int left, int top, int right, int bottom, int color) { + drawHorizontalLine(left, right, top, color); + drawHorizontalLine(left, right, bottom - 1, color); + net.minecraft.client.gui.Gui.drawRect(left, top, left + 1, bottom, color); + net.minecraft.client.gui.Gui.drawRect(right - 1, top, right, bottom, color); + } + + private String convertColorCodes(String text) { + return text.replaceAll("&([0-9a-fk-or])", "§$1"); + } + + private ArrayList splitLines(String text, int maxWidth) { + ArrayList lines = new ArrayList<>(); + String[] words = text.split(" "); + StringBuilder current = new StringBuilder(); + FontRenderer font = mc.fontRenderer; + for (String word : words) { + String test = current.length() == 0 ? word : current.toString() + " " + word; + if (font.getStringWidth(test) > maxWidth) { + if (current.length() > 0) { + lines.add(current.toString()); + current = new StringBuilder(word); + } else { + lines.add(word); + } + } else { + if (current.length() > 0) + current.append(" ").append(word); + else + current.append(word); + } + } + if (current.length() > 0) + lines.add(current.toString()); + return lines; + } +} diff --git a/src/main/java/noppes/npcs/client/gui/item/SubGuiLinkedItem.java b/src/main/java/noppes/npcs/client/gui/item/SubGuiLinkedItem.java index 77a2d35ee..92d4df551 100644 --- a/src/main/java/noppes/npcs/client/gui/item/SubGuiLinkedItem.java +++ b/src/main/java/noppes/npcs/client/gui/item/SubGuiLinkedItem.java @@ -2,25 +2,20 @@ package noppes.npcs.client.gui.item; import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.linked.LinkedItemSavePacket; -import kamkeel.npcs.network.packets.request.linked.LinkedNPCAddPacket; import kamkeel.npcs.util.ColorUtil; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.StatCollector; import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.client.CustomNpcResourceListener; -import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.SubGuiColorSelector; -import noppes.npcs.client.gui.SubGuiEditText; import noppes.npcs.client.gui.global.GuiNPCManageLinked; import noppes.npcs.client.gui.script.GuiScriptLinkedItem; import noppes.npcs.client.gui.util.*; import noppes.npcs.client.renderer.ImageData; import noppes.npcs.controllers.data.LinkedItem; -import noppes.npcs.util.ValueUtil; import org.lwjgl.opengl.GL11; public class SubGuiLinkedItem extends SubGuiInterface implements ITextfieldListener, GuiYesNoCallback, ISubGuiListener { diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java index a70e427da..a4b38906e 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java @@ -11,12 +11,7 @@ import noppes.npcs.client.gui.util.GuiNpcSquareButton; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.entity.EntityNPCInterface; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.HashMap; +import java.util.*; import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons; @@ -88,7 +83,7 @@ public class GuiNPCGlobalMainMenu extends GuiNPCInterface2 { tagButton.setIconPos(24, 24, 192, 32).setIconTexture(specialIcons); registerButton(effectsButton = new GuiNpcSquareButton(19, 0, 0, 20, "global.customeffects", 0xFF333333)); - effectsButton.setIconPos(24, 24, 192, 32).setIconTexture(specialIcons); + effectsButton.setIconPos(24, 24, 24, 56).setIconTexture(specialIcons); // Layout composite buttons optimally. layoutButtons(); diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCInv.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCInv.java index d4b033b4d..2d18c8769 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCInv.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCInv.java @@ -10,9 +10,7 @@ import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.inventory.Slot; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.containers.ContainerNPCInv; import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java index dafe8f50d..683898be0 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAI.java @@ -6,12 +6,10 @@ import kamkeel.npcs.network.packets.request.mainmenu.MainmenuAISavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.DataAI; - import noppes.npcs.client.gui.SubGuiNpcMovement; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumCombatPolicy; import noppes.npcs.constants.EnumNavType; - import noppes.npcs.entity.EntityNPCInterface; public class GuiNpcAI extends GuiNPCInterface2 implements ITextfieldListener, IGuiData{ diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAdvanced.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAdvanced.java index 4a4eae046..fb722e1ce 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAdvanced.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcAdvanced.java @@ -8,7 +8,6 @@ import kamkeel.npcs.network.packets.request.role.RoleGetPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.NoppesStringUtils; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.advanced.*; import noppes.npcs.client.gui.roles.*; @@ -17,7 +16,6 @@ import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.IGuiData; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.constants.EnumJobType; - import noppes.npcs.constants.EnumRoleType; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java index b035b84be..41394770c 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java @@ -9,14 +9,12 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import noppes.npcs.DataDisplay; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.*; import noppes.npcs.client.gui.model.GuiCreationScreen; import noppes.npcs.client.gui.select.GuiTextureSelection; import noppes.npcs.client.gui.util.*; import noppes.npcs.config.ConfigMain; - import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java index 8fc1d567c..7dc198388 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcStats.java @@ -8,10 +8,8 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.DataStats; - import noppes.npcs.client.gui.*; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; public class GuiNpcStats extends GuiNPCInterface2 implements ITextfieldListener, IGuiData{ diff --git a/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java b/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java index 590b8d4ea..68aff497e 100644 --- a/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java +++ b/src/main/java/noppes/npcs/client/gui/model/GuiCreationScreen.java @@ -16,10 +16,8 @@ import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagByte; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; - import noppes.npcs.client.gui.util.*; import noppes.npcs.compat.PixelmonHelper; - import noppes.npcs.entity.*; import java.lang.reflect.Method; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiAnvilRecipes.java b/src/main/java/noppes/npcs/client/gui/player/GuiAnvilRecipes.java index cac06388a..c1c78865a 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiAnvilRecipes.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiAnvilRecipes.java @@ -2,25 +2,24 @@ package noppes.npcs.client.gui.player; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.minecraft.util.StatCollector; -import noppes.npcs.client.CustomNpcResourceListener; -import noppes.npcs.client.gui.util.*; -import noppes.npcs.controllers.RecipeController; -import noppes.npcs.controllers.data.RecipeAnvil; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.item.ItemStack; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; -import noppes.npcs.util.ValueUtil; +import net.minecraft.util.StatCollector; +import noppes.npcs.client.CustomNpcResourceListener; +import noppes.npcs.client.gui.util.*; +import noppes.npcs.controllers.RecipeController; +import noppes.npcs.controllers.data.RecipeAnvil; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + @SideOnly(Side.CLIENT) public class GuiAnvilRecipes extends GuiNPCInterface { diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiBigSign.java b/src/main/java/noppes/npcs/client/gui/player/GuiBigSign.java index f9773d335..fb4554bed 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiBigSign.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiBigSign.java @@ -2,10 +2,8 @@ package noppes.npcs.client.gui.player; import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.player.SaveSignPacket; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.blocks.tiles.TileBigSign; import noppes.npcs.client.gui.SubGuiNpcTextArea; -import noppes.npcs.constants.EnumPlayerPacket; public class GuiBigSign extends SubGuiNpcTextArea{ public TileBigSign tile; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiBook.java b/src/main/java/noppes/npcs/client/gui/player/GuiBook.java index bc609440e..730427a24 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiBook.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiBook.java @@ -17,8 +17,6 @@ import net.minecraft.nbt.NBTTagString; import net.minecraft.util.ChatAllowedCharacters; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; -import noppes.npcs.NoppesUtilPlayer; -import noppes.npcs.constants.EnumPlayerPacket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiMailbox.java b/src/main/java/noppes/npcs/client/gui/player/GuiMailbox.java index 70e2130f9..360d69c0c 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiMailbox.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiMailbox.java @@ -6,10 +6,8 @@ import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.controllers.data.PlayerMail; import noppes.npcs.controllers.data.PlayerMailData; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiMailmanWrite.java b/src/main/java/noppes/npcs/client/gui/player/GuiMailmanWrite.java index 32efa064c..3f2bf588b 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiMailmanWrite.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiMailmanWrite.java @@ -13,10 +13,8 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; import net.minecraft.util.*; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.util.*; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.containers.ContainerMail; import noppes.npcs.controllers.data.PlayerMail; import org.lwjgl.input.Keyboard; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollower.java b/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollower.java index 815ae9c9a..05d162aa0 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollower.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollower.java @@ -9,12 +9,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.GuiContainerNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.IGuiData; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.containers.ContainerNPCFollower; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleFollower; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollowerHire.java b/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollowerHire.java index 5dfc6008b..261e2d9bb 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollowerHire.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiNpcFollowerHire.java @@ -7,11 +7,9 @@ import net.minecraft.client.renderer.RenderHelper; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.GuiContainerNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.containers.ContainerNPCFollowerHire; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleFollower; diff --git a/src/main/java/noppes/npcs/client/gui/player/GuiTransportSelection.java b/src/main/java/noppes/npcs/client/gui/player/GuiTransportSelection.java index 601f01df5..df217675a 100644 --- a/src/main/java/noppes/npcs/client/gui/player/GuiTransportSelection.java +++ b/src/main/java/noppes/npcs/client/gui/player/GuiTransportSelection.java @@ -5,9 +5,7 @@ import kamkeel.npcs.network.packets.player.TransportPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.gui.util.*; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionStats.java b/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionStats.java index c95927985..11215c505 100644 --- a/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionStats.java +++ b/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionStats.java @@ -11,12 +11,10 @@ import net.minecraft.util.MathHelper; import noppes.npcs.CustomItems; import noppes.npcs.CustomNpcs; import noppes.npcs.NoppesStringUtils; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumCompanionJobs; import noppes.npcs.constants.EnumCompanionTalent; import noppes.npcs.constants.EnumGuiType; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleCompanion; diff --git a/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionTalents.java b/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionTalents.java index f9e1c8a9d..9478240f2 100644 --- a/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionTalents.java +++ b/src/main/java/noppes/npcs/client/gui/player/companion/GuiNpcCompanionTalents.java @@ -11,14 +11,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import noppes.npcs.CustomNpcs; import noppes.npcs.NoppesStringUtils; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.constants.EnumCompanionTalent; import noppes.npcs.constants.EnumGuiType; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleCompanion; import org.lwjgl.input.Mouse; diff --git a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiCNPCInventory.java b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiCNPCInventory.java index 3ab43c14e..4783e7cff 100644 --- a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiCNPCInventory.java +++ b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiCNPCInventory.java @@ -1,22 +1,27 @@ package noppes.npcs.client.gui.player.inventory; -import cpw.mods.fml.common.Loader; -import kamkeel.npcs.addon.client.DBCClient; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.ClientCacheHandler; +import noppes.npcs.client.gui.util.GuiEffectBar; import noppes.npcs.client.gui.util.GuiMenuSideButton; import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.config.ConfigClient; -import noppes.npcs.config.ConfigMain; +import noppes.npcs.controllers.CustomEffectController; +import noppes.npcs.controllers.data.CustomEffect; +import noppes.npcs.controllers.data.PlayerData; +import noppes.npcs.controllers.data.PlayerEffect; +import org.lwjgl.input.Mouse; import tconstruct.client.tabs.InventoryTabCustomNpc; import tconstruct.client.tabs.TabRegistry; public class GuiCNPCInventory extends GuiNPCInterface { public static final ResourceLocation specialIcons = new ResourceLocation("customnpcs","textures/gui/icons.png"); - public static int activeTab = 0; + public static int activeTab = -100; protected Minecraft mc = Minecraft.getMinecraft(); + private GuiEffectBar effectBar; public GuiCNPCInventory() { super(); @@ -34,84 +39,117 @@ public class GuiCNPCInventory extends GuiNPCInterface { int y = 3; - GuiMenuSideButton questsButton = new GuiMenuSideButton(100, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); + GuiMenuSideButton questsButton = new GuiMenuSideButton(-100, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); questsButton.rightSided = true; - questsButton.active = activeTab == 0; + questsButton.active = activeTab == -100; questsButton.renderIconPosX = 32; questsButton.renderResource = specialIcons; - addButton(questsButton); - - y += 21; - GuiMenuSideButton partyButton = new GuiMenuSideButton(101, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); - partyButton.rightSided = true; - partyButton.active = activeTab == 1; - partyButton.renderResource = specialIcons; - addButton(partyButton); + addSideButton(questsButton); + if(ClientCacheHandler.allowParties){ + y += 21; + GuiMenuSideButton partyButton = new GuiMenuSideButton(-101, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); + partyButton.rightSided = true; + partyButton.active = activeTab == -101; + partyButton.renderResource = specialIcons; + addSideButton(partyButton); + } if(ConfigClient.enableFactionTab){ y += 21; - GuiMenuSideButton factionButton = new GuiMenuSideButton(102, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); + GuiMenuSideButton factionButton = new GuiMenuSideButton(-102, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); factionButton.rightSided = true; - factionButton.active = activeTab == 2; + factionButton.active = activeTab == -102; factionButton.renderIconPosX = 48; factionButton.renderResource = specialIcons; - addButton(factionButton); + addSideButton(factionButton); } - - if(Loader.isModLoaded("npcdbc")){ + if(ClientCacheHandler.allowProfiles){ y += 21; - GuiMenuSideButton dbcButton = new GuiMenuSideButton(104, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); - dbcButton.rightSided = true; - dbcButton.active = activeTab == 4; - dbcButton.renderIconPosX = 64; - dbcButton.renderResource = specialIcons; - addButton(dbcButton); - } - - if(ConfigMain.EnableProfiles){ - y += 21; - GuiMenuSideButton profileButton = new GuiMenuSideButton(105, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); + GuiMenuSideButton profileButton = new GuiMenuSideButton(-104, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); profileButton.rightSided = true; - profileButton.active = activeTab == 5; - profileButton.renderIconPosX = 80; + profileButton.active = activeTab == -104; + profileButton.renderIconPosX = 64; profileButton.renderResource = specialIcons; - addButton(profileButton); + addSideButton(profileButton); } y += 21; - GuiMenuSideButton clientButton = new GuiMenuSideButton(103, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); + GuiMenuSideButton clientButton = new GuiMenuSideButton(-103, guiLeft + xSize + 37, this.guiTop + y, 22, 22, ""); clientButton.rightSided = true; - clientButton.active = activeTab == 3; + clientButton.active = activeTab == -103; clientButton.renderIconPosX = 16; clientButton.renderResource = specialIcons; - addButton(clientButton); + addSideButton(clientButton); + + int effectBarX = guiLeft - 40; + int effectBarY = guiTop + 10; + int effectBarWidth = 28; + int effectBarHeight = ySize; + effectBar = new GuiEffectBar(effectBarX, effectBarY, effectBarWidth, effectBarHeight); + } + + private void updateEffectBar() { + if (effectBar != null) { + effectBar.entries.clear(); + PlayerData data = PlayerData.get(mc.thePlayer); + if (data != null && data.effectData != null) { + for (PlayerEffect pe : data.effectData.getEffects().values()) { + CustomEffect effect = CustomEffectController.getInstance().get(pe.id, pe.index); + if (effect != null) { + effectBar.entries.add(new GuiEffectBar.EffectEntry(effect, pe)); + } + } + } + } } + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + updateEffectBar(); + super.drawScreen(mouseX, mouseY, partialTicks); + if (!ConfigClient.HideEffectsBar && effectBar != null && !effectBar.entries.isEmpty()) { + if(activeTab != -100) + effectBar.drawScreen(mouseX, mouseY, partialTicks); + } + } + + @Override + public void handleMouseInput() { + int delta = Mouse.getDWheel(); + if (delta != 0 && effectBar != null) { + int mouseX = Mouse.getX() * this.width / mc.displayWidth; + int mouseY = this.height - Mouse.getY() * this.height / mc.displayHeight - 1; + if (mouseX >= effectBar.x && mouseX < effectBar.x + effectBar.width && + mouseY >= effectBar.y && mouseY < effectBar.y + effectBar.height) { + // Use delta/120 to convert the typical scroll wheel values to ±1 + effectBar.mouseScrolled(delta / 120); + } + } + super.handleMouseInput(); + } + + @Override protected void actionPerformed(GuiButton guibutton){ - if (guibutton.id >= 100) { - if (guibutton.id == 100 && activeTab != 0) { - activeTab = 0; + if (guibutton.id <= -100) { + if (guibutton.id == -100 && activeTab != -100) { + activeTab = -100; mc.displayGuiScreen(new GuiQuestLog()); } - if (guibutton.id == 101 && activeTab != 1) { - activeTab = 1; + if (guibutton.id == -101 && activeTab != -101) { + activeTab = -101; mc.displayGuiScreen(new GuiParty()); } - if (guibutton.id == 102 && activeTab != 2) { - activeTab = 2; + if (guibutton.id == -102 && activeTab != -102) { + activeTab = -102; mc.displayGuiScreen(new GuiFaction()); } - if (guibutton.id == 103 && activeTab != 3) { - activeTab = 3; + if (guibutton.id == -103 && activeTab != -103) { + activeTab = -103; mc.displayGuiScreen(new GuiSettings()); } - if (guibutton.id == 104 && activeTab != 4) { - activeTab = 4; - mc.displayGuiScreen(DBCClient.Instance.inventoryGUI()); - } - if (guibutton.id == 105 && activeTab != 5) { - activeTab = 5; + if (guibutton.id == -104 && activeTab != -104) { + activeTab = -104; mc.displayGuiScreen(new GuiProfiles()); } } diff --git a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiFaction.java b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiFaction.java index 9e7b39cf6..f8a4969d6 100644 --- a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiFaction.java +++ b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiFaction.java @@ -7,11 +7,9 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.GuiButtonNextPage; import noppes.npcs.client.gui.util.IGuiData; -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.controllers.data.Faction; import noppes.npcs.controllers.data.PlayerFactionData; import org.lwjgl.opengl.GL11; @@ -133,7 +131,7 @@ public class GuiFaction extends GuiCNPCInventory implements IGuiData { if(guibutton instanceof AbstractTab) return; - if (guibutton.id >= 100 && guibutton.id <= 105) { + if (guibutton.id <= -100) { super.actionPerformed(guibutton); return; } diff --git a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiParty.java b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiParty.java index 07af473b1..58348542a 100644 --- a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiParty.java +++ b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiParty.java @@ -1,7 +1,6 @@ package noppes.npcs.client.gui.player.inventory; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.packets.data.large.PartyDataPacket; import kamkeel.npcs.network.packets.player.CheckPlayerValue; import kamkeel.npcs.network.packets.request.party.*; import net.minecraft.client.gui.GuiButton; @@ -12,14 +11,10 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.QuestLogData; - import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.*; - -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.controllers.data.Party; import noppes.npcs.controllers.data.Quest; import org.lwjgl.opengl.GL11; @@ -226,7 +221,7 @@ public class GuiParty extends GuiCNPCInventory implements ITextfieldListener,ICu return; Party party = ClientCacheHandler.party; - if (guibutton.id >= 100 && guibutton.id <= 105) { + if (guibutton.id <= -100) { super.actionPerformed(guibutton); return; } diff --git a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiProfiles.java b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiProfiles.java index 053deddac..c4a805a68 100644 --- a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiProfiles.java +++ b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiProfiles.java @@ -1,43 +1,58 @@ package noppes.npcs.client.gui.player.inventory; +import noppes.npcs.api.handler.data.ISlot; +import kamkeel.npcs.controllers.data.InfoEntry; +import kamkeel.npcs.controllers.data.Profile; +import kamkeel.npcs.controllers.data.Slot; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.packets.player.CheckPlayerValue; +import kamkeel.npcs.network.packets.request.profile.*; import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiYesNo; +import net.minecraft.client.gui.GuiYesNoCallback; +import net.minecraft.client.gui.ScaledResolution; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.client.CustomNpcResourceListener; -import noppes.npcs.client.gui.util.GuiButtonNextPage; -import noppes.npcs.client.gui.util.IGuiData; -import noppes.npcs.constants.EnumPlayerPacket; -import noppes.npcs.controllers.data.Faction; -import noppes.npcs.controllers.data.PlayerFactionData; +import noppes.npcs.client.NoppesUtil; +import noppes.npcs.client.gui.SubGuiEditText; +import noppes.npcs.client.gui.util.*; +import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import tconstruct.client.tabs.AbstractTab; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; -public class GuiProfiles extends GuiCNPCInventory implements IGuiData { +public class GuiProfiles extends GuiCNPCInventory implements ISubGuiListener, ICustomScrollListener, IGuiData, GuiYesNoCallback { private final ResourceLocation resource = new ResourceLocation("customnpcs","textures/gui/standardbg.png"); + private GuiCustomScroll scroll; + public HashMap data = new HashMap<>(); + private String selected = null; + private String rename; + private Profile profile; + private Slot slot; + private HashMap> slotInfoMap = new HashMap<>(); + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm"); - private ArrayList playerFactions = new ArrayList(); + private int scrollY = 0; // Vertical scrolling position + private int maxScrollY = 0; // Maximum scroll limit - private int page = 0; - private int pages = 1; + private boolean draggingScrollbar = false; // Track if user is dragging the scrollbar + private int lastMouseY = 0; // Last recorded mouse Y position when dragging - private GuiButtonNextPage buttonNextPage; - private GuiButtonNextPage buttonPreviousPage; - - public GuiProfiles() { + public GuiProfiles() { super(); xSize = 280; ySize = 180; this.drawDefaultBackground = false; title = ""; - PacketClient.sendClient(new CheckPlayerValue(CheckPlayerValue.Type.Faction)); + PacketClient.sendClient(new ProfileGetPacket()); + PacketClient.sendClient(new ProfileGetInfoPacket()); } @Override @@ -45,155 +60,360 @@ public class GuiProfiles extends GuiCNPCInventory implements IGuiData { { super.initGui(); - this.buttonList.add(buttonNextPage = new GuiButtonNextPage(1, (guiLeft + (xSize + 35) / 2) + 25, guiTop + 170, true)); - this.buttonList.add(buttonPreviousPage = new GuiButtonNextPage(2, (guiLeft + (xSize + 35) / 2) - 40, guiTop + 170, false)); - updateButtons(); - } + int y = guiTop + 4; + this.addButton(new GuiNpcButton(1,guiLeft + 4, y += 144, 60, 20, "gui.change")); + this.addButton(new GuiNpcButton(2,guiLeft + 4 + 63, y, 60, 20, "gui.rename")); + this.addButton(new GuiNpcButton(3,guiLeft + 4 + 63, y += 22, 60, 20, "gui.remove")); + this.addButton(new GuiNpcButton(4,guiLeft + 4, y, 60, 20, "gui.create")); - @Override - public void drawScreen(int i, int j, float f) - { - drawDefaultBackground(); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - mc.renderEngine.bindTexture(resource); - drawTexturedModalRect(guiLeft, guiTop, 0, 0, 252, 195); - drawTexturedModalRect(guiLeft + 252, guiTop, 188, 0, 67, 195); - - if(playerFactions.isEmpty()){ - String noFaction = StatCollector.translateToLocal("faction.nostanding"); - fontRendererObj.drawString(noFaction,guiLeft + (xSize - fontRendererObj.getStringWidth(noFaction)) / 2,guiTop + 80, CustomNpcResourceListener.DefaultTextColor); + if(scroll == null){ + scroll = new GuiCustomScroll(this,0); + scroll.setSize(123, 141); } - else - renderScreen(); - - super.drawScreen(i, j, f); - + scroll.guiLeft = guiLeft + 4; + scroll.guiTop = guiTop + 4; + scroll.setList(new ArrayList(this.data.keySet())); + this.addScroll(scroll); } - private void renderScreen(){ - int size = 10; - if(playerFactions.size() % 10 != 0 && page == pages) - size = playerFactions.size() % 10; + @Override + protected void actionPerformed(GuiButton guibutton){ + if(guibutton instanceof AbstractTab) + return; - int hLine = 5; - if(size < 5){ - hLine = size; - } + if (guibutton.id <= -100) { + super.actionPerformed(guibutton); + return; + } - int count = -1; - for(int id = 0 ; id < size; id++){ - count++; + if(guibutton.id == 4){ + GuiYesNo guiyesno = new GuiYesNo(this, StatCollector.translateToLocal("profile.create.message"), StatCollector.translateToLocal("gui.sure"), 104); + displayGuiScreen(guiyesno); + } - Faction faction = playerFactions.get((page - 1) * 10 + id); - String name = faction.name; - String points = " : " + faction.defaultPoints; + if(this.slot == null) + return; - String standing = StatCollector.translateToLocal("faction.friendly"); - int color = 0x00FF00; - if(faction.defaultPoints < faction.neutralPoints){ - standing = StatCollector.translateToLocal("faction.unfriendly"); - color = 0xFF0000; - points += "/" + faction.neutralPoints; - } - else if(faction.defaultPoints < faction.friendlyPoints){ - standing = StatCollector.translateToLocal("faction.neutral"); - color = 0xF2FF00; - points += "/" + faction.friendlyPoints; - } - else{ - points += "/-"; - } - - drawVerticalLine(guiLeft + (xSize + 45) / 2, (guiTop + ySize - 15), guiTop + 13, 0xFF000000 + CustomNpcResourceListener.DefaultTextColor); - if(count < 5){ - drawHorizontalLine(guiLeft + 2, guiLeft + xSize + 35, guiTop + 14 + count * 30, 0xFF000000 + CustomNpcResourceListener.DefaultTextColor); - fontRendererObj.drawString(name, guiLeft + (xSize + 45 - fontRendererObj.getStringWidth(name)) / 4, guiTop + 19 + count * 30, faction.color); - - fontRendererObj.drawString(standing, (guiLeft + (xSize + 45) / 4) - fontRendererObj.getStringWidth(standing), guiTop + 33 + count * 30, color); - fontRendererObj.drawString(points, (guiLeft + (xSize + 45) / 4), guiTop + 33 + count * 30, CustomNpcResourceListener.DefaultTextColor); - } - else { - fontRendererObj.drawString(name, guiLeft + 3*(xSize + 45 - fontRendererObj.getStringWidth(name)) / 4, guiTop + 19 + (count - 5) * 30, faction.color); - - fontRendererObj.drawString(standing, (guiLeft + 3*(xSize + 45) / 4) - fontRendererObj.getStringWidth(standing) - 10, guiTop + 33 + (count - 5) * 30, color); - fontRendererObj.drawString(points, (guiLeft + 3*(xSize + 45) / 4) - 10, guiTop + 33 + (count - 5) * 30, CustomNpcResourceListener.DefaultTextColor); - } - - drawHorizontalLine(guiLeft + 2, guiLeft + xSize + 35, guiTop + 14 + hLine * 30, 0xFF000000 + CustomNpcResourceListener.DefaultTextColor); - } - - if(pages > 1){ - String s = page +"/" + pages; - fontRendererObj.drawString(s, guiLeft + (xSize + 45 - fontRendererObj.getStringWidth(s)) / 2, guiTop + 175, CustomNpcResourceListener.DefaultTextColor); + if(guibutton.id == 1){ + GuiYesNo guiyesno = new GuiYesNo(this, slot.getName(), StatCollector.translateToLocal("profile.change.message"), 101); + displayGuiScreen(guiyesno); + } + if(guibutton.id == 2){ + setSubGui(new SubGuiEditText(slot.getName())); + } + if(guibutton.id == 3){ + GuiYesNo guiyesno = new GuiYesNo(this, slot.getName(), StatCollector.translateToLocal("gui.delete"), 103); + displayGuiScreen(guiyesno); } } @Override - protected void actionPerformed(GuiButton guibutton){ - if(guibutton instanceof AbstractTab) - return; + public void drawScreen(int mouseX, int mouseY, float f) { + drawDefaultBackground(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture(resource); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, 252, 195); + drawTexturedModalRect(guiLeft + 252, guiTop, 188, 0, 67, 195); - if (guibutton.id >= 100 && guibutton.id <= 105) { - super.actionPerformed(guibutton); - return; + super.drawScreen(mouseX, mouseY, f); + if (hasSubGui()) return; + + renderScrollableScreen(mouseX, mouseY); + } + + /** + * Renders the scrollable area inside the background box. + */ + private void renderScrollableScreen(int mouseX, int mouseY) { + drawGradientRect(guiLeft + 133, guiTop + 4, guiLeft + xSize + 33, guiTop + 24, 0xC0101010, 0xC0101010); + drawHorizontalLine(guiLeft + 133, guiLeft + xSize + 33, guiTop + 25, 0xFF000000 + CustomNpcResourceListener.DefaultTextColor); + drawGradientRect(guiLeft + 133, guiTop + 27, guiLeft + xSize + 33, guiTop + ySize + 9, 0xA0101010, 0xA0101010); + + if (this.profile != null && slot != null) { + + String topBarText = slot.getName(); + int textWidth = fontRendererObj.getStringWidth(topBarText); + int barCenterX = guiLeft + 133 + ((xSize + 33 - 133) / 2); + int textX = barCenterX - (textWidth / 2); + fontRendererObj.drawString(topBarText, textX, guiTop + 10, 0xFFFFFF, true); + + GL11.glEnable(GL11.GL_SCISSOR_TEST); + ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int scaleFactor = sr.getScaleFactor(); + + // Define the SCISSOR RECTANGLE to restrict drawing to only within the background box + int scissorX = (guiLeft + 133) * scaleFactor; + int scissorY = (sr.getScaledHeight() - (guiTop + ySize + 6)) * scaleFactor; + int scissorW = (xSize + 33 - 133) * scaleFactor; + int scissorH = (ySize + 4 - 27) * scaleFactor; // The height from 27 to ySize+9 + GL11.glScissor(scissorX, scissorY, scissorW, scissorH); + + GL11.glPushMatrix(); + GL11.glTranslatef(0, -scrollY, 0); // Apply Scroll to Info + + int spacing = 14; + int y = guiTop + 30; + int xLabel = guiLeft + 136; + int boxRightX = guiLeft + xSize + 30; + + String label, result; + int labelColor, resultColor, resultWidth, resultX; + + label = StatCollector.translateToLocal("profile.lastLoaded"); + result = String.valueOf(DATE_FORMAT.format(new Date(slot.getLastLoaded()))); + labelColor = 0xff9c2b; + resultColor = 0xffdb59; + fontRendererObj.drawString(label, xLabel, y, labelColor, false); + resultWidth = fontRendererObj.getStringWidth(result); + resultX = boxRightX - resultWidth - 5; + fontRendererObj.drawString(result, resultX, y, resultColor, false); + y += spacing; + + if(slot.isTemporary()){ + label = StatCollector.translateToLocal("profile.temporary"); + result = (String.valueOf(slot.isTemporary())).toUpperCase(); + labelColor = 0xfc60dd; + resultColor = 0x35fc81; + fontRendererObj.drawString(label, xLabel, y, labelColor, false); + resultWidth = fontRendererObj.getStringWidth(result); + resultX = boxRightX - resultWidth - 5; + fontRendererObj.drawString(result, resultX, y, resultColor, false); + y += spacing; + } + + if (slotInfoMap.containsKey(slot.getId())) { + List infoEntries = slotInfoMap.get(slot.getId()); + for (InfoEntry entry : infoEntries) { + label = StatCollector.translateToLocal(entry.getLabel()); + result = StatCollector.translateToLocal(entry.getResult()); + labelColor = entry.getLabelColor(); + resultColor = entry.getResultColor(); + + // Draw Label + fontRendererObj.drawString(label, xLabel, y, labelColor, false); + + // Calculate Result X Position (Right-Aligned) + resultWidth = fontRendererObj.getStringWidth(result); + resultX = boxRightX - resultWidth - 5; + + // Draw Result at Right-Aligned Position + fontRendererObj.drawString(result, resultX, y, resultColor, false); + + // Move to next line + y += spacing; + } + } + + maxScrollY = Math.max(0, y - (guiTop + ySize - 35)); } - if(!(guibutton instanceof GuiButtonNextPage)) - return; - int id = guibutton.id; - if(id == 1){ - page++; - } - if(id == 2){ - page--; - } - updateButtons(); - } - private void updateButtons(){ - buttonNextPage.setVisible(page < pages); - buttonPreviousPage.setVisible(page > 1); - } - protected void drawGuiContainerBackgroundLayer(float f, int i, int j) - { + GL11.glPopMatrix(); + GL11.glDisable(GL11.GL_SCISSOR_TEST); + + // Draw scrollbar only if needed + if (maxScrollY > 0) { + drawScrollbar(); + } + } + + /** + * Handles mouse scroll input **only inside the background box**. + */ + @Override + public void handleMouseInput() { + super.handleMouseInput(); + if(isMouseOverScrollBox(mouseX, mouseY)){ + int delta = Mouse.getEventDWheel(); + if (delta != 0) { + scrollY -= delta / 7; + if (scrollY < 0) scrollY = 0; + if (scrollY > maxScrollY) scrollY = maxScrollY; + } + } + + if (draggingScrollbar) { + if (Mouse.isButtonDown(0)) { + int mouseDiff = mouseY - lastMouseY; + scrollY += (mouseDiff * maxScrollY) / (ySize - 70); + scrollY = Math.max(0, Math.min(scrollY, maxScrollY)); + lastMouseY = mouseY; + } else { + draggingScrollbar = false; + } + } + } + + /** + * Draws the vertical scrollbar (only if needed). + */ + private void drawScrollbar() { + int scrollbarX = guiLeft + xSize + 30; + int scrollbarY = guiTop + 27; + int scrollbarHeight = ySize - 18; + int thumbHeight = Math.max(10, (scrollbarHeight * scrollbarHeight) / (maxScrollY + scrollbarHeight)); + int thumbY = scrollbarY + ((scrollY * (scrollbarHeight - thumbHeight)) / maxScrollY); + + drawRect(scrollbarX, scrollbarY, scrollbarX + 5, scrollbarY + scrollbarHeight, 0xFF333333); + drawRect(scrollbarX, thumbY, scrollbarX + 5, thumbY + thumbHeight, 0xFFAAAAAA); + } + + /** + * Checks if the mouse is inside the background box for scrolling. + */ + private boolean isMouseOverScrollBox(int mouseX, int mouseY) { + return (mouseX >= guiLeft + 133 && mouseX <= guiLeft + xSize + 33 && + mouseY >= guiTop + 27 && mouseY <= guiTop + ySize + 9); } @Override public void keyTyped(char c, int i) { - if (i == 1 || isInventoryKey(i)) + super.keyTyped(c, i); + if (i == 1 || (!hasSubGui() && isInventoryKey(i))) { close(); } } @Override - public void save() { - } - @Override - public void setGuiData(NBTTagCompound compound) { - playerFactions = new ArrayList(); + public void save() {} - NBTTagList list = compound.getTagList("FactionList", 10); - for(int i = 0; i < list.tagCount(); i++){ - Faction faction = new Faction(); - faction.readNBT(list.getCompoundTagAt(i)); - playerFactions.add(faction); - } - PlayerFactionData data = new PlayerFactionData(); - data.loadNBTData(compound); - for(int id : data.factionData.keySet()){ - int points = data.factionData.get(id); - for(Faction faction : playerFactions){ - if(faction.id == id) - faction.defaultPoints = points; - } - } + @Override + public void confirmClicked(boolean result, int id) { + NoppesUtil.openGUI(player, this); + if (!result) + return; + if (id == 104) { + // Create Slot + PacketClient.sendClient(new ProfileCreatePacket()); + } + if(slot == null) + return; - pages = (playerFactions.size() - 1) / 10 ; - pages++; + if(id == 101){ + // Change Slot + PacketClient.sendClient(new ProfileChangePacket(slot.getId())); + } + if(id == 102 && rename != null && !rename.equalsIgnoreCase(slot.getName())){ + // Rename Slot + PacketClient.sendClient(new ProfileRenamePacket(slot.getId(), rename)); + } + if(id == 103){ + // Delete Slot + PacketClient.sendClient(new ProfileRemovePacket(slot.getId())); + } + } - page = 1; + @Override + public void subGuiClosed(SubGuiInterface subgui) { + if(subgui instanceof SubGuiEditText){ + if(!((SubGuiEditText)subgui).cancelled){ + rename = ((SubGuiEditText)subgui).text; + GuiYesNo guiyesno = new GuiYesNo(this, rename, StatCollector.translateToLocal("profile.rename.message"), 102); + displayGuiScreen(guiyesno); + } + } + } - updateButtons(); - } + @Override + public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) { + if (guiCustomScroll.id == 0) { + slot = null; + selected = scroll.getSelected(); + if (profile != null && selected != null && !selected.isEmpty()){ + for(ISlot checkSlot : profile.getSlots().values()){ + if(checkSlot.getId() == data.get(selected)){ + slot = (Slot) checkSlot; + break; + } + } + } + } + } + @Override + public void customScrollDoubleClicked(String selection, GuiCustomScroll scroll) {} + + public void setGuiData(NBTTagCompound compound) { + this.slot = null; + if(compound.hasKey("PROFILE")){ + // Load Profile + this.profile = new Profile(mc.thePlayer, compound); + this.data = new HashMap<>(); + String currentSlot = "\u00A7e"; + String otherSlot = "\u00A7f"; + for(ISlot slot1 : profile.getSlots().values()){ + String name = slot1.getId() + " - " + slot1.getName(); + if(profile.currentSlotId == slot1.getId()) + name = currentSlot + name; + else + name = otherSlot + name; + this.data.put(name, slot1.getId()); + } + } else if(compound.hasKey("PROFILE_INFO")){ + slotInfoMap = ProfileGetInfoPacket.readProfileInfo(compound); + } + if(scroll != null){ + scroll.setSelected(""); + } + initGui(); + } + + /** + * Handles mouse clicks for the scrollbar. + */ + @Override + public void mouseClicked(int mouseX, int mouseY, int button) { + super.mouseClicked(mouseX, mouseY, button); + + if (button == 0) { // Left mouse button + if (isMouseOverScrollbar(mouseX, mouseY)) { + int scrollbarY = guiTop + 27; + int scrollbarHeight = ySize - 35; + int thumbHeight = Math.max(10, (scrollbarHeight * scrollbarHeight) / (maxScrollY + scrollbarHeight)); + int thumbY = scrollbarY + ((scrollY * (scrollbarHeight - thumbHeight)) / maxScrollY); + + // If clicking on scrollbar thumb, start dragging + if (mouseY >= thumbY && mouseY <= thumbY + thumbHeight) { + draggingScrollbar = true; + lastMouseY = mouseY; + } else { + // Click anywhere on scrollbar background to jump position + scrollY = ((mouseY - scrollbarY) * maxScrollY) / scrollbarHeight; + scrollY = Math.max(0, Math.min(scrollY, maxScrollY)); + } + } + } + } + + /** + * Handles mouse dragging while clicking. + */ + @Override + public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + if (draggingScrollbar) { + int mouseDiff = mouseY - lastMouseY; + scrollY += (mouseDiff * maxScrollY) / (ySize - 70); + scrollY = Math.max(0, Math.min(scrollY, maxScrollY)); + lastMouseY = mouseY; + } + } + + /** + * Handles mouse release. + */ + @Override + protected void mouseMovedOrUp(int mouseX, int mouseY, int state) { + super.mouseMovedOrUp(mouseX, mouseY, state); + if (state == 0) { + draggingScrollbar = false; + } + } + + private boolean isMouseOverScrollbar(int mouseX, int mouseY) { + int scrollbarX = guiLeft + xSize + 30; + int scrollbarY = guiTop + 27; + int scrollbarHeight = ySize - 35; + return (mouseX >= scrollbarX && mouseX <= scrollbarX + 5 && + mouseY >= scrollbarY && mouseY <= scrollbarY + scrollbarHeight); + } } diff --git a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiQuestLog.java b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiQuestLog.java index 1ab495627..55583f14e 100644 --- a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiQuestLog.java +++ b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiQuestLog.java @@ -2,7 +2,6 @@ package noppes.npcs.client.gui.player.inventory; import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.player.CheckPlayerValue; -import kamkeel.npcs.network.packets.request.party.PartyLogToServerPacket; import kamkeel.npcs.network.packets.request.party.PartySetQuestPacket; import kamkeel.npcs.network.packets.request.quest.QuestLogToServerPacket; import net.minecraft.client.gui.GuiButton; @@ -13,12 +12,12 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; import noppes.npcs.NBTTags; -import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.QuestLogData; -import noppes.npcs.client.*; +import noppes.npcs.client.ClientCacheHandler; +import noppes.npcs.client.CustomNpcResourceListener; +import noppes.npcs.client.NoppesUtil; +import noppes.npcs.client.TextBlockClient; import noppes.npcs.client.gui.util.*; - -import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.controllers.data.Party; import noppes.npcs.util.ValueUtil; import org.lwjgl.input.Mouse; @@ -171,7 +170,7 @@ public class GuiQuestLog extends GuiCNPCInventory implements ICustomScrollListen if(guibutton instanceof AbstractTab) return; - if (guibutton.id >= 100 && guibutton.id <= 105) { + if (guibutton.id <= -100) { super.actionPerformed(guibutton); return; } diff --git a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiSettings.java b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiSettings.java index f85d95c00..5ad6c4882 100644 --- a/src/main/java/noppes/npcs/client/gui/player/inventory/GuiSettings.java +++ b/src/main/java/noppes/npcs/client/gui/player/inventory/GuiSettings.java @@ -1,21 +1,20 @@ package noppes.npcs.client.gui.player.inventory; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.packets.request.quest.QuestUntrackPacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; - import noppes.npcs.client.ClientCacheHandler; +import noppes.npcs.client.gui.hud.GuiHudEditor; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.GuiNpcTextField; import noppes.npcs.client.gui.util.ITextfieldListener; import noppes.npcs.config.ConfigClient; - +import noppes.npcs.config.ConfigMain; import org.lwjgl.opengl.GL11; import tconstruct.client.tabs.AbstractTab; @@ -40,17 +39,14 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, this.addLabel(new GuiNpcLabel(1, "settings.chatBubbles", guiLeft + 8, guiTop + 14 + y)); this.addButton(new GuiNpcButton(1, guiLeft + 105, guiTop + 9 + y, 50, 20, new String[]{"gui.no", "gui.yes"}, ConfigClient.EnableChatBubbles?1:0)); - this.addLabel(new GuiNpcLabel(3, "settings.trackAlignment", guiLeft + 8 + 155, guiTop + 14 + y)); - this.addButton(new GuiNpcButton(3, guiLeft + 105 + 160, guiTop + 9 + y, 50, 20, new String[]{"TLeft", "TCenter", "TRight", "Left", "Center", "Right", "BLeft", "BCenter", "BRight"}, ConfigClient.TrackingInfoAlignment)); - y += 22; this.addLabel(new GuiNpcLabel(2, "settings.dialogSound", guiLeft + 8, guiTop + 14 + y)); this.addButton(new GuiNpcButton(2, guiLeft + 105, guiTop + 9 + y, 50, 20, new String[]{"gui.no", "gui.yes"}, ConfigClient.DialogSound?1:0)); - this.addLabel(new GuiNpcLabel(12,"settings.alignmentX", guiLeft + 8 + 155, guiTop + 14 + y)); - this.addTextField(new GuiNpcTextField(12, this, this.fontRendererObj, guiLeft + 107 + 160, guiTop + 9 + y, 45, 20, ConfigClient.TrackingInfoX + "")); - getTextField(12).integersOnly = true; - getTextField(12).setMinMaxDefault(-2000, 2000, 0); +// this.addLabel(new GuiNpcLabel(12,"settings.alignmentX", guiLeft + 8 + 155, guiTop + 14 + y)); +// this.addTextField(new GuiNpcTextField(12, this, this.fontRendererObj, guiLeft + 107 + 160, guiTop + 9 + y, 45, 20, ConfigClient.TrackingInfoX + "")); +// getTextField(12).integersOnly = true; +// getTextField(12).setMinMaxDefault(-2000, 2000, 0); y += 22; this.addLabel(new GuiNpcLabel(10,"settings.dialogSpeed", guiLeft + 8, guiTop + 14 + y)); @@ -58,21 +54,12 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, getTextField(10).integersOnly = true; getTextField(10).setMinMaxDefault(1, 20, 10); - this.addLabel(new GuiNpcLabel(13,"settings.alignmentY", guiLeft + 8 + 155, guiTop + 14 + y)); - this.addTextField(new GuiNpcTextField(13, this, this.fontRendererObj, guiLeft + 107 + 160, guiTop + 9 + y, 45, 20, ConfigClient.TrackingInfoY + "")); - getTextField(13).integersOnly = true; - getTextField(13).setMinMaxDefault(-2000, 2000, 0); y += 22; this.addLabel(new GuiNpcLabel(6, "settings.chatAlerts", guiLeft + 8, guiTop + 14 + y)); this.addButton(new GuiNpcButton(6, guiLeft + 105, guiTop + 9 + y, 50, 20, new String[]{"gui.no", "gui.yes"}, ConfigClient.ChatAlerts?1:0)); - this.addLabel(new GuiNpcLabel(14,"settings.trackScale", guiLeft + 8 + 155, guiTop + 14 + y)); - this.addTextField(new GuiNpcTextField(14, this, this.fontRendererObj, guiLeft + 107 + 160, guiTop + 9 + y, 45, 20, ConfigClient.TrackingScale + "")); - getTextField(14).integersOnly = true; - getTextField(14).setMinMaxDefault(0, 300, 100); - y += 22; this.addLabel(new GuiNpcLabel(7, "settings.bannerAlerts", guiLeft + 8, guiTop + 14 + y)); @@ -80,8 +67,14 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, y += 22; + this.addLabel(new GuiNpcLabel(8, "settings.effectsBar", guiLeft + 8, guiTop + 14 + y)); + this.addButton(new GuiNpcButton(8, guiLeft + 105, guiTop + 9 + y, 50, 20, new String[]{"gui.no", "gui.yes"}, ConfigClient.HideEffectsBar?1:0)); + y += 22; + this.addLabel(new GuiNpcLabel(90, "overlayer", guiLeft + 8, guiTop + 14 + y)); + this.addButton(new GuiNpcButton(90, guiLeft + 105, guiTop + 9 + y, "EDIT")); + y += 22; this.addButton(new GuiNpcButton(5, guiLeft + 8, guiTop + 9 + y, 150, 20, "settings.clearSkin")); this.addButton(new GuiNpcButton(4, guiLeft + 8 + 155, guiTop + 9 + y, 150, 20, "settings.clearTrack")); @@ -122,7 +115,7 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, if(btn instanceof AbstractTab) return; - if (btn.id >= 100 && btn.id <= 105) { + if (btn.id <= -100) { super.actionPerformed(btn); return; } @@ -137,10 +130,6 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, ConfigClient.DialogSound = button.getValue() == 1; ConfigClient.DialogSoundProperty.set(ConfigClient.DialogSound); } - if(button.id == 3){ - ConfigClient.TrackingInfoAlignment = button.getValue(); - ConfigClient.TrackingInfoAlignmentProperty.set(ConfigClient.TrackingInfoAlignment); - } if(button.id == 4){ GuiYesNo yesNoTrack = new GuiYesNo(this, "Confirm", StatCollector.translateToLocal("settings.confirmClearTrack"), 0); displayGuiScreen(yesNoTrack); @@ -157,6 +146,15 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, ConfigClient.BannerAlerts = button.getValue() == 1; ConfigClient.BannerAlertsProperty.set(ConfigClient.BannerAlerts); } + if(button.id == 8){ + ConfigClient.HideEffectsBar = button.getValue() == 1; + ConfigClient.HideEffectsBarProperty.set(ConfigClient.HideEffectsBar); + } + if(button.id == 90){ + mc.displayGuiScreen(new GuiHudEditor(this)); + } + + ConfigClient.config.save(); } @@ -180,19 +178,5 @@ public class GuiSettings extends GuiCNPCInventory implements ITextfieldListener, ConfigClient.DialogSpeed = textfield.getInteger(); ConfigClient.DialogSpeedProperty.set(ConfigClient.DialogSound); } - - // Quest Tracking - if(textfield.id == 12){ - ConfigClient.TrackingInfoX = textfield.getInteger(); - ConfigClient.TrackingInfoXProperty.set(ConfigClient.TrackingInfoX); - } - if(textfield.id == 13){ - ConfigClient.TrackingInfoY = textfield.getInteger(); - ConfigClient.TrackingInfoYProperty.set(ConfigClient.TrackingInfoY); - } - if(textfield.id == 14){ - ConfigClient.TrackingScale = textfield.getInteger(); - ConfigClient.TrackingScaleProperty.set(ConfigClient.TrackingScale); - } } } diff --git a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeDialog.java b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeDialog.java index 9458c5095..3aa5d0fea 100644 --- a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeDialog.java +++ b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeDialog.java @@ -5,13 +5,11 @@ import kamkeel.npcs.network.packets.request.quest.QuestDialogGetTitlePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.select.GuiDialogSelection; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiSelectionListener; import noppes.npcs.client.gui.util.IGuiData; import noppes.npcs.client.gui.util.SubGuiInterface; - import noppes.npcs.controllers.data.Quest; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.quests.QuestDialog; diff --git a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java index 19ca84c53..c1e8381ad 100644 --- a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java +++ b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeKill.java @@ -12,7 +12,6 @@ import noppes.npcs.quests.QuestKill; import java.lang.reflect.Modifier; import java.util.ArrayList; -import java.util.HashMap; import java.util.Map; import java.util.TreeMap; diff --git a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java index 19f2293bb..a05a38c72 100644 --- a/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java +++ b/src/main/java/noppes/npcs/client/gui/questtypes/GuiNpcQuestTypeManual.java @@ -7,7 +7,6 @@ import noppes.npcs.controllers.data.Quest; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.quests.QuestManual; -import java.util.HashMap; import java.util.TreeMap; public class GuiNpcQuestTypeManual extends SubGuiInterface implements ITextfieldListener diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBankSetup.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBankSetup.java index 615368344..1483c9aba 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBankSetup.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBankSetup.java @@ -1,17 +1,14 @@ package noppes.npcs.client.gui.roles; import kamkeel.npcs.network.PacketClient; -import kamkeel.npcs.network.packets.request.bank.BankGetPacket; import kamkeel.npcs.network.packets.request.bank.BanksGetPacket; import kamkeel.npcs.network.packets.request.role.RoleSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.util.GuiCustomScroll; import noppes.npcs.client.gui.util.GuiNPCInterface2; import noppes.npcs.client.gui.util.ICustomScrollListener; import noppes.npcs.client.gui.util.IScrollData; - import noppes.npcs.controllers.data.Bank; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleBank; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBard.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBard.java index 319d3bfcf..37317a08f 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBard.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcBard.java @@ -1,14 +1,10 @@ package noppes.npcs.client.gui.roles; -import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.jobs.JobSavePacket; import net.minecraft.client.gui.GuiButton; -import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.controllers.MusicController; import noppes.npcs.client.gui.select.GuiSoundSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobBard; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcCompanion.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcCompanion.java index 136dbdc77..f17b3052e 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcCompanion.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcCompanion.java @@ -5,12 +5,10 @@ import kamkeel.npcs.network.packets.request.role.RoleCompanionUpdatePacket; import kamkeel.npcs.network.packets.request.role.RoleSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.player.companion.GuiNpcCompanionTalents.GuiTalent; import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumCompanionStage; import noppes.npcs.constants.EnumCompanionTalent; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleCompanion; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcConversation.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcConversation.java index 1ee14f2f4..1948c26b0 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcConversation.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcConversation.java @@ -2,12 +2,9 @@ package noppes.npcs.client.gui.roles; import kamkeel.npcs.network.packets.request.jobs.JobSavePacket; import net.minecraft.client.gui.GuiButton; -import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.SubGuiNpcAvailability; import noppes.npcs.client.gui.select.GuiQuestSelection; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobConversation; import noppes.npcs.roles.JobConversation.ConversationLine; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerJob.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerJob.java index 0223de066..a995ce380 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerJob.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerJob.java @@ -1,10 +1,7 @@ package noppes.npcs.client.gui.roles; import kamkeel.npcs.network.packets.request.jobs.JobSavePacket; -import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobFollower; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerSetup.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerSetup.java index bf40f5cf4..5664d3549 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerSetup.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcFollowerSetup.java @@ -6,9 +6,7 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.containers.ContainerNPCFollowerSetup; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleFollower; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcGuard.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcGuard.java index bb2a2bdf9..0fa18d455 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcGuard.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcGuard.java @@ -4,13 +4,10 @@ import kamkeel.npcs.network.packets.request.jobs.JobSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.util.GuiCustomScroll; import noppes.npcs.client.gui.util.GuiNPCInterface2; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobGuard; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcHealer.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcHealer.java index 25ac2077e..05c41b644 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcHealer.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcHealer.java @@ -1,12 +1,9 @@ package noppes.npcs.client.gui.roles; import kamkeel.npcs.network.packets.request.jobs.JobSavePacket; -import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.util.GuiNPCInterface2; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.GuiNpcTextField; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobHealer; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcItemGiver.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcItemGiver.java index 15cf67340..5b518dc2b 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcItemGiver.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcItemGiver.java @@ -2,14 +2,11 @@ package noppes.npcs.client.gui.roles; import kamkeel.npcs.network.packets.request.jobs.JobSavePacket; import net.minecraft.client.gui.GuiButton; -import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.SubGuiNpcAvailability; import noppes.npcs.client.gui.util.GuiContainerNPCInterface2; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.GuiNpcLabel; import noppes.npcs.client.gui.util.GuiNpcTextField; - import noppes.npcs.containers.ContainerNpcItemGiver; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobItemGiver; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcSpawner.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcSpawner.java index 1afbedf74..105a52be6 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcSpawner.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcSpawner.java @@ -7,10 +7,8 @@ import kamkeel.npcs.network.packets.request.jobs.JobSpawnerRemovePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.StatCollector; - import noppes.npcs.client.gui.GuiNpcMobSpawnerSelector; import noppes.npcs.client.gui.util.*; - import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.JobSpawner; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTraderSetup.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTraderSetup.java index 389e52850..38e270d18 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTraderSetup.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTraderSetup.java @@ -7,10 +7,8 @@ import kamkeel.npcs.network.packets.request.role.RoleSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; - import noppes.npcs.client.CustomNpcResourceListener; import noppes.npcs.client.gui.util.*; - import noppes.npcs.containers.ContainerNPCTraderSetup; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.roles.RoleTrader; diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTransporter.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTransporter.java index 6bf2c3f62..15da59255 100644 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTransporter.java +++ b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcTransporter.java @@ -6,9 +6,7 @@ import kamkeel.npcs.network.packets.request.transport.TransportGetLocationPacket import kamkeel.npcs.network.packets.request.transport.TransportSavePacket; import net.minecraft.client.gui.GuiButton; import net.minecraft.nbt.NBTTagCompound; - import noppes.npcs.client.gui.util.*; - import noppes.npcs.controllers.data.TransportLocation; import noppes.npcs.entity.EntityNPCInterface; diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java index 908d1b75a..c4220720a 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptAllNPCs.java @@ -3,8 +3,6 @@ package noppes.npcs.client.gui.script; import kamkeel.npcs.network.packets.request.script.GlobalNPCScriptPacket; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.NBTTags; - - import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.data.GlobalNPCDataScript; diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptForge.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptForge.java index 7d0ec5aee..d26499219 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptForge.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptForge.java @@ -13,8 +13,6 @@ import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.ChunkWatchEvent; import net.minecraftforge.event.world.WorldEvent; import noppes.npcs.NBTTags; - - import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.data.ForgeDataScript; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptGlobal.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptGlobal.java index 234c9b893..0683ef87c 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptGlobal.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptGlobal.java @@ -5,11 +5,9 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; - import noppes.npcs.client.gui.util.GuiNPCInterface; import noppes.npcs.client.gui.util.GuiNpcButton; import noppes.npcs.client.gui.util.IGuiData; - import org.lwjgl.opengl.GL11; import java.util.HashMap; diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptItem.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptItem.java index 6f7d9e1cd..2880df5d8 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptItem.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptItem.java @@ -1,16 +1,11 @@ package noppes.npcs.client.gui.script; -import kamkeel.npcs.network.PacketClient; import kamkeel.npcs.network.packets.request.script.item.ItemScriptErrorPacket; import kamkeel.npcs.network.packets.request.script.item.ItemScriptPacket; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.CustomItems; - - import noppes.npcs.NBTTags; -import noppes.npcs.NoppesStringUtils; -import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.scripted.item.ScriptCustomItem; import java.util.Date; diff --git a/src/main/java/noppes/npcs/client/gui/script/GuiScriptPlayers.java b/src/main/java/noppes/npcs/client/gui/script/GuiScriptPlayers.java index 22973038d..153dea0c7 100644 --- a/src/main/java/noppes/npcs/client/gui/script/GuiScriptPlayers.java +++ b/src/main/java/noppes/npcs/client/gui/script/GuiScriptPlayers.java @@ -4,8 +4,6 @@ import kamkeel.npcs.network.packets.request.script.PlayerScriptPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.NBTTags; - - import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.data.PlayerDataScript; diff --git a/src/main/java/noppes/npcs/client/gui/select/GuiSoundSelection.java b/src/main/java/noppes/npcs/client/gui/select/GuiSoundSelection.java index 97bb7af13..11573e2a4 100644 --- a/src/main/java/noppes/npcs/client/gui/select/GuiSoundSelection.java +++ b/src/main/java/noppes/npcs/client/gui/select/GuiSoundSelection.java @@ -7,10 +7,8 @@ import net.minecraft.client.audio.SoundHandler; import net.minecraft.client.audio.SoundRegistry; import net.minecraft.client.gui.GuiButton; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.StatCollector; import noppes.npcs.client.controllers.MusicController; import noppes.npcs.client.gui.util.*; -import noppes.npcs.entity.EntityNPCInterface; import java.util.ArrayList; import java.util.HashMap; 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 68f5e6de7..a98f2c329 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiCustomScroll.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiCustomScroll.java @@ -4,7 +4,6 @@ import kamkeel.npcs.util.TextSplitter; import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; -import noppes.npcs.client.gui.global.GuiNPCManageDialogs; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; @@ -15,7 +14,7 @@ import static noppes.npcs.client.gui.util.GuiNPCInterface.resizingActive; public class GuiCustomScroll extends GuiScreen { public static final ResourceLocation resource = new ResourceLocation("customnpcs","textures/gui/misc.png"); - protected List list; + public List list; public final HashMap colors = new HashMap<>(); public int id; diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiDiagram.java b/src/main/java/noppes/npcs/client/gui/util/GuiDiagram.java index 8c8e839de..a831842e6 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiDiagram.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiDiagram.java @@ -1,8 +1,5 @@ package noppes.npcs.client.gui.util; -import java.awt.Point; -import java.util.*; - import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; @@ -10,6 +7,11 @@ import net.minecraft.client.gui.ScaledResolution; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; +import java.awt.*; +import java.util.List; +import java.util.Queue; +import java.util.*; + /** * Abstract GUI class for drawing diagrams with icons (nodes) and connections (arrows). * diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiEffectBar.java b/src/main/java/noppes/npcs/client/gui/util/GuiEffectBar.java new file mode 100644 index 000000000..7aa4119a2 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/util/GuiEffectBar.java @@ -0,0 +1,213 @@ +package noppes.npcs.client.gui.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.client.ClientCacheHandler; +import noppes.npcs.client.renderer.ImageData; +import noppes.npcs.controllers.data.CustomEffect; +import noppes.npcs.controllers.data.PlayerEffect; +import org.lwjgl.opengl.GL11; + +import java.util.ArrayList; +import java.util.List; + +import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons; + +public class GuiEffectBar extends GuiScreen { + public int x, y, width, height; + public int scrollY = 0; // Tracks vertical scrolling + public int entryHeight = 28; // Height for each effect slot + public List entries = new ArrayList<>(); + public FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; + + public GuiEffectBar(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + @Override + public void initGui() { + this.fontRenderer = Minecraft.getMinecraft().fontRenderer; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + // Draw background of effect bar + drawRect(x, y, x + width, y + height, 0x90000000); + + int totalHeight = entries.size() * (entryHeight + 2); // +2 for padding + if (scrollY < 0) scrollY = 0; + if (scrollY > totalHeight - height) scrollY = Math.max(totalHeight - height, 0); + + // Enable scissoring for vertical clipping + GL11.glEnable(GL11.GL_SCISSOR_TEST); + Minecraft minecraft = Minecraft.getMinecraft(); + ScaledResolution sr = new ScaledResolution(minecraft, minecraft.displayWidth, minecraft.displayHeight); + int scaleFactor = sr.getScaleFactor(); + int scissorX = x * scaleFactor; + int scissorY = (sr.getScaledHeight() - (y + height)) * scaleFactor; + int scissorW = width * scaleFactor; + int scissorH = height * scaleFactor; + GL11.glScissor(scissorX, scissorY, scissorW, scissorH); + + int iconRenderSize = 24; + int padding = 1; + // Calculate vertical offset to center the icon in the slot + int iconYOffset = (entryHeight - iconRenderSize) / 2; + + int startIndex = scrollY / (entryHeight + padding); + int endIndex = Math.min(entries.size(), startIndex + height / (entryHeight + padding) + 1); + + List hoveredTooltip = null; + int tooltipX = 0, tooltipY = 0; + CustomEffect toolTipEffect = null; + + for (int i = startIndex; i < endIndex; i++) { + int drawY = y + (i - startIndex) * (entryHeight + padding) - (scrollY % (entryHeight + padding)); + EffectEntry entry = entries.get(i); + ImageData imageData = ClientCacheHandler.getImageData(entry.effect.getIcon()); + + if (imageData != null && imageData.imageLoaded()) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + imageData.bindTexture(); + int iconU = entry.effect.iconX; + int iconV = entry.effect.iconY; + int iconWidth = entry.effect.getWidth(); + int iconHeight = entry.effect.getHeight(); + int texWidth = imageData.getTotalWidth(); + + // Use iconYOffset to vertically center the icon + func_152125_a(x + 2, drawY + iconYOffset, iconU, iconV, iconWidth, iconHeight, iconRenderSize, iconRenderSize, texWidth, texWidth); + + GL11.glDisable(GL11.GL_DEPTH_TEST); + Minecraft.getMinecraft().getTextureManager().bindTexture(specialIcons); + func_152125_a(x + 2, drawY + iconYOffset, 0, 224, 16, 16, iconRenderSize, iconRenderSize, 256, 256); + GL11.glEnable(GL11.GL_DEPTH_TEST); + } + + // Mouse hover logic remains unchanged + if (mouseX >= x && mouseX < x + width && + mouseY >= drawY && mouseY < drawY + entryHeight) { + int seconds = entry.playerEffect.duration; + hoveredTooltip = new ArrayList<>(); + hoveredTooltip.add(entry.effect.getMenuName()); + hoveredTooltip.add("Time: " + seconds + "s"); + + tooltipX = mouseX; + tooltipY = mouseY; + toolTipEffect = entry.effect; + } + } + + // Disable scissoring for tooltip rendering + GL11.glDisable(GL11.GL_SCISSOR_TEST); + + // Draw vertical scrollbar + if (totalHeight > height) { + int scrollBarWidth = 4; + int scrollBarX = x + width - scrollBarWidth - 2 + 10 ; + drawRect(scrollBarX, y, scrollBarX + scrollBarWidth, y + height, 0xFF333333); + int thumbHeight = Math.max(20, height * height / totalHeight); + int thumbY = y + (scrollY * (height - thumbHeight)) / (totalHeight - height); + drawRect(scrollBarX, thumbY, scrollBarX + scrollBarWidth, thumbY + thumbHeight, 0xFFAAAAAA); + } + + super.drawScreen(mouseX, mouseY, partialTicks); + + // Draw tooltip after all icons + if (hoveredTooltip != null && fontRenderer != null && toolTipEffect != null) { + drawCustomHoveringText(hoveredTooltip, tooltipX, tooltipY, fontRenderer, toolTipEffect); + } + } + + /** + * Adjusted scrolling to move up and down instead of left and right. + */ + public void mouseScrolled(int delta) { + int padding = 1; + int totalHeight = entries.size() * (entryHeight + padding); + scrollY -= delta * 10; // Adjust scroll speed as needed. + if (scrollY < 0) scrollY = 0; + if (scrollY > totalHeight - height) scrollY = Math.max(totalHeight - height, 0); + } + + /** + * Custom tooltip with enlarged effect icon. + */ + public void drawCustomHoveringText(List textLines, int x, int y, FontRenderer font, CustomEffect hoveredEffect) { + if (textLines == null || textLines.isEmpty()) return; + + int maxWidth = 0; + for (String s : textLines) { + int lineWidth = font.getStringWidth(s); + if (lineWidth > maxWidth) { + maxWidth = lineWidth; + } + } + + int iconSize = 32; + + int tooltipHeight = 8 + iconSize + 8; // Reserve space for enlarged icon + if (textLines.size() > 1) { + tooltipHeight += 2 + (textLines.size() - 1) * 10; + } + + int screenWidth = Minecraft.getMinecraft().currentScreen.width; + int screenHeight = Minecraft.getMinecraft().currentScreen.height; + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); + + int tooltipX = x + 12; + int tooltipY = y - 12; + if (tooltipX + maxWidth > screenWidth) { + tooltipX = x - 28 - maxWidth; + } + if (tooltipY + tooltipHeight + 6 > screenHeight) { + tooltipY = screenHeight - tooltipHeight - 6; + } + + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glPushMatrix(); + this.zLevel = 1000.0F; + + // Draw tooltip background + drawRect(tooltipX - 3, tooltipY - 4, tooltipX + maxWidth + 3, tooltipY + tooltipHeight, 0xF0100010); + + // Draw text + int textY = tooltipY; + for (String s : textLines) { + font.drawStringWithShadow(s, tooltipX, textY, 0xFFFFFF); + textY += 10; + } + + // Draw enlarged icon + ImageData imageData = ClientCacheHandler.getImageData(hoveredEffect.getIcon()); + if (imageData != null && imageData.imageLoaded()) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + imageData.bindTexture(); + func_152125_a(tooltipX + (maxWidth - iconSize) / 2, textY + 4, hoveredEffect.iconX, hoveredEffect.iconY, hoveredEffect.getWidth(), hoveredEffect.getHeight(), iconSize, iconSize, imageData.getTotalWidth(), imageData.getTotalWidth()); + } + + textureManager.bindTexture(specialIcons); + func_152125_a(tooltipX + (maxWidth - iconSize) / 2, textY + 4, 0, 224, 16, 16, iconSize, iconSize, 256, 256); + GL11.glEnable(GL11.GL_DEPTH_TEST); + + GL11.glPopMatrix(); + GL11.glPopAttrib(); + } + + public static class EffectEntry { + public CustomEffect effect; + public PlayerEffect playerEffect; + public EffectEntry(CustomEffect effect, PlayerEffect playerEffect) { + this.effect = effect; + this.playerEffect = playerEffect; + } + } +} diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiMenuTopButton.java b/src/main/java/noppes/npcs/client/gui/util/GuiMenuTopButton.java index 48ad1b389..33604c02c 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiMenuTopButton.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiMenuTopButton.java @@ -40,6 +40,9 @@ public class GuiMenuTopButton extends GuiNpcButton public int getHoverState(boolean flag) { byte byte0 = 1; + if(!enabled) + return byte0; + if (active) { byte0 = 0; @@ -57,7 +60,7 @@ public class GuiMenuTopButton extends GuiNpcButton if (!getVisible()) { return; - } + } GL11.glPushMatrix(); minecraft.renderEngine.bindTexture(resource); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); @@ -74,7 +77,7 @@ public class GuiMenuTopButton extends GuiNpcButton { drawCenteredString(fontrenderer, displayString, xPosition + getWidth() / 2, yPosition + (height - 8) / 2, 0xffffa0); } - else if (hover) + else if (hover && enabled) { drawCenteredString(fontrenderer, displayString, xPosition + getWidth() / 2, yPosition + (height - 8) / 2, 0xffffa0); } diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java index 7ffbc3b34..d605aaa76 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java @@ -162,6 +162,24 @@ public abstract class GuiNPCInterface extends GuiScreen { } } + @Override + public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + if (subgui != null) { + subgui.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + return; + } + super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + } + + @Override + protected void mouseMovedOrUp(int mouseX, int mouseY, int state) { + if (subgui != null) { + subgui.mouseMovedOrUp(mouseX, mouseY, state); + return; + } + super.mouseMovedOrUp(mouseX, mouseY, state); + } + public void mouseEvent(int i, int j, int k){} @Override diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface2.java b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface2.java index a987fe826..da766c681 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface2.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface2.java @@ -1,12 +1,9 @@ package noppes.npcs.client.gui.util; -import net.minecraft.client.gui.FontRenderer; import net.minecraft.util.ResourceLocation; import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.opengl.GL11; -import java.util.List; - public abstract class GuiNPCInterface2 extends GuiNPCInterface { private ResourceLocation background = new ResourceLocation("customnpcs:textures/gui/menubg.png"); diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiNpcMenu.java b/src/main/java/noppes/npcs/client/gui/util/GuiNpcMenu.java index 70492f9cb..10be5d5d8 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiNpcMenu.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiNpcMenu.java @@ -10,10 +10,8 @@ import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; import net.minecraft.util.StatCollector; import noppes.npcs.CustomNpcs; - import noppes.npcs.client.NoppesUtil; import noppes.npcs.constants.EnumGuiType; - import noppes.npcs.entity.EntityNPCInterface; import org.lwjgl.input.Keyboard; diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiNpcSquareButton.java b/src/main/java/noppes/npcs/client/gui/util/GuiNpcSquareButton.java index 8132e2eaa..072f64c30 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiNpcSquareButton.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiNpcSquareButton.java @@ -5,8 +5,6 @@ import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.RenderHelper; import org.lwjgl.opengl.GL11; -import static noppes.npcs.client.gui.player.inventory.GuiCNPCInventory.specialIcons; - public class GuiNpcSquareButton extends GuiNpcButton { // Fixed height for the text button portion. diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiToggleButton.java b/src/main/java/noppes/npcs/client/gui/util/GuiToggleButton.java new file mode 100644 index 000000000..c2e0506af --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/util/GuiToggleButton.java @@ -0,0 +1,172 @@ +package noppes.npcs.client.gui.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class GuiToggleButton extends GuiNpcButton { + + // Fixed dimensions: 40x20 (even if other values are passed) + private static final int FIXED_WIDTH = 40; + private static final int FIXED_HEIGHT = 20; + + private boolean toggled; + // Animation progress: 0.0 = OFF (knob left), 1.0 = ON (knob right) + private float animProgress; + + // Optional off icon (if not set, the super class icon is used) + private ResourceLocation textureOff = null; + private int textureOffPosX = 0; + private int textureOffPosY = 0; + // Off icon always 16x16 + private static final int ICON_SIZE = 16; + + /** + * Basic constructor. Uses the super class’s icon as the ON texture. + * Note: The button is fixed at 40×20. + */ + public GuiToggleButton(int id, int x, int y, boolean initialState) { + super(id, x, y, FIXED_WIDTH, FIXED_HEIGHT, ""); + this.toggled = initialState; + this.animProgress = initialState ? 1.0f : 0.0f; + } + + /** + * Constructor with both an ON and OFF icon. + * The ON icon is taken from the super class’s icon. + */ + public GuiToggleButton(int id, int x, int y, boolean initialState, + ResourceLocation textureOn, ResourceLocation textureOff) { + super(id, x, y, FIXED_WIDTH, FIXED_HEIGHT, ""); + this.setIconTexture(textureOn); + this.toggled = initialState; + this.animProgress = initialState ? 1.0f : 0.0f; + this.textureOff = textureOff; + } + + // Off icon setters + public GuiToggleButton setTextureOff(ResourceLocation texture) { + this.textureOff = texture; + return this; + } + + public GuiToggleButton setTextureOffPos(int posX, int posY) { + this.textureOffPosX = posX; + this.textureOffPosY = posY; + return this; + } + + @Override + public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { + boolean pressed = super.mousePressed(mc, mouseX, mouseY); + if (pressed) { + toggled = !toggled; + } + return pressed; + } + + @Override + public void drawButton(Minecraft mc, int mouseX, int mouseY) { + if (!this.visible) + return; + + FontRenderer fontrenderer = mc.fontRenderer; + // Bind vanilla button texture. + mc.getTextureManager().bindTexture(buttonTextures); + GL11.glColor4f(1F, 1F, 1F, 1F); + + // Determine hover state (vanilla style) + this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition && + mouseX < this.xPosition + FIXED_WIDTH && mouseY < this.yPosition + FIXED_HEIGHT; + int k = this.getHoverState(this.field_146123_n); + + GL11.glEnable(GL11.GL_BLEND); + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + // Update animation progress smoothly toward the target state. + float target = toggled ? 1.0f : 0.0f; + animProgress += (target - animProgress) * 0.2f; + if (Math.abs(target - animProgress) < 0.01f) + animProgress = target; + + // Draw the two halves using the vanilla button drawing code. + // Left half: + GL11.glColor4f(1F, 1F, 1F, 1F); + this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + k * 20, FIXED_WIDTH / 2, FIXED_HEIGHT); + // Right half: + this.drawTexturedModalRect(this.xPosition + FIXED_WIDTH / 2, this.yPosition, 200 - FIXED_WIDTH / 2, 46 + k * 20, FIXED_WIDTH / 2, FIXED_HEIGHT); + + // Determine which half is the non-head (static background) area. + // When toggled ON, the knob (head) is on the right so non-head is the left half. + // When toggled OFF, the knob is on the left so non-head is the right half. + int nonHeadX, nonHeadWidth; + if (animProgress > 0.5f) { + // ON: knob on right, non-head = left half. + nonHeadX = this.xPosition; + nonHeadWidth = FIXED_WIDTH / 2; + } else { + // OFF: knob on left, non-head = right half. + nonHeadX = this.xPosition + FIXED_WIDTH / 2; + nonHeadWidth = FIXED_WIDTH / 2; + } + + // Tint the non-head area darker. + GL11.glColor4f(0.6f, 0.6f, 0.6f, 1.0F); + // Redraw that half to simulate a darker tone. + this.drawTexturedModalRect(nonHeadX, this.yPosition, 0, 46 + k * 20, nonHeadWidth, FIXED_HEIGHT); + + // Now draw the knob ("head") that slides. + // Knob width equals half of the button (20 pixels). + int knobWidth = FIXED_WIDTH / 2; + // The knob slides from xPosition (OFF) to xPosition + (FIXED_WIDTH - knobWidth) (ON). + int knobX = this.xPosition + (int)((FIXED_WIDTH - knobWidth) * animProgress); + int knobY = this.yPosition; + + // Draw the knob with no tint. + GL11.glColor4f(1F, 1F, 1F, 1F); + this.drawTexturedModalRect(knobX, knobY, 0, 46 + k * 20, knobWidth / 2, FIXED_HEIGHT); + this.drawTexturedModalRect(knobX + knobWidth / 2, knobY, 200 - knobWidth / 2, 46 + k * 20, knobWidth / 2, FIXED_HEIGHT); + + // Draw the icon on the knob (always 16×16, centered on the knob). + int iconX = knobX + (knobWidth - ICON_SIZE) / 2; + int iconY = knobY + (FIXED_HEIGHT - ICON_SIZE) / 2; + ResourceLocation iconTex; + int texX, texY; + // When ON, use the super class icon; when OFF, use textureOff if provided. + if (toggled) { + iconTex = this.iconTexture; + texX = this.iconPosX; + texY = this.iconPosY; + } else { + if (this.textureOff != null) { + iconTex = this.textureOff; + texX = this.textureOffPosX; + texY = this.textureOffPosY; + } else { + iconTex = this.iconTexture; + texX = this.iconPosX; + texY = this.iconPosY; + } + } + if (iconTex != null) { + mc.getTextureManager().bindTexture(iconTex); + GL11.glColor4f(1F, 1F, 1F, 1F); + this.drawTexturedModalRect(iconX, iconY, texX, texY, ICON_SIZE, ICON_SIZE); + } + + // Optionally, draw the centered display string (if needed). + int textColor = 14737632; + if (packedFGColour != 0) { + textColor = packedFGColour; + } else if (!this.enabled) { + textColor = 10526880; + } else if (this.field_146123_n) { + textColor = 16777120; + } + this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + FIXED_WIDTH / 2, + this.yPosition + (FIXED_HEIGHT - 8) / 2, textColor); + } +} diff --git a/src/main/java/noppes/npcs/client/gui/util/IPlayerDataInfo.java b/src/main/java/noppes/npcs/client/gui/util/IPlayerDataInfo.java new file mode 100644 index 000000000..c41b9b626 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/util/IPlayerDataInfo.java @@ -0,0 +1,11 @@ +package noppes.npcs.client.gui.util; + +import java.util.Map; + +public interface IPlayerDataInfo { + void setQuestData(Map questCategories, Map questActive, Map questFinished); + void setDialogData(Map dialogCategories, Map dialogRead); + void setTransportData(Map transportCategories, Map transportLocations); + void setBankData(Map bankData); + void setFactionData(Map factionData); +} diff --git a/src/main/java/noppes/npcs/client/gui/util/SubGuiNpcCooldownPicker.java b/src/main/java/noppes/npcs/client/gui/util/SubGuiNpcCooldownPicker.java new file mode 100644 index 000000000..35df31263 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/util/SubGuiNpcCooldownPicker.java @@ -0,0 +1,118 @@ +package noppes.npcs.client.gui.util; + +import net.minecraft.client.gui.GuiButton; + +public class SubGuiNpcCooldownPicker extends SubGuiInterface implements ITextfieldListener { + + private final boolean isMCCustom; + public long cooldownValue; + + private GuiNpcTextField daysField; + private GuiNpcTextField hoursField; + private GuiNpcTextField minutesField; + private GuiNpcTextField secondsField; + + public SubGuiNpcCooldownPicker(boolean isMCCustom, long currentCooldown) { + this.isMCCustom = isMCCustom; + this.cooldownValue = currentCooldown; + setBackground("smallbg.png"); + xSize = 220; + ySize = 222; + closeOnEsc = true; + } + + @Override + public void initGui() { + super.initGui(); + + int days = 0, hours = 0, minutes = 0, seconds = 0; + if(isMCCustom) { + long currentMillis = cooldownValue * 50; + days = (int)(currentMillis / 86400000L); + long remainder = currentMillis % 86400000L; + hours = (int)(remainder / 3600000L); + remainder %= 3600000L; + minutes = (int)(remainder / 60000L); + remainder %= 60000L; + seconds = (int)(remainder / 1000L); + } else { + // For RL custom cooldown, currentCooldown is stored in milliseconds. + days = (int)(cooldownValue / 86400000L); + long remainder = cooldownValue % 86400000L; + hours = (int)(remainder / 3600000L); + remainder %= 3600000L; + minutes = (int)(remainder / 60000L); + remainder %= 60000L; + seconds = (int)(remainder / 1000L); + } + + int y = guiTop + 20; + addLabel(new GuiNpcLabel(1, "mailbox.days", guiLeft + 10, y)); + daysField = new GuiNpcTextField(1, this, fontRendererObj, guiLeft + xSize - 110, y - 5, 40, 20, "" + days); + daysField.setIntegersOnly(); + daysField.setMinMaxDefault(0, Integer.MAX_VALUE, 0); + addTextField(daysField); + + y += 30; + + addLabel(new GuiNpcLabel(2, "mailbox.hours", guiLeft + 10, y)); + hoursField = new GuiNpcTextField(2, this, fontRendererObj, guiLeft + xSize - 110, y - 5, 40, 20, "" + hours); + hoursField.setIntegersOnly(); + hoursField.setMinMaxDefault(0, 24, 0); + addTextField(hoursField); + + y += 30; + + addLabel(new GuiNpcLabel(3, "mailbox.minutes", guiLeft + 10, y)); + minutesField = new GuiNpcTextField(3, this, fontRendererObj, guiLeft + xSize - 110, y - 5, 40, 20, "" + minutes); + minutesField.setIntegersOnly(); + minutesField.setMinMaxDefault(0, 60, 0); + addTextField(minutesField); + + y += 30; + + addLabel(new GuiNpcLabel(4, "mailbox.seconds", guiLeft + 10, y)); + secondsField = new GuiNpcTextField(4, this, fontRendererObj, guiLeft + xSize - 110, y - 5, 40, 20, "" + seconds); + secondsField.setIntegersOnly(); + secondsField.setMinMaxDefault(0, 60, 0); + addTextField(secondsField); + + addButton(new GuiNpcButton(0, guiLeft + 10, guiTop + ySize - 30, 80, 20, "gui.done")); + } + + @Override + public void buttonEvent(GuiButton button) { + if(button.id == 0) { + close(); + } + } + + public void close(){ + int inputDays = parseInt(daysField.getText()); + int inputHours = parseInt(hoursField.getText()); + int inputMinutes = parseInt(minutesField.getText()); + int inputSeconds = parseInt(secondsField.getText()); + // Calculate total time in milliseconds. + long totalMillis = inputDays * 86400000L + inputHours * 3600000L + inputMinutes * 60000L + inputSeconds * 1000L; + if(isMCCustom) { + // Convert real milliseconds to ticks. + cooldownValue = totalMillis / 50; + } else { + cooldownValue = totalMillis; + } + super.close(); + } + + @Override + public void unFocused(GuiNpcTextField textField) { + // No immediate action needed on unfocus. + } + + private int parseInt(String text) { + try { + return Integer.parseInt(text); + } catch(Exception e) { + return 0; + } + } +} diff --git a/src/main/java/noppes/npcs/client/model/blocks/barrel/ModelBarrel.java b/src/main/java/noppes/npcs/client/model/blocks/barrel/ModelBarrel.java index 6c1a2692f..c8506d465 100644 --- a/src/main/java/noppes/npcs/client/model/blocks/barrel/ModelBarrel.java +++ b/src/main/java/noppes/npcs/client/model/blocks/barrel/ModelBarrel.java @@ -3,7 +3,6 @@ package noppes.npcs.client.model.blocks.barrel; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBox; import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; public class ModelBarrel extends ModelBase { private final ModelRenderer Wall; diff --git a/src/main/java/noppes/npcs/client/model/util/Model2DRenderer.java b/src/main/java/noppes/npcs/client/model/util/Model2DRenderer.java index fdf31d224..62038fa9f 100644 --- a/src/main/java/noppes/npcs/client/model/util/Model2DRenderer.java +++ b/src/main/java/noppes/npcs/client/model/util/Model2DRenderer.java @@ -5,7 +5,6 @@ import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.renderer.GLAllocation; -import net.minecraft.client.renderer.ItemRenderer; import net.minecraft.client.renderer.Tessellator; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/noppes/npcs/client/renderer/RenderCNPCPlayer.java b/src/main/java/noppes/npcs/client/renderer/RenderCNPCPlayer.java index 82da923bb..9ccd98016 100644 --- a/src/main/java/noppes/npcs/client/renderer/RenderCNPCPlayer.java +++ b/src/main/java/noppes/npcs/client/renderer/RenderCNPCPlayer.java @@ -19,7 +19,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.MathHelper; import net.minecraftforge.client.event.RenderPlayerEvent; import noppes.npcs.client.ClientCacheHandler; -import noppes.npcs.client.model.ModelMPM; import noppes.npcs.controllers.data.SkinOverlay; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.Project; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockBannerRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockBannerRenderer.java index 56c7aec7c..b8e4beb58 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockBannerRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockBannerRenderer.java @@ -6,6 +6,7 @@ import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.item.ItemStack; @@ -14,14 +15,19 @@ import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import noppes.npcs.CustomItems; +import noppes.npcs.api.item.IItemCustomizable; +import noppes.npcs.api.item.IItemStack; import noppes.npcs.blocks.BlockBanner; import noppes.npcs.blocks.tiles.TileBanner; +import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.client.model.blocks.banner.ModelBannerFloor; import noppes.npcs.client.model.blocks.banner.ModelBannerFloorFlag; import noppes.npcs.client.model.blocks.legacy.ModelLegacyBanner; import noppes.npcs.client.model.blocks.legacy.ModelLegacyBannerFlag; +import noppes.npcs.client.renderer.ImageData; import noppes.npcs.config.ConfigClient; import noppes.npcs.constants.EnumBannerVariant; +import noppes.npcs.scripted.NpcAPI; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; @@ -129,11 +135,44 @@ public class BlockBannerRenderer extends BlockRendererInterface{ float f2 = 0.05f; Minecraft mc = Minecraft.getMinecraft(); GL11.glScalef(f2, f2, f2); - renderItemBanner(mc.renderEngine, iicon, -8, -8, false); + IItemStack iItemStack = NpcAPI.Instance().getIItemStack(iicon); + if (iItemStack instanceof IItemCustomizable) { + IItemCustomizable custom = (IItemCustomizable) iItemStack; + ImageData imageData = ClientCacheHandler.getImageData(custom.getTexture()); + if (imageData.imageLoaded()) { + imageData.bindTexture(); + int color = custom.getColor(); + float[] colors = ColorUtil.hexToRGB(color); + renderCustomItemInBanner(colors[0], colors[1], colors[2]); + GL11.glColor3f(1.0f, 1.0f, 1.0f); + } else { + renderItemBanner(mc.renderEngine, iicon, -8, -8, false); + } + } else { + renderItemBanner(mc.renderEngine, iicon, -8, -8, false); + } GL11.glDepthMask(true); GL11.glPopMatrix(); } + private void renderCustomItemInBanner(float red, float green, float blue) { + // Ensure lighting isn't interfering + GL11.glDisable(GL11.GL_LIGHTING); + // Force the texture to use the current color + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_F(red, green, blue, 1.0F); + tessellator.addVertexWithUV(-8, 8, 0, 0, 1); + tessellator.addVertexWithUV(8, 8, 0, 1, 1); + tessellator.addVertexWithUV(8, -8, 0, 1, 0); + tessellator.addVertexWithUV(-8, -8, 0, 0, 0); + tessellator.draw(); + + GL11.glEnable(GL11.GL_LIGHTING); + } + public void renderItemBanner(TextureManager txtMng, ItemStack item, int p_77015_4_, int p_77015_5_, boolean renderEffect) { Object object = item.getIconIndex(); diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockBeamRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockBeamRenderer.java index b734a48dd..60e9b5d3c 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockBeamRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockBeamRenderer.java @@ -7,8 +7,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import noppes.npcs.CustomItems; import noppes.npcs.blocks.BlockRotated; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileShelf; +import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.client.model.blocks.ModelBeam; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockCarpentryBenchRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockCarpentryBenchRenderer.java index 3b0c40a03..49c61c0b6 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockCarpentryBenchRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockCarpentryBenchRenderer.java @@ -11,10 +11,9 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.world.IBlockAccess; import noppes.npcs.CustomItems; import noppes.npcs.blocks.BlockCarpentryBench; -import noppes.npcs.blocks.tiles.TileBlockAnvil; import noppes.npcs.client.model.blocks.ModelAnvil; -import noppes.npcs.client.model.blocks.legacy.ModelLegacyAnvil; import noppes.npcs.client.model.blocks.ModelCarpentryBench; +import noppes.npcs.client.model.blocks.legacy.ModelLegacyAnvil; import noppes.npcs.client.model.blocks.legacy.ModelLegacyCarpentryBench; import noppes.npcs.config.ConfigClient; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockChairRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockChairRenderer.java index bd915dfc9..b7dd1b738 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockChairRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockChairRenderer.java @@ -42,8 +42,8 @@ public class BlockChairRenderer extends BlockRendererInterface{ GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glPushMatrix(); - GL11.glTranslatef((float)var2 + 0.5f, (float)var4 + 1.65f, (float)var6 + 0.5f); - GL11.glScalef(1.2f, 1.1f, 1.2f); + GL11.glTranslatef((float)var2 + 0.5f, (float)var4 + 1.5f, (float)var6 + 0.5f); + // GL11.glScalef(1.2f, 1.1f, 1.2f); GL11.glRotatef(180, 0, 0, 1); GL11.glRotatef(90 * tile.rotation, 0, 1, 0); GL11.glColor3f(1, 1, 1); diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockLanternRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockLanternRenderer.java index 842f71a1b..57e4da380 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockLanternRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockLanternRenderer.java @@ -15,8 +15,8 @@ import noppes.npcs.blocks.tiles.TileLamp; import noppes.npcs.client.model.blocks.lantern.LanternCeiling; import noppes.npcs.client.model.blocks.lantern.LanternFloor; import noppes.npcs.client.model.blocks.lantern.LanternWall; -import noppes.npcs.client.model.blocks.legacy.ModelLegacyLantern; import noppes.npcs.client.model.blocks.legacy.ModelLegacyCeiling; +import noppes.npcs.client.model.blocks.legacy.ModelLegacyLantern; import noppes.npcs.client.model.blocks.legacy.ModelLegacyWall; import noppes.npcs.config.ConfigClient; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java index 4148da831..c6a48e3bc 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java @@ -4,7 +4,10 @@ import cpw.mods.fml.client.registry.RenderingRegistry; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.ItemBlock; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockShelfRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockShelfRenderer.java index 8e29769a6..ef4cd98db 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockShelfRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockShelfRenderer.java @@ -7,8 +7,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import noppes.npcs.CustomItems; import noppes.npcs.blocks.BlockRotated; -import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.blocks.tiles.TileShelf; +import noppes.npcs.blocks.tiles.TileVariant; import noppes.npcs.client.model.blocks.ModelShelf; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockWallBannerRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockWallBannerRenderer.java index b578fb8b2..945775a0f 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockWallBannerRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockWallBannerRenderer.java @@ -6,22 +6,31 @@ import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.init.Blocks; -import net.minecraft.item.*; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import noppes.npcs.CustomItems; +import noppes.npcs.api.item.IItemCustomizable; +import noppes.npcs.api.item.IItemStack; import noppes.npcs.blocks.BlockWallBanner; import noppes.npcs.blocks.tiles.TileWallBanner; +import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.client.model.blocks.banner.ModelBannerWall; import noppes.npcs.client.model.blocks.banner.ModelBannerWallFlag; import noppes.npcs.client.model.blocks.legacy.ModelLegacyWallBanner; import noppes.npcs.client.model.blocks.legacy.ModelLegacyWallBannerFlag; +import noppes.npcs.client.renderer.ImageData; import noppes.npcs.config.ConfigClient; +import noppes.npcs.scripted.NpcAPI; +import noppes.npcs.scripted.item.ScriptItemStack; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; @@ -93,34 +102,68 @@ public class BlockWallBannerRenderer extends BlockRendererInterface{ } GL11.glPopAttrib(); } - public void doRender(double par2, double par4, double par6, int meta, ItemStack iicon, float rotate) - { + + public void doRender(double par2, double par4, double par6, int meta, ItemStack iicon, float rotate) { GL11.glPushMatrix(); bindTexture(TextureMap.locationItemsTexture); GL11.glTranslatef((float)par2 + 0.5f, (float)par4 + 0.2f, (float)par6 + 0.5f); GL11.glRotatef(180, 0, 0, 1); GL11.glRotatef(90 * meta, 0, 1, 0); - - if(ConfigClient.LegacyBanner){ + if (ConfigClient.LegacyBanner) { GL11.glTranslatef(0, 0, 0.26f); - } - else { + } else { GL11.glTranslatef(0, 0, 0.3f); GL11.glTranslatef(0, -0.6f, 0); // Translate to pivot point GL11.glRotatef((float) Math.toDegrees(rotate), 1, 0, 0); // Apply sway rotation GL11.glTranslatef(0, 0.6f, 0); // Translate to pivot point } - GL11.glDepthMask(false); float f2 = 0.05f; Minecraft mc = Minecraft.getMinecraft(); GL11.glScalef(f2, f2, f2); - renderItemBanner(mc.renderEngine, iicon, -8, -8, false); + + // Check if the item is customizable. + IItemStack iItemStack = NpcAPI.Instance().getIItemStack(iicon); + if (iItemStack instanceof IItemCustomizable) { + IItemCustomizable custom = (IItemCustomizable) iItemStack; + ImageData imageData = ClientCacheHandler.getImageData(custom.getTexture()); + if (imageData.imageLoaded()) { + imageData.bindTexture(); + int color = custom.getColor(); + float[] colors = ColorUtil.hexToRGB(color); + renderCustomItemInBanner(colors[0], colors[1], colors[2]); + GL11.glColor3f(1.0f, 1.0f, 1.0f); + } else { + renderItemBanner(mc.renderEngine, iicon, -8, -8, false); + } + } else { + renderItemBanner(mc.renderEngine, iicon, -8, -8, false); + } + GL11.glDepthMask(true); GL11.glPopMatrix(); } + private void renderCustomItemInBanner(float red, float green, float blue) { + // Ensure lighting isn't interfering + GL11.glDisable(GL11.GL_LIGHTING); + // Force the texture to use the current color + GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_F(red, green, blue, 1.0F); + tessellator.addVertexWithUV(-8, 8, 0, 0, 1); + tessellator.addVertexWithUV(8, 8, 0, 1, 1); + tessellator.addVertexWithUV(8, -8, 0, 1, 0); + tessellator.addVertexWithUV(-8, -8, 0, 0, 0); + tessellator.draw(); + + GL11.glEnable(GL11.GL_LIGHTING); + } + + public void renderItemBanner(TextureManager txtMng, ItemStack item, int p_77015_4_, int p_77015_5_, boolean renderEffect) { Object object = item.getIconIndex(); diff --git a/src/main/java/noppes/npcs/client/renderer/items/ItemBannerRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/ItemBannerRenderer.java index dad55ad1f..c64393181 100644 --- a/src/main/java/noppes/npcs/client/renderer/items/ItemBannerRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/items/ItemBannerRenderer.java @@ -6,7 +6,6 @@ import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.item.ItemStack; import net.minecraftforge.client.IItemRenderer; import noppes.npcs.client.renderer.blocks.BlockBannerRenderer; -import noppes.npcs.client.renderer.blocks.BlockShortLampRenderer; import noppes.npcs.config.ConfigClient; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/noppes/npcs/client/renderer/items/ItemCouchWoolRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/ItemCouchWoolRenderer.java index 928916bae..481dcc4ef 100644 --- a/src/main/java/noppes/npcs/client/renderer/items/ItemCouchWoolRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/items/ItemCouchWoolRenderer.java @@ -1,15 +1,15 @@ package noppes.npcs.client.renderer.items; +import kamkeel.npcs.util.ColorUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.item.ItemStack; import net.minecraftforge.client.IItemRenderer; import noppes.npcs.client.renderer.blocks.BlockCouchWoolRenderer; import noppes.npcs.client.renderer.blocks.BlockRendererInterface; -import org.lwjgl.opengl.GL11; import noppes.npcs.client.renderer.blocks.BlockTallLampRenderer; import noppes.npcs.config.ConfigClient; -import kamkeel.npcs.util.ColorUtil; +import org.lwjgl.opengl.GL11; public class ItemCouchWoolRenderer implements IItemRenderer { diff --git a/src/main/java/noppes/npcs/client/renderer/items/CustomItemRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/ItemCustomRenderer.java similarity index 99% rename from src/main/java/noppes/npcs/client/renderer/items/CustomItemRenderer.java rename to src/main/java/noppes/npcs/client/renderer/items/ItemCustomRenderer.java index 44465218b..9c16b4d4d 100644 --- a/src/main/java/noppes/npcs/client/renderer/items/CustomItemRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/items/ItemCustomRenderer.java @@ -27,7 +27,7 @@ import java.util.Random; import static net.minecraft.client.renderer.entity.RenderItem.renderInFrame; -public class CustomItemRenderer implements IItemRenderer { +public class ItemCustomRenderer implements IItemRenderer { private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); private static final ResourceLocation enchant = new ResourceLocation("textures/misc/enchanted_item_glint.png"); private final Random random = new Random(); diff --git a/src/main/java/noppes/npcs/client/renderer/items/ItemShortLampRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/ItemShortLampRenderer.java index aaa98ab1c..b413c722f 100644 --- a/src/main/java/noppes/npcs/client/renderer/items/ItemShortLampRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/items/ItemShortLampRenderer.java @@ -1,14 +1,9 @@ package noppes.npcs.client.renderer.items; import kamkeel.npcs.util.ColorUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.item.ItemStack; import net.minecraftforge.client.IItemRenderer; -import noppes.npcs.client.renderer.blocks.BlockRendererInterface; import noppes.npcs.client.renderer.blocks.BlockShortLampRenderer; -import noppes.npcs.client.renderer.blocks.BlockTallLampRenderer; -import noppes.npcs.config.ConfigClient; import org.lwjgl.opengl.GL11; public class ItemShortLampRenderer implements IItemRenderer { diff --git a/src/main/java/noppes/npcs/client/renderer/items/ItemTallLampRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/ItemTallLampRenderer.java index 5ce2cfac1..2b891aa1a 100644 --- a/src/main/java/noppes/npcs/client/renderer/items/ItemTallLampRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/items/ItemTallLampRenderer.java @@ -5,7 +5,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.item.ItemStack; import net.minecraftforge.client.IItemRenderer; -import noppes.npcs.client.renderer.blocks.BlockCouchWoolRenderer; import noppes.npcs.client.renderer.blocks.BlockRendererInterface; import noppes.npcs.client.renderer.blocks.BlockTallLampRenderer; import noppes.npcs.config.ConfigClient; diff --git a/src/main/java/noppes/npcs/client/renderer/items/ItemToolRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/ItemToolRenderer.java new file mode 100644 index 000000000..6cf9aac84 --- /dev/null +++ b/src/main/java/noppes/npcs/client/renderer/items/ItemToolRenderer.java @@ -0,0 +1,544 @@ +package noppes.npcs.client.renderer.items; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; +import noppes.npcs.items.ItemNpcTool; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import java.util.Random; + +import static net.minecraft.client.renderer.entity.RenderItem.renderInFrame; + +public class ItemToolRenderer implements IItemRenderer { + + private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + private static final ResourceLocation PAINTBRUSH_HANDLE = new ResourceLocation("customnpcs", "textures/items/npcBrushHandle.png"); + private static final ResourceLocation PAINTBRUSH_BRUSH = new ResourceLocation("customnpcs", "textures/items/npcBrushHair.png"); + + private static final ResourceLocation HAMMER = new ResourceLocation("customnpcs", "textures/items/npcHammer.png"); + + private final Random random = new Random(); + + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + return type != ItemRenderType.FIRST_PERSON_MAP; + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + return helper == ItemRendererHelper.ENTITY_ROTATION || helper == ItemRendererHelper.ENTITY_BOBBING; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack itemStack, Object... data) { + if (itemStack == null || !(itemStack.getItem() instanceof ItemNpcTool)) { + return; + } + + if (type == ItemRenderType.INVENTORY) { + GL11.glPushMatrix(); + renderInventoryCustomItem(itemStack); + GL11.glPopMatrix(); + return; + } + if (type == ItemRenderType.ENTITY) { + GL11.glPushMatrix(); + EntityItem entityItem = (EntityItem) data[1]; + if (!entityItem.ignoreFrustumCheck) { + entityItem.ignoreFrustumCheck = true; + + float entityXZSize = (float) Math.sqrt(Math.pow(1,2) + Math.pow(1,2)); + this.setEntitySize(entityItem, entityXZSize * 0.25F, 1 * 0.25F); + + double XSize = entityItem.boundingBox.maxX - entityItem.boundingBox.minX; + double YSize = entityItem.boundingBox.maxY - entityItem.boundingBox.minY; + double ZSize = entityItem.boundingBox.maxZ - entityItem.boundingBox.minZ; + entityItem.boundingBox.maxX = entityItem.boundingBox.minX + XSize * 1; + entityItem.boundingBox.maxY = entityItem.boundingBox.minY + YSize * 1; + entityItem.boundingBox.maxZ = entityItem.boundingBox.minZ + ZSize * 1; + } + if(itemStack.getItemDamage() == 1){ + renderEntityCustomItem(itemStack, entityItem, PAINTBRUSH_HANDLE); + int color = ItemNpcTool.getColor(itemStack.getTagCompound()); + float red = ((color >> 16) & 0xFF) / 255.0F; + float green = ((color >> 8) & 0xFF) / 255.0F; + float blue = (color & 0xFF) / 255.0F; + GL11.glColor3f(red, green, blue); + renderEntityCustomItem(itemStack, entityItem, PAINTBRUSH_BRUSH); + } else { + renderEntityCustomItem(itemStack, entityItem, HAMMER); + } + GL11.glPopMatrix(); + return; + } + GL11.glPushMatrix(); + + GL11.glTranslatef(0.9375F, 0.0625F, 0.0F); + GL11.glRotatef(-315.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.135F * 1, 0.2F * 1, 0.07F * 1); + + GL11.glScalef(1, 1, 1); + GL11.glRotatef(-20.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(-0.09375F, 0.0625F, 0.0F); + + + EntityLivingBase entityLivingBase = (EntityLivingBase) data[1]; + + if(itemStack.getItemDamage() == 1){ + GL11.glPushMatrix(); + renderItem3d(entityLivingBase, itemStack, PAINTBRUSH_HANDLE); + GL11.glPopMatrix(); + + int color = ItemNpcTool.getColor(itemStack.getTagCompound()); + float red = ((color >> 16) & 0xFF) / 255.0F; + float green = ((color >> 8) & 0xFF) / 255.0F; + float blue = (color & 0xFF) / 255.0F; + GL11.glColor3f(red, green, blue); + + GL11.glPushMatrix(); + renderItem3d(entityLivingBase, itemStack, PAINTBRUSH_BRUSH); + GL11.glPopMatrix(); + } else { + GL11.glPushMatrix(); + renderItem3d(entityLivingBase, itemStack, HAMMER); + GL11.glPopMatrix(); + } + + GL11.glPopMatrix(); + } + + private void setEntitySize(EntityItem entityItem, float p_70105_1_, float p_70105_2_) + { + float f2; + + if (p_70105_1_ != entityItem.width || p_70105_2_ != entityItem.height) + { + f2 = entityItem.width; + entityItem.width = p_70105_1_; + entityItem.height = p_70105_2_; + entityItem.boundingBox.maxX = entityItem.boundingBox.minX + (double)entityItem.width; + entityItem.boundingBox.maxZ = entityItem.boundingBox.minZ + (double)entityItem.width; + entityItem.boundingBox.maxY = entityItem.boundingBox.minY + (double)entityItem.height; + + if (entityItem.width > f2 && !entityItem.firstUpdate && !entityItem.worldObj.isRemote) + { + entityItem.moveEntity((double)(f2 - entityItem.width), 0.0D, (double)(f2 - entityItem.width)); + } + } + + f2 = p_70105_1_ % 2.0F; + + if ((double)f2 < 0.375D) + { + entityItem.myEntitySize = Entity.EnumEntitySize.SIZE_1; + } + else if ((double)f2 < 0.75D) + { + entityItem.myEntitySize = Entity.EnumEntitySize.SIZE_2; + } + else if ((double)f2 < 1.0D) + { + entityItem.myEntitySize = Entity.EnumEntitySize.SIZE_3; + } + else if ((double)f2 < 1.375D) + { + entityItem.myEntitySize = Entity.EnumEntitySize.SIZE_4; + } + else if ((double)f2 < 1.75D) + { + entityItem.myEntitySize = Entity.EnumEntitySize.SIZE_5; + } + else + { + entityItem.myEntitySize = Entity.EnumEntitySize.SIZE_6; + } + } + + public void renderEntityCustomItem(ItemStack itemStack, EntityItem entityItem, ResourceLocation location) { + int pass = 0; + + GL11.glPushMatrix(); + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); + textureManager.bindTexture(location); + + if (renderInFrame) + { + GL11.glTranslatef(0.0F, -0.05F, 0.0F); + GL11.glScalef(1.025641F,1.025641F,1.025641F); + GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + } + + Tessellator tessellator = Tessellator.instance; + + float f14 = 0.0F; + float f15 = 1.0F; + float f4 = 0.0F; + float f5 = 1.0F; + float f6 = 1.0F; + float f7 = 0.5F; + float f8 = 0.25F; + float f10; + + if (RenderManager.instance.options.fancyGraphics) + { + GL11.glPushMatrix(); + + float f9 = 0.0625F; + f10 = 0.021875F; + int j = itemStack.stackSize; + byte b0; + + if (j < 2) + { + b0 = 1; + } + else if (j < 16) + { + b0 = 2; + } + else if (j < 32) + { + b0 = 3; + } + else + { + b0 = 4; + } + + GL11.glTranslatef(-f7, -f8, -((f9 + f10) * (float)b0 / 2.0F)); + + for (int k = 0; k < b0; ++k) + { + GL11.glTranslatef(0f, 0f, f9 + f10); + ItemRenderer.renderItemIn2D(tessellator, 1.0F, 0.0F, 0.0F, 1.0F, 16, 16, f9); + if (itemStack.hasEffect(pass)) + { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + RenderManager.instance.renderEngine.bindTexture(RES_ITEM_GLINT); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f11 = 0.76F; + GL11.glColor4f(0.5F * f11, 0.25F * f11, 0.8F * f11, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glPushMatrix(); + float f12 = 0.125F; + GL11.glScalef(f12, f12, f12); + float f13 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; + GL11.glTranslatef(f13, 0.0F, 0.0F); + GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 255, 255, f9); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f12, f12, f12); + f13 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; + GL11.glTranslatef(-f13, 0.0F, 0.0F); + GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 255, 255, f9); + GL11.glPopMatrix(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + } + + GL11.glPopMatrix(); + } + else + { + int j = itemStack.stackSize; + int b0; + + if (j < 2) + { + b0 = 1; + } + else if (j < 16) + { + b0 = 2; + } + else if (j < 32) + { + b0 = 3; + } + else + { + b0 = 4; + } + + for (int l = 0; l < b0; ++l) + { + GL11.glPushMatrix(); + + if (l > 0) + { + f10 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.3F; + float f16 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.3F; + float f17 = (this.random.nextFloat() * 2.0F - 1.0F) * 0.3F; + GL11.glTranslatef(f10, f16, f17); + } + + if (!renderInFrame) + { + GL11.glRotatef(180.0F - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + } + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.0D, (double)f14, (double)f5); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.0D, (double)f15, (double)f5); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.0D, (double)f15, (double)f4); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.0D, (double)f14, (double)f4); + tessellator.draw(); + GL11.glPopMatrix(); + } + } + GL11.glPopMatrix(); + } + + public void renderInventoryCustomItem(ItemStack itemStack) { + GL11.glPushMatrix(); + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); + + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_ALPHA_TEST); + + if(itemStack.getItemDamage() == 1){ + textureManager.bindTexture(PAINTBRUSH_HANDLE); + renderCustomItemSlot(0,0,16,16, 1.0f, 1.0f, 1.0f); + + int color = ItemNpcTool.getColor(itemStack.getTagCompound()); + float red = ((color >> 16) & 0xFF) / 255.0F; + float green = ((color >> 8) & 0xFF) / 255.0F; + float blue = (color & 0xFF) / 255.0F; + textureManager.bindTexture(PAINTBRUSH_BRUSH); + renderCustomItemSlot(0,0,16,16, red, green, blue); + } else { + textureManager.bindTexture(HAMMER); + renderCustomItemSlot(0,0,16,16, 1.0f, 1.0f, 1.0f); + } + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_ALPHA_TEST); + + if (itemStack.hasEffect(0)) + { + renderEffect(Minecraft.getMinecraft().getTextureManager(), 0, 0); + } + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + } + + public void renderEffect(TextureManager manager, int x, int y) + { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDepthMask(false); + manager.bindTexture(RES_ITEM_GLINT); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_BLEND); + GL11.glColor4f(0.5F, 0.25F, 0.8F, 1.0F); + this.renderGlint(x - 2, y - 2, 20, 20); + GL11.glDepthMask(true); + GL11.glDisable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + private void renderGlint(int p_77018_2_, int p_77018_3_, int p_77018_4_, int p_77018_5_) + { + for (int j1 = 0; j1 < 2; ++j1) + { + OpenGlHelper.glBlendFunc(772, 1, 0, 0); + float f = 0.00390625F; + float f1 = 0.00390625F; + float f2 = (float)(Minecraft.getSystemTime() % (long)(3000 + j1 * 1873)) / (3000.0F + (float)(j1 * 1873)) * 256.0F; + float f3 = 0.0F; + Tessellator tessellator = Tessellator.instance; + float f4 = 4.0F; + + if (j1 == 1) + { + f4 = -1.0F; + } + + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(p_77018_2_ + 0), (double)(p_77018_3_ + p_77018_5_), 0, (double)((f2 + (float)p_77018_5_ * f4) * f), (double)((f3 + (float)p_77018_5_) * f1)); + tessellator.addVertexWithUV((double)(p_77018_2_ + p_77018_4_), (double)(p_77018_3_ + p_77018_5_), 0, (double)((f2 + (float)p_77018_4_ + (float)p_77018_5_ * f4) * f), (double)((f3 + (float)p_77018_5_) * f1)); + tessellator.addVertexWithUV((double)(p_77018_2_ + p_77018_4_), (double)(p_77018_3_ + 0), 0, (double)((f2 + (float)p_77018_4_) * f), (double)((f3 + 0.0F) * f1)); + tessellator.addVertexWithUV((double)(p_77018_2_ + 0), (double)(p_77018_3_ + 0), 0, (double)((f2 + 0.0F) * f), (double)((f3 + 0.0F) * f1)); + tessellator.draw(); + } + } + + public void renderCustomItemSlot(int posX, int posY, int imageWidth, int imageHeight, float itemRed, float itemGreen, float itemBlue) { + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_F(itemRed, itemGreen, itemBlue, 1.0F); + tessellator.addVertexWithUV((double)(posX), (double)(posY + imageHeight), 0, 0, 1); + tessellator.addVertexWithUV((double)(posX + imageWidth), (double)(posY + imageHeight), 0, 1, 1); + tessellator.addVertexWithUV((double)(posX + imageWidth), (double)(posY), 0, 1, 0); + tessellator.addVertexWithUV((double)(posX), (double)(posY), 0, 0, 0); + tessellator.draw(); + } + + public void renderItem3d(EntityLivingBase entityLivingBase, ItemStack itemStack, ResourceLocation location) { + Minecraft mc = Minecraft.getMinecraft(); + TextureManager texturemanager = mc.getTextureManager(); + int par3 = 0; + + texturemanager.bindTexture(location); + + Tessellator tessellator = Tessellator.instance; + IIcon icon = entityLivingBase.getItemIcon(itemStack, par3); + + if (icon == null) { + return; + } + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + + float f4 = 0.0F; + float f5 = 0.3F; + GL11.glTranslatef(-f4, -f5, 0.0F); + GL11.glRotatef(50.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(335.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.9375F, -0.0625F, 0.0F); + + renderCustomItemIn2D(tessellator, 1.0F, 0.0F, 0.0F, 1.0F, 0.0625F); + + if (itemStack.hasEffect(par3)) { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + texturemanager.bindTexture(RES_ITEM_GLINT); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glPushMatrix(); + float f8 = 0.125F; + GL11.glScalef(f8, f8, f8); + float f9 = (float) (Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; + GL11.glTranslatef(f9, 0.0F, 0.0F); + GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f8, f8, f8); + f9 = (float) (Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; + GL11.glTranslatef(-f9, 0.0F, 0.0F); + GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + } + + public static void renderCustomItemIn2D(Tessellator p_78439_0_, float p_78439_1_, float p_78439_2_, float p_78439_3_, float p_78439_4_, float p_78439_7_) + { + int width = 16; + int height = 16; + + p_78439_0_.startDrawingQuads(); + p_78439_0_.setNormal(0.0F, 0.0F, 1.0F); + p_78439_0_.addVertexWithUV(0.0D, 0.0D, 0.0D, (double)p_78439_1_, (double)p_78439_4_); + p_78439_0_.addVertexWithUV(1.0D, 0.0D, 0.0D, (double)p_78439_3_, (double)p_78439_4_); + p_78439_0_.addVertexWithUV(1.0D, 1.0D, 0.0D, (double)p_78439_3_, (double)p_78439_2_); + p_78439_0_.addVertexWithUV(0.0D, 1.0D, 0.0D, (double)p_78439_1_, (double)p_78439_2_); + p_78439_0_.draw(); + p_78439_0_.startDrawingQuads(); + p_78439_0_.setNormal(0.0F, 0.0F, -1.0F); + p_78439_0_.addVertexWithUV(0.0D, 1.0D, (double)(0.0F - p_78439_7_), (double)p_78439_1_, (double)p_78439_2_); + p_78439_0_.addVertexWithUV(1.0D, 1.0D, (double)(0.0F - p_78439_7_), (double)p_78439_3_, (double)p_78439_2_); + p_78439_0_.addVertexWithUV(1.0D, 0.0D, (double)(0.0F - p_78439_7_), (double)p_78439_3_, (double)p_78439_4_); + p_78439_0_.addVertexWithUV(0.0D, 0.0D, (double)(0.0F - p_78439_7_), (double)p_78439_1_, (double)p_78439_4_); + p_78439_0_.draw(); + float f5 = 0.5F * (p_78439_1_ - p_78439_3_) / (float)width; + float f6 = 0.5F * (p_78439_4_ - p_78439_2_) / (float)height; + p_78439_0_.startDrawingQuads(); + p_78439_0_.setNormal(-1.0F, 0.0F, 0.0F); + int k; + float f7; + float f8; + + for (k = 0; k < width; ++k) + { + f7 = (float)k / (float)width; + f8 = p_78439_1_ + (p_78439_3_ - p_78439_1_) * f7 - f5; + p_78439_0_.addVertexWithUV((double)f7, 0.0D, (double)(0.0F - p_78439_7_), (double)f8, (double)p_78439_4_); + p_78439_0_.addVertexWithUV((double)f7, 0.0D, 0.0D, (double)f8, (double)p_78439_4_); + p_78439_0_.addVertexWithUV((double)f7, 1.0D, 0.0D, (double)f8, (double)p_78439_2_); + p_78439_0_.addVertexWithUV((double)f7, 1.0D, (double)(0.0F - p_78439_7_), (double)f8, (double)p_78439_2_); + } + + p_78439_0_.draw(); + p_78439_0_.startDrawingQuads(); + p_78439_0_.setNormal(1.0F, 0.0F, 0.0F); + float f9; + + for (k = 0; k < width; ++k) + { + f7 = (float)k / (float)width; + f8 = p_78439_1_ + (p_78439_3_ - p_78439_1_) * f7 - f5; + f9 = f7 + 1.0F / (float)width; + p_78439_0_.addVertexWithUV((double)f9, 1.0D, (double)(0.0F - p_78439_7_), (double)f8, (double)p_78439_2_); + p_78439_0_.addVertexWithUV((double)f9, 1.0D, 0.0D, (double)f8, (double)p_78439_2_); + p_78439_0_.addVertexWithUV((double)f9, 0.0D, 0.0D, (double)f8, (double)p_78439_4_); + p_78439_0_.addVertexWithUV((double)f9, 0.0D, (double)(0.0F - p_78439_7_), (double)f8, (double)p_78439_4_); + } + + p_78439_0_.draw(); + p_78439_0_.startDrawingQuads(); + p_78439_0_.setNormal(0.0F, 1.0F, 0.0F); + + for (k = 0; k < height; ++k) + { + f7 = (float)k / (float)height; + f8 = p_78439_4_ + (p_78439_2_ - p_78439_4_) * f7 - f6; + f9 = f7 + 1.0F / (float)height; + p_78439_0_.addVertexWithUV(0.0D, (double)f9, 0.0D, (double)p_78439_1_, (double)f8); + p_78439_0_.addVertexWithUV(1.0D, (double)f9, 0.0D, (double)p_78439_3_, (double)f8); + p_78439_0_.addVertexWithUV(1.0D, (double)f9, (double)(0.0F - p_78439_7_), (double)p_78439_3_, (double)f8); + p_78439_0_.addVertexWithUV(0.0D, (double)f9, (double)(0.0F - p_78439_7_), (double)p_78439_1_, (double)f8); + } + + p_78439_0_.draw(); + p_78439_0_.startDrawingQuads(); + p_78439_0_.setNormal(0.0F, -1.0F, 0.0F); + + for (k = 0; k < height; ++k) + { + f7 = (float)k / (float)height; + f8 = p_78439_4_ + (p_78439_2_ - p_78439_4_) * f7 - f6; + p_78439_0_.addVertexWithUV(1.0D, (double)f7, 0.0D, (double)p_78439_3_, (double)f8); + p_78439_0_.addVertexWithUV(0.0D, (double)f7, 0.0D, (double)p_78439_1_, (double)f8); + p_78439_0_.addVertexWithUV(0.0D, (double)f7, (double)(0.0F - p_78439_7_), (double)p_78439_1_, (double)f8); + p_78439_0_.addVertexWithUV(1.0D, (double)f7, (double)(0.0F - p_78439_7_), (double)p_78439_3_, (double)f8); + } + + p_78439_0_.draw(); + } +} diff --git a/src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java deleted file mode 100644 index 9b7a85885..000000000 --- a/src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java +++ /dev/null @@ -1,154 +0,0 @@ -package noppes.npcs.client.renderer.items; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.IItemRenderer; -import noppes.npcs.items.ItemNpcTool; -import noppes.npcs.items.ItemRenderInterface; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; - -import static noppes.npcs.items.ItemNpcTool.BRUSH_COLOR_TAG; - -public class NpcItemToolRenderer implements IItemRenderer { - - // Textures for the assembled paintbrush parts: - private static final ResourceLocation PAINTBRUSH_HANDLE = new ResourceLocation("customnpcs", "textures/items/paintbrush_handle.png"); - private static final ResourceLocation PAINTBRUSH_BRUSH = new ResourceLocation("customnpcs", "textures/items/paintbrush_brush.png"); - private static final ResourceLocation ENCHANT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); - - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - // Only handle equipped types (first person or third person equipped) - return type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON; - } - - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return false; - } - - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - // Ensure the item implements our render interface - if (!(item.getItem() instanceof ItemNpcTool)) - return; - - EntityLivingBase entity = (EntityLivingBase) data[1]; - - GL11.glPushMatrix(); - // For meta==1 (paintbrush) we want to assemble the texture from two parts - if (item.getItemDamage() == 1) { - renderPaintbrush(entity, item); - } else { - // For other tools, fall back on the normal special render routine. - renderItem3d(entity, item); - } - GL11.glPopMatrix(); - } - - /** - * Renders the paintbrush by drawing its handle first, then overlaying the brush part tinted - * by the NBT "BrushColor" value (an integer/hex value). - */ - private void renderPaintbrush(EntityLivingBase entity, ItemStack item) { - Minecraft mc = Minecraft.getMinecraft(); - TextureManager textureManager = mc.getTextureManager(); - Tessellator tessellator = Tessellator.instance; - int width = 16; - int height = 16; - float thickness = 0.0625F; - - GL11.glEnable(GL12.GL_RESCALE_NORMAL); - - // Render the handle (untinted) - textureManager.bindTexture(PAINTBRUSH_HANDLE); - // Using full texture coordinates (0→1) in the same order as vanilla's renderItemIn2D: - ItemRenderer.renderItemIn2D(tessellator, 1.0F, 0.0F, 0.0F, 1.0F, width, height, thickness); - - // Get the NBT color (default is white if not present) - int color = ItemNpcTool.getColor(item.getTagCompound()); - float red = ((color >> 16) & 0xFF) / 255.0F; - float green = ((color >> 8) & 0xFF) / 255.0F; - float blue = (color & 0xFF) / 255.0F; - GL11.glColor3f(red, green, blue); - - // Render the brush (tinted by the color) - textureManager.bindTexture(PAINTBRUSH_BRUSH); - ItemRenderer.renderItemIn2D(tessellator, 1.0F, 0.0F, 0.0F, 1.0F, width, height, thickness); - - // Reset GL color to white so that subsequent rendering is not tinted - GL11.glColor3f(1.0F, 1.0F, 1.0F); - GL11.glDisable(GL12.GL_RESCALE_NORMAL); - - // If the item is enchanted, render the enchanted glint effect on top - if (item.hasEffect(0)) { - renderEnchantedEffect(tessellator, textureManager); - } - } - - /** - * Fallback 3D item renderer (for non-paintbrush items) - */ - private void renderItem3d(EntityLivingBase entity, ItemStack item) { - Minecraft mc = Minecraft.getMinecraft(); - TextureManager textureManager = mc.getTextureManager(); - Tessellator tessellator = Tessellator.instance; - textureManager.bindTexture(textureManager.getResourceLocation(item.getItemSpriteNumber())); - IIcon icon = entity.getItemIcon(item, 0); - if (icon == null) { - return; - } - float minU = icon.getMinU(); - float maxU = icon.getMaxU(); - float minV = icon.getMinV(); - float maxV = icon.getMaxV(); - int width = icon.getIconWidth(); - int height = icon.getIconHeight(); - - GL11.glEnable(GL12.GL_RESCALE_NORMAL); - // Note: The order here mimics vanilla's 2D item rendering - ItemRenderer.renderItemIn2D(tessellator, maxU, minV, minU, maxV, width, height, 0.0625F); - GL11.glDisable(GL12.GL_RESCALE_NORMAL); - } - - /** - * Renders the enchanted glint overlay. - */ - private void renderEnchantedEffect(Tessellator tessellator, TextureManager textureManager) { - GL11.glDepthFunc(GL11.GL_EQUAL); - GL11.glDisable(GL11.GL_LIGHTING); - textureManager.bindTexture(ENCHANT); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); - float f7 = 0.76F; - GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glPushMatrix(); - float f8 = 0.125F; - GL11.glScalef(f8, f8, f8); - float f9 = (float) (Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; - GL11.glTranslatef(f9, 0.0F, 0.0F); - GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(f8, f8, f8); - f9 = (float) (Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; - GL11.glTranslatef(-f9, 0.0F, 0.0F); - GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glMatrixMode(GL11.GL_MODELVIEW); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDepthFunc(GL11.GL_LEQUAL); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - } -} diff --git a/src/main/java/noppes/npcs/config/ConfigClient.java b/src/main/java/noppes/npcs/config/ConfigClient.java index 459268552..96fc12067 100644 --- a/src/main/java/noppes/npcs/config/ConfigClient.java +++ b/src/main/java/noppes/npcs/config/ConfigClient.java @@ -15,9 +15,9 @@ public class ConfigClient public final static String GENERAL = "General"; public final static String VISUAL = "Visual"; - public final static String QUESTING = "Questing"; public final static String MODEL = "Model"; public final static String TEXTURE = "Texture"; + public final static String HUD = "Hud"; /** @@ -47,21 +47,12 @@ public class ConfigClient public static Property ChatBubblesFontTypeProperty; public static boolean ChatBubblesFontType = false; + public static Property HideEffectsBarProperty; + public static boolean HideEffectsBar = false; + /** * Questing Properties **/ - public static Property TrackingInfoAlignmentProperty; - public static int TrackingInfoAlignment = 3; - - public static Property TrackingInfoXProperty; - public static int TrackingInfoX = 0; - - public static Property TrackingInfoYProperty; - public static int TrackingInfoY = 0; - - public static Property TrackingScaleProperty; - public static int TrackingScale = 100; - public static Property DialogSpeedProperty; public static int DialogSpeed = 10; @@ -74,6 +65,34 @@ public class ConfigClient public static Property BannerAlertsProperty; public static boolean BannerAlerts = true; + // HUD PROPERTIES + public static Property QuestOverlayXProperty; + public static int QuestOverlayX = 100; + + public static Property QuestOverlayYProperty; + public static int QuestOverlayY = 100; + + public static Property QuestOverlayScaleProperty; + public static int QuestOverlayScale = 100; + + public static Property QuestOverlayTextAlignProperty; + public static int QuestOverlayTextAlign = 1; // 0: Left, 1: Center, 2: Right + + public static Property CompassEnabledProperty; + public static boolean CompassEnabled; + + public static Property CompassOverlayXProperty; + public static int CompassOverlayX; + + public static Property CompassOverlayYProperty; + public static int CompassOverlayY; + + public static Property CompassOverlayScaleProperty; + public static int CompassOverlayScale; + + public static Property CompassOverlayWidthProperty; + public static int CompassOverlayWidth; + /** * Texture Properties **/ @@ -104,6 +123,69 @@ public class ConfigClient { config.load(); + // Hud Quest Overlay settings + QuestOverlayXProperty = config.get(HUD, "Quest Hud X", 100, "X position of the quest overlay."); + QuestOverlayX = QuestOverlayXProperty.getInt(100); + + QuestOverlayYProperty = config.get(HUD, "Quest Hud Y", 100, "Y position of the quest overlay."); + QuestOverlayY = QuestOverlayYProperty.getInt(100); + + QuestOverlayScaleProperty = config.get(HUD, "Quest Hud Scale", 100, "Scale percentage of the quest overlay."); + QuestOverlayScale = QuestOverlayScaleProperty.getInt(100); + + QuestOverlayTextAlignProperty = config.get(HUD, "Quest Hud Text Alignment", 1, "Text alignment in quest overlay (0: Left, 1: Center, 2: Right)."); + QuestOverlayTextAlign = QuestOverlayTextAlignProperty.getInt(1); + + CompassEnabledProperty = config.get( + HUD, + "Compass Hud Enabled", + true, + "Enable Compass Hud Component" + ); + CompassEnabled = CompassEnabledProperty.getBoolean(); + + // Compass HUD Configs + CompassOverlayXProperty = config.get( + HUD, + "Compass Hud X", + 50, + "Horizontal position of compass overlay (0-100 percentage)", + 0, + 100 + ); + CompassOverlayX = CompassOverlayXProperty.getInt(); + + CompassOverlayYProperty = config.get( + HUD, + "Compass Hud Y", + 5, + "Vertical position of compass overlay (0-100 percentage)", + 0, + 100 + ); + CompassOverlayY = CompassOverlayYProperty.getInt(); + + CompassOverlayScaleProperty = config.get( + HUD, + "Compass Hud Scale", + 100, + "Scale percentage of compass overlay", + 50, + 300 + ); + CompassOverlayScale = CompassOverlayScaleProperty.getInt(); + + CompassOverlayWidthProperty = config.get( + HUD, + "Compass Hud Width", + 200, + "Base width of compass bar in pixels", + 100, + 1000 + ); + CompassOverlayWidth = CompassOverlayWidthProperty.getInt(); + + // General CacheLifeProperty = config.get(GENERAL, "Cache Life", 10, "How long should downloaded imagery data be saved client side? (In minutes)"); CacheLife = CacheLifeProperty.getInt(10); @@ -127,18 +209,8 @@ public class ConfigClient ChatBubblesFontTypeProperty = config.get(VISUAL, "Chat Bubbles Font Type", false, "Enable the use of Custom Font for Chat Bubbles"); ChatBubblesFontType = ChatBubblesFontTypeProperty.getBoolean(false); - // 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); - - TrackingInfoXProperty = config.get(QUESTING, "Tracking Info X", 0, "Client sided! Offsets the tracking info GUI by this amount in the X direction."); - TrackingInfoX = TrackingInfoXProperty.getInt(0); - - TrackingInfoYProperty = config.get(QUESTING, "Tracking Info Y", 0, "Client sided! Offsets the tracking info GUI by this amount in the Y direction."); - TrackingInfoY = TrackingInfoYProperty.getInt(0); - - TrackingScaleProperty = config.get(QUESTING, "Tracking Scale", 100, "Client sided! Adjusts the scaling of the Quest Tracking"); - TrackingScale = TrackingScaleProperty.getInt(100); + HideEffectsBarProperty = config.get(VISUAL, "Hide Effects Bar", false, "Hides CNPC+ Inventory Effects Bar"); + HideEffectsBar = HideEffectsBarProperty.getBoolean(false); DialogSpeedProperty = config.get(VISUAL, "Dialog Speed", true, "Only set for gradual dialogs"); DialogSpeed = DialogSpeedProperty.getInt(10); @@ -181,21 +253,7 @@ public class ConfigClient FontSize = LegacyConfig.FontSize; FontSizeProperty.set(FontSize); - - TrackingInfoAlignment = LegacyConfig.TrackingInfoAlignment; - TrackingInfoAlignmentProperty.set(TrackingInfoAlignment); - - TrackingInfoX = LegacyConfig.TrackingInfoX; - TrackingInfoXProperty.set(TrackingInfoX); - - TrackingInfoY = LegacyConfig.TrackingInfoY; - TrackingInfoYProperty.set(TrackingInfoY); } - - if (TrackingInfoAlignment < 0) - TrackingInfoAlignment = 0; - if (TrackingInfoAlignment > 8) - TrackingInfoAlignment = 8; } catch (Exception e) { diff --git a/src/main/java/noppes/npcs/config/ConfigMain.java b/src/main/java/noppes/npcs/config/ConfigMain.java index e3437c610..7732dd7c5 100644 --- a/src/main/java/noppes/npcs/config/ConfigMain.java +++ b/src/main/java/noppes/npcs/config/ConfigMain.java @@ -8,6 +8,8 @@ import noppes.npcs.config.legacy.LegacyConfig; import org.apache.logging.log4j.Level; import java.io.File; +import java.util.ArrayList; +import java.util.List; public class ConfigMain { @@ -80,7 +82,18 @@ public class ConfigMain public static Property DefaultMaxPartySizeProperty; public static int DefaultMaxPartySize = 4; - public static boolean EnableProfiles = true; + /** + * Profile Properties + **/ + public static boolean ProfilesEnabled = true; + public static boolean AllowProfileBackups = true; + public static int ProfileBackupAmount = 5; + + public static Property RegionProfileSwitchingProperty; + public static boolean RegionProfileSwitching = false; + + public static Property RestrictedProfileRegionsProperty; + public static List> RestrictedProfileRegions = new ArrayList<>(); /** * General NPC Properties @@ -220,7 +233,27 @@ public class ConfigMain TrackedQuestUpdateFrequency = TrackedQuestUpdateFrequencyProperty.getInt(5); // PROFILES - EnableProfiles = config.get(PROFILES, "Enable Profiles", true, "Allow the use of character Profiles").getBoolean(true); + ProfilesEnabled = config.get(PROFILES, "Enable Profiles", true, "Allow the use of character Profiles").getBoolean(true); + AllowProfileBackups = config.get(PROFILES, "Enable Profile Backups", true, "Will create backups of profile changes").getBoolean(true); + ProfileBackupAmount = config.get(PROFILES, "Number of Backups", 5, "How many backups per player to save").getInt(5); + + RegionProfileSwitchingProperty = config.get(PROFILES, "Region Profile Switching", false, "If true, only allows profile switching in certain regions."); + RegionProfileSwitching = RegionProfileSwitchingProperty.getBoolean(false); + + RestrictedProfileRegionsProperty = config.get(PROFILES, "Restricted Profile Regions", new String[]{ + "0, 100, 64, 100, 200, 80, 200", + "1, 50, 60, 50, 150, 75, 150" + }, "List of restricted regions where profile switching is enabled. Format: DIM, X1, Y1, Z1, X2, Y2, Z2"); + + RestrictedProfileRegions.clear(); + for (String region : RestrictedProfileRegionsProperty.getStringList()) { + String[] parts = region.split(", "); + List regionList = new ArrayList<>(); + for (String part : parts) { + regionList.add(Integer.parseInt(part)); + } + RestrictedProfileRegions.add(regionList); + } // Convert to Legacy if(CustomNpcs.legacyExist){ diff --git a/src/main/java/noppes/npcs/config/LoadConfiguration.java b/src/main/java/noppes/npcs/config/LoadConfiguration.java index f415674b7..43152620b 100644 --- a/src/main/java/noppes/npcs/config/LoadConfiguration.java +++ b/src/main/java/noppes/npcs/config/LoadConfiguration.java @@ -1,5 +1,7 @@ package noppes.npcs.config; +import net.minecraftforge.common.config.Property; + import java.io.File; public class LoadConfiguration { diff --git a/src/main/java/noppes/npcs/constants/EnumGuiType.java b/src/main/java/noppes/npcs/constants/EnumGuiType.java index 16927bacc..b95544a8a 100644 --- a/src/main/java/noppes/npcs/constants/EnumGuiType.java +++ b/src/main/java/noppes/npcs/constants/EnumGuiType.java @@ -1,11 +1,5 @@ package noppes.npcs.constants; -import noppes.npcs.quests.QuestItem; -import noppes.npcs.roles.companion.CompanionTrader; -import noppes.npcs.scripted.ScriptBlock; - -import javax.swing.border.Border; - public enum EnumGuiType { MainMenuDisplay, MainMenuInv, diff --git a/src/main/java/noppes/npcs/constants/EnumProfileSync.java b/src/main/java/noppes/npcs/constants/EnumProfileSync.java new file mode 100644 index 000000000..6702e08f7 --- /dev/null +++ b/src/main/java/noppes/npcs/constants/EnumProfileSync.java @@ -0,0 +1,21 @@ +package noppes.npcs.constants; + +import java.util.ArrayList; + +public enum EnumProfileSync { + Individual("profile.individual"), + Shared("party.shared"); + + public final String name; + + EnumProfileSync(String name){ + this.name = name; + } + public static String[] names(){ + ArrayList list = new ArrayList(); + for(EnumProfileSync e : values()) + list.add(e.name); + + return list.toArray(new String[list.size()]); + } +} diff --git a/src/main/java/noppes/npcs/constants/EnumQuestRepeat.java b/src/main/java/noppes/npcs/constants/EnumQuestRepeat.java index 954e4acd8..7cb4ecac5 100644 --- a/src/main/java/noppes/npcs/constants/EnumQuestRepeat.java +++ b/src/main/java/noppes/npcs/constants/EnumQuestRepeat.java @@ -1,5 +1,5 @@ package noppes.npcs.constants; public enum EnumQuestRepeat { - NONE, REPEATABLE, MCDAILY, MCWEEKLY, RLDAILY, RLWEEKLY; + NONE, REPEATABLE, MCDAILY, MCWEEKLY, RLDAILY, RLWEEKLY, MCCUSTOM, RLCUSTOM; } diff --git a/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java b/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java index 9230ed884..4b46ccdfa 100644 --- a/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java +++ b/src/main/java/noppes/npcs/containers/ContainerAnvilRepair.java @@ -3,12 +3,7 @@ package noppes.npcs.containers; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.ICrafting; -import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.inventory.InventoryCraftResult; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.Slot; +import net.minecraft.inventory.*; import net.minecraft.item.ItemStack; import net.minecraft.world.World; import noppes.npcs.api.handler.data.IAnvilRecipe; diff --git a/src/main/java/noppes/npcs/controllers/LinkedItemController.java b/src/main/java/noppes/npcs/controllers/LinkedItemController.java index 93d1ebe42..117f497b5 100644 --- a/src/main/java/noppes/npcs/controllers/LinkedItemController.java +++ b/src/main/java/noppes/npcs/controllers/LinkedItemController.java @@ -7,7 +7,9 @@ import noppes.npcs.CustomNpcs; import noppes.npcs.LogWriter; import noppes.npcs.api.handler.data.ILinkedItem; import noppes.npcs.api.item.IItemStack; -import noppes.npcs.controllers.data.*; +import noppes.npcs.controllers.data.INpcScriptHandler; +import noppes.npcs.controllers.data.LinkedItem; +import noppes.npcs.controllers.data.LinkedItemScript; import noppes.npcs.util.NBTJsonUtil; import java.io.*; diff --git a/src/main/java/noppes/npcs/controllers/MagicController.java b/src/main/java/noppes/npcs/controllers/MagicController.java index c92465252..adb3fe138 100644 --- a/src/main/java/noppes/npcs/controllers/MagicController.java +++ b/src/main/java/noppes/npcs/controllers/MagicController.java @@ -1,48 +1,54 @@ package noppes.npcs.controllers; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import noppes.npcs.CustomItems; import noppes.npcs.CustomNpcs; import noppes.npcs.LogWriter; -import noppes.npcs.api.handler.data.IMagic; import noppes.npcs.controllers.data.Magic; +import noppes.npcs.controllers.data.MagicCategory; +import noppes.npcs.controllers.data.MagicAssociation; -import java.io.*; -import java.util.*; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashMap; import java.util.zip.GZIPInputStream; public class MagicController { - public HashMap magicSync = new HashMap(); - public HashMap magics; + public HashMap magics = new HashMap<>(); + public HashMap magicSync = new HashMap<>(); + + public HashMap categories = new HashMap<>(); + public HashMap categoriesSync = new HashMap<>(); + + public int lastUsedCategoryID = 0; + private int lastUsedID = 0; private static MagicController instance; - private int lastUsedID = 0; - public MagicController() { instance = this; - magics = new HashMap(); } public static MagicController getInstance() { return instance; } - public Magic getMagic(int magic) { - return magics.get(magic); + public Magic getMagic(int magicId) { + return magics.get(magicId); + } + + public MagicCategory getCategory(int categoryId) { + return categories.get(categoryId); } public void load() { - magics = new HashMap(); - lastUsedID = 0; File saveDir = CustomNpcs.getWorldSaveDirectory(); - if (saveDir == null) { - return; - } + if (saveDir == null) return; try { File file = new File(saveDir, "magic.dat"); if (file.exists()) { @@ -56,214 +62,6 @@ public class MagicController { } } catch (Exception ee) { } } - magics.clear(); - if (false) { - // Create default Pokémon types - Magic normal = new Magic(0, "Normal", 0xA8A878); - normal.setIconItem(new ItemStack(net.minecraft.init.Items.paper)); // using paper for Normal - - Magic fire = new Magic(1, "Fire", 0xF08030); - fire.setIconItem(new ItemStack(net.minecraft.init.Items.flint)); // flint for Fire - - Magic water = new Magic(2, "Water", 0x6890F0); - water.setIconItem(new ItemStack(net.minecraft.init.Items.water_bucket)); // water bucket - - Magic electric = new Magic(3, "Electric", 0xF8D030); - electric.setIconItem(new ItemStack(net.minecraft.init.Items.redstone)); // redstone - - Magic grass = new Magic(4, "Grass", 0x78C850); - grass.setIconItem(new ItemStack(net.minecraft.init.Items.wheat_seeds)); // wheat seeds - - Magic ice = new Magic(5, "Ice", 0x98D8D8); - ice.setIconItem(new ItemStack(net.minecraft.init.Items.snowball)); // snowball for Ice - - Magic fighting = new Magic(6, "Fighting", 0xC03028); - fighting.setIconItem(new ItemStack(net.minecraft.init.Items.iron_sword)); // sword for Fighting - - Magic poison = new Magic(7, "Poison", 0xA040A0); - poison.setIconItem(new ItemStack(net.minecraft.init.Items.potionitem)); // potion item for Poison - - Magic ground = new Magic(8, "Ground", 0xE0C068); - ground.setIconItem(new ItemStack(Blocks.dirt)); // dirt for Ground - - Magic flying = new Magic(9, "Flying", 0xA890F0); - flying.setIconItem(new ItemStack(net.minecraft.init.Items.feather)); // feather for Flying - - Magic psychic = new Magic(10, "Psychic", 0xF85888); - psychic.setIconItem(new ItemStack(net.minecraft.init.Items.ender_pearl)); // ender pearl for Psychic - - Magic bug = new Magic(11, "Bug", 0xA8B820); - bug.setIconItem(new ItemStack(net.minecraft.init.Items.spider_eye)); // spider eye for Bug - - Magic rock = new Magic(12, "Rock", 0xB8A038); - rock.setIconItem(new ItemStack(Blocks.cobblestone)); // cobblestone for Rock - - Magic ghost = new Magic(13, "Ghost", 0x705898); - ghost.setIconItem(new ItemStack(net.minecraft.init.Items.skull)); // skull for Ghost - - Magic dragon = new Magic(14, "Dragon", 0x7038F8); - dragon.setIconItem(new ItemStack(Blocks.dragon_egg)); // dragon egg - - Magic dark = new Magic(15, "Dark", 0x705848); - dark.setIconItem(new ItemStack(net.minecraft.init.Items.coal)); // coal for Dark - - Magic steel = new Magic(16, "Steel", 0xB8B8D0); - steel.setIconItem(new ItemStack(net.minecraft.init.Items.iron_ingot)); // iron ingot for Steel - - Magic fairy = new Magic(17, "Fairy", 0xEE99AC); - fairy.setIconItem(new ItemStack(net.minecraft.init.Items.sugar)); // sugar for Fairy - - // Now set weaknesses (using a multiplier of 2.0f to indicate “double damage”). - // The following is based on a common Pokémon type chart. - normal.weaknesses.put(fighting.id, 2.0f); - - fire.weaknesses.put(water.id, 2.0f); - fire.weaknesses.put(ground.id, 2.0f); - fire.weaknesses.put(rock.id, 2.0f); - - water.weaknesses.put(electric.id, 2.0f); - water.weaknesses.put(grass.id, 2.0f); - - electric.weaknesses.put(ground.id, 2.0f); - - grass.weaknesses.put(fire.id, 2.0f); - grass.weaknesses.put(ice.id, 2.0f); - grass.weaknesses.put(poison.id, 2.0f); - grass.weaknesses.put(flying.id, 2.0f); - grass.weaknesses.put(bug.id, 2.0f); - - ice.weaknesses.put(fire.id, 2.0f); - ice.weaknesses.put(fighting.id, 2.0f); - ice.weaknesses.put(rock.id, 2.0f); - ice.weaknesses.put(steel.id, 2.0f); - - fighting.weaknesses.put(flying.id, 2.0f); - fighting.weaknesses.put(psychic.id, 2.0f); - fighting.weaknesses.put(fairy.id, 2.0f); - - poison.weaknesses.put(ground.id, 2.0f); - poison.weaknesses.put(psychic.id, 2.0f); - - ground.weaknesses.put(water.id, 2.0f); - ground.weaknesses.put(grass.id, 2.0f); - ground.weaknesses.put(ice.id, 2.0f); - - flying.weaknesses.put(electric.id, 2.0f); - flying.weaknesses.put(ice.id, 2.0f); - flying.weaknesses.put(rock.id, 2.0f); - - psychic.weaknesses.put(bug.id, 2.0f); - psychic.weaknesses.put(ghost.id, 2.0f); - psychic.weaknesses.put(dark.id, 2.0f); - - bug.weaknesses.put(fire.id, 2.0f); - bug.weaknesses.put(flying.id, 2.0f); - bug.weaknesses.put(rock.id, 2.0f); - - rock.weaknesses.put(water.id, 2.0f); - rock.weaknesses.put(grass.id, 2.0f); - rock.weaknesses.put(fighting.id, 2.0f); - rock.weaknesses.put(ground.id, 2.0f); - rock.weaknesses.put(steel.id, 2.0f); - - ghost.weaknesses.put(ghost.id, 2.0f); - ghost.weaknesses.put(dark.id, 2.0f); - - dragon.weaknesses.put(ice.id, 2.0f); - dragon.weaknesses.put(dragon.id, 2.0f); - dragon.weaknesses.put(fairy.id, 2.0f); - - dark.weaknesses.put(fighting.id, 2.0f); - dark.weaknesses.put(bug.id, 2.0f); - dark.weaknesses.put(fairy.id, 2.0f); - - steel.weaknesses.put(fire.id, 2.0f); - steel.weaknesses.put(fighting.id, 2.0f); - steel.weaknesses.put(ground.id, 2.0f); - - fairy.weaknesses.put(poison.id, 2.0f); - fairy.weaknesses.put(steel.id, 2.0f); - - // Register the types. - magics.put(normal.id, normal); - magics.put(fire.id, fire); - magics.put(water.id, water); - magics.put(electric.id, electric); - magics.put(grass.id, grass); - magics.put(ice.id, ice); - magics.put(fighting.id, fighting); - magics.put(poison.id, poison); - magics.put(ground.id, ground); - magics.put(flying.id, flying); - magics.put(psychic.id, psychic); - magics.put(bug.id, bug); - magics.put(rock.id, rock); - magics.put(ghost.id, ghost); - magics.put(dragon.id, dragon); - magics.put(dark.id, dark); - magics.put(steel.id, steel); - magics.put(fairy.id, fairy); - } - - if (true) { - // Create default magics - Magic earth = new Magic(0, "Earth", 0x00DD00, 1, 1); - earth.setIconItem(new ItemStack(CustomItems.earthElement)); - - Magic water = new Magic(1, "Water", 0xF2DD00, 1, 2); - water.setIconItem(new ItemStack(CustomItems.waterElement)); - - Magic fire = new Magic(2, "Fire", 0xDD0000, 1, 3); - fire.setIconItem(new ItemStack(CustomItems.spellFire)); - - Magic air = new Magic(3, "Air", 0xDD0000, 1, 0); - air.setIconItem(new ItemStack(CustomItems.airElement)); - - Magic dark = new Magic(4, "Dark", 0xDD0000, 0, 3); - dark.setIconItem(new ItemStack(CustomItems.spellDark)); - - Magic holy = new Magic(5, "Holy", 0xDD0000, 0, 1); - holy.setIconItem(new ItemStack(CustomItems.spellHoly)); - - Magic nature = new Magic(6, "Nature", 0xDD0000, 0, 0); - nature.setIconItem(new ItemStack(CustomItems.spellNature)); - - Magic arcane = new Magic(7, "Arcane", 0xDD0000, 0, 2); - arcane.setIconItem(new ItemStack(CustomItems.spellArcane)); - - // Insiders - earth.weaknesses.put(air.id, 0.60f); - water.weaknesses.put(earth.id, 0.60f); - fire.weaknesses.put(water.id, 0.60f); - air.weaknesses.put(fire.id, 0.60f); - - // Outsiders - dark.weaknesses.put(nature.id, 0.60f); - nature.weaknesses.put(holy.id, 0.60f); - holy.weaknesses.put(arcane.id, 0.60f); - arcane.weaknesses.put(dark.id, 0.60f); - - // Cross Interactions - earth.weaknesses.put(nature.id, 0.30f); - water.weaknesses.put(holy.id, 0.30f); - fire.weaknesses.put(arcane.id, 0.30f); - air.weaknesses.put(dark.id, 0.30f); - dark.weaknesses.put(fire.id, 0.30f); - nature.weaknesses.put(air.id, 0.30f); - holy.weaknesses.put(earth.id, 0.30f); - arcane.weaknesses.put(water.id, 0.30f); - - // Add them to the registry - magics.put(earth.id, earth); - magics.put(water.id, water); - magics.put(fire.id, fire); - magics.put(air.id, air); - magics.put(dark.id, dark); - magics.put(holy.id, holy); - magics.put(nature.id, nature); - magics.put(arcane.id, arcane); - } - printAllMagicInteractions(); } private void loadMagicFile(File file) throws IOException { @@ -275,67 +73,69 @@ public class MagicController { } public void loadMagic(DataInputStream stream) throws IOException { - HashMap magic = new HashMap(); - NBTTagCompound nbttagcompound1 = CompressedStreamTools.read(stream); - lastUsedID = nbttagcompound1.getInteger("lastID"); - NBTTagList list = nbttagcompound1.getTagList("NPCMagic", 10); // using "NPCMagic" as tag + NBTTagCompound compound = CompressedStreamTools.read(stream); + lastUsedID = compound.getInteger("lastID"); + lastUsedCategoryID = compound.getInteger("lastCatID"); - if (list != null) { - for (int i = 0; i < list.tagCount(); i++) { - NBTTagCompound nbttagcompound = list.getCompoundTagAt(i); - Magic loadMagic = new Magic(); - loadMagic.readNBT(nbttagcompound); - magic.put(loadMagic.id, loadMagic); - } + // Load magics + magics.clear(); + NBTTagList magicList = compound.getTagList("Magics", 10); + for (int i = 0; i < magicList.tagCount(); i++) { + NBTTagCompound magCompound = magicList.getCompoundTagAt(i); + Magic mag = new Magic(); + mag.readNBT(magCompound); + magics.put(mag.id, mag); + } + + // Load categories + categories.clear(); + NBTTagList catList = compound.getTagList("Categories", 10); + for (int i = 0; i < catList.tagCount(); i++) { + NBTTagCompound catCompound = catList.getCompoundTagAt(i); + MagicCategory cat = new MagicCategory(); + cat.readNBT(catCompound); + categories.put(cat.id, cat); } - this.magics = magic; } public NBTTagCompound getNBT() { - NBTTagList list = new NBTTagList(); - for (int slot : magics.keySet()) { - Magic mag = magics.get(slot); - NBTTagCompound nbtMagic = new NBTTagCompound(); - mag.writeNBT(nbtMagic); - list.appendTag(nbtMagic); + NBTTagList magicList = new NBTTagList(); + for (Magic mag : magics.values()) { + NBTTagCompound magCompound = new NBTTagCompound(); + mag.writeNBT(magCompound); + magicList.appendTag(magCompound); } - NBTTagCompound nbttagcompound = new NBTTagCompound(); - nbttagcompound.setInteger("lastID", lastUsedID); - nbttagcompound.setTag("NPCMagic", list); // use same tag as loadMagic - return nbttagcompound; + NBTTagList catList = new NBTTagList(); + for (MagicCategory cat : categories.values()) { + NBTTagCompound catCompound = new NBTTagCompound(); + cat.writeNBT(catCompound); + catList.appendTag(catCompound); + } + NBTTagCompound compound = new NBTTagCompound(); + compound.setInteger("lastID", lastUsedID); + compound.setInteger("lastCatID", lastUsedCategoryID); + compound.setTag("Magics", magicList); + compound.setTag("Categories", catList); + return compound; } - public void saveFactions() { + public void saveMagicData() { try { File saveDir = CustomNpcs.getWorldSaveDirectory(); - File file = new File(saveDir, "magic.dat_new"); - File file1 = new File(saveDir, "magic.dat_old"); - File file2 = new File(saveDir, "magic.dat"); - CompressedStreamTools.writeCompressed(getNBT(), new FileOutputStream(file)); - if (file1.exists()) { - file1.delete(); - } - file2.renameTo(file1); - if (file2.exists()) { - file2.delete(); - } - file.renameTo(file2); - if (file.exists()) { - file.delete(); - } + File fileNew = new File(saveDir, "magic.dat_new"); + File fileOld = new File(saveDir, "magic.dat_old"); + File fileCurrent = new File(saveDir, "magic.dat"); + CompressedStreamTools.writeCompressed(getNBT(), new FileOutputStream(fileNew)); + if (fileOld.exists()) fileOld.delete(); + fileCurrent.renameTo(fileOld); + if (fileCurrent.exists()) fileCurrent.delete(); + fileNew.renameTo(fileCurrent); + if (fileNew.exists()) fileNew.delete(); } catch (Exception e) { LogWriter.except(e); } } - public Magic get(int magicID) { - return magics.get(magicID); - } - - public List list() { - return new ArrayList(this.magics.values()); - } - public void saveMagic(Magic mag) { if (mag.id < 0) { mag.id = getUnusedId(); @@ -347,252 +147,76 @@ public class MagicController { while (hasName(mag.name)) mag.name += "_"; } - magics.remove(mag.id); magics.put(mag.id, mag); - - NBTTagCompound facCompound = new NBTTagCompound(); - mag.writeNBT(facCompound); - // Server.sendToAll(EnumPacketClient.SYNC_UPDATE, SyncType.MAGIC, facCompound); - saveFactions(); + saveMagicData(); } public int getUnusedId() { if (lastUsedID == 0) { - for (int catid : magics.keySet()) - if (catid > lastUsedID) - lastUsedID = catid; + for (int id : magics.keySet()) + if (id > lastUsedID) + lastUsedID = id; } lastUsedID++; return lastUsedID; } public boolean hasName(String newName) { - if (newName.trim().isEmpty()) - return true; + if (newName.trim().isEmpty()) return true; for (Magic mag : magics.values()) if (mag.name.equals(newName)) return true; return false; } - public Magic getMagicFromName(String magicName) { - for (Map.Entry entryMag : MagicController.getInstance().magics.entrySet()) { - if (entryMag.getValue().name.equalsIgnoreCase(magicName)) { - return entryMag.getValue(); - } - } - return null; - } + // === Category management methods === - public String[] getNames() { - String[] names = new String[magics.size()]; - int i = 0; - for (Magic mag : magics.values()) { - names[i] = mag.name.toLowerCase(); - i++; - } - return names; - } - - // --- New functions for applying magic NBT stats and calculating damage --- - - /** - * Applies magic-type damage to an item. A weapon/item can have multiple magic damage values. - * The damage is stored under a compound tag "MagicDamage" where each key is the magic ID. - */ - public static void addMagicDamageToItem(ItemStack item, int magicId, float damage) { - if (item == null) return; - if (item.stackTagCompound == null) - item.stackTagCompound = new NBTTagCompound(); - NBTTagCompound compound = item.stackTagCompound; - NBTTagCompound magicDamage; - if (compound.hasKey("MagicDamage")) { - magicDamage = compound.getCompoundTag("MagicDamage"); + public void addCategory(MagicCategory category) { + if (category.id < 0) { + lastUsedCategoryID++; + category.id = lastUsedCategoryID; } else { - magicDamage = new NBTTagCompound(); + while (containsCategoryName(category.title)) + category.title += "_"; + } + categories.put(category.id, category); + saveMagicData(); + } + + public boolean containsCategoryName(String title) { + title = title.toLowerCase(); + for (MagicCategory cat : categories.values()) { + if (cat.title.toLowerCase().equals(title)) + return true; + } + return false; + } + + public void removeCategory(int categoryId) { + if (categories.containsKey(categoryId)) { + categories.remove(categoryId); + saveMagicData(); } - magicDamage.setFloat(String.valueOf(magicId), damage); - compound.setTag("MagicDamage", magicDamage); } /** - * Applies magic resistance to an armor piece. - * The resistance is stored under a compound tag "MagicResistances" with the magic ID as key. + * Associates a magic with a category along with its per-category ordering data. */ - public static void addMagicResistanceToArmor(ItemStack armor, int magicId, float resistance) { - if (armor == null) return; - if (armor.stackTagCompound == null) - armor.stackTagCompound = new NBTTagCompound(); - NBTTagCompound compound = armor.stackTagCompound; - NBTTagCompound magicResist; - if (compound.hasKey("MagicResistances")) { - magicResist = compound.getCompoundTag("MagicResistances"); - } else { - magicResist = new NBTTagCompound(); - } - magicResist.setFloat(String.valueOf(magicId), resistance); - compound.setTag("MagicResistances", magicResist); + public void addMagicToCategory(int magicId, int categoryId, int index, int priority) { + MagicCategory cat = categories.get(categoryId); + if (cat == null) return; + MagicAssociation assoc = new MagicAssociation(); + assoc.magicId = magicId; + assoc.index = index; + assoc.priority = priority; + cat.associations.put(magicId, assoc); + saveMagicData(); } - /** - * Given a collection of armor pieces, sums the resistance value for the specified magic ID. - */ - public static float calculateTotalMagicResistance(int magicId, Iterable armors) { - float totalResistance = 0.0F; - for (ItemStack armor : armors) { - if (armor != null && armor.hasTagCompound() && armor.stackTagCompound.hasKey("MagicResistances")) { - NBTTagCompound magicResist = armor.stackTagCompound.getCompoundTag("MagicResistances"); - if (magicResist.hasKey(String.valueOf(magicId))) { - totalResistance += magicResist.getFloat(String.valueOf(magicId)); - } - } - } - return totalResistance; - } - - /** - * Calculates the final magic damage after applying armor resistances. - * For a given magic type, the resistance is applied. - * - * @param magicId the magic type - * @param baseDamage the base damage value - * @param armors an Iterable collection of armor ItemStacks - * @return the final damage after reduction - */ - public static float calculateFinalMagicDamage(int magicId, float baseDamage, Iterable armors) { - if (getInstance().getMagic(magicId) == null) { - // If the magic type is not defined, treat it as non-magical. - return baseDamage; - } - float resistance = calculateTotalMagicResistance(magicId, armors); - // Resistance is assumed to be a fractional reduction (e.g., 0.2 = 20% reduction). - return baseDamage * (1.0F - resistance); - } - - /** - * Extracts magic damage values from a weapon ItemStack. - * It looks for a compound tag "CNPCMagic" first; if not found, it falls back to "MagicDamage". - * Returns a mapping of magic ID to its damage value. - */ - public static Map getMagicDamageFromItem(ItemStack item) { - Map damageMap = new HashMap(); - if (item == null || item.stackTagCompound == null) return damageMap; - NBTTagCompound compound = item.stackTagCompound; - NBTTagCompound damageCompound = null; - if (compound.hasKey("CNPCMagic")) { - NBTTagCompound magicCompound = compound.getCompoundTag("CNPCMagic"); - if (magicCompound.hasKey("MagicDamage")) { - damageCompound = magicCompound.getCompoundTag("MagicDamage"); - } - } else if (compound.hasKey("MagicDamage")) { - damageCompound = compound.getCompoundTag("MagicDamage"); - } - if (damageCompound != null) { - Set keys = damageCompound.func_150296_c(); - for (String key : keys) { - try { - int magicId = Integer.parseInt(key); - float dmg = damageCompound.getFloat(key); - damageMap.put(magicId, dmg); - } catch (NumberFormatException e) { - // Ignore non-integer keys. - } - } - } - return damageMap; - } - - /** - * Extracts magic resistances from an armor ItemStack. - * It checks for a "CNPCMagic" container first; if not present, it falls back to "MagicResistances". - * Returns a mapping of magic ID to its resistance value. - */ - public static Map getMagicResistancesFromItem(ItemStack item) { - Map resistMap = new HashMap(); - if (item == null || item.stackTagCompound == null) return resistMap; - NBTTagCompound compound = item.stackTagCompound; - NBTTagCompound resistCompound = null; - if (compound.hasKey("CNPCMagic")) { - NBTTagCompound magicCompound = compound.getCompoundTag("CNPCMagic"); - if (magicCompound.hasKey("MagicResistances")) { - resistCompound = magicCompound.getCompoundTag("MagicResistances"); - } - } else if (compound.hasKey("MagicResistances")) { - resistCompound = compound.getCompoundTag("MagicResistances"); - } - if (resistCompound != null) { - Set keys = resistCompound.func_150296_c(); - for (String key : keys) { - try { - int magicId = Integer.parseInt(key); - float res = resistCompound.getFloat(key); - resistMap.put(magicId, res); - } catch (NumberFormatException e) { - // Ignore non-integer keys. - } - } - } - return resistMap; - } - - /** - * Validates whether an item (weapon or armor) contains any magic-related NBT. - */ - public static boolean hasMagicStats(ItemStack item) { - if (item == null || item.stackTagCompound == null) return false; - NBTTagCompound compound = item.stackTagCompound; - return compound.hasKey("CNPCMagic") || compound.hasKey("MagicDamage") || compound.hasKey("MagicResistances"); - } - - /** - * Calculates a damage breakdown for each magic type from a weapon when applied against a set of armors. - * This function will ignore any magic with ID 0 (neutral), so only magic damage is returned. - * Returns a map where keys are magic IDs (non-zero) and values are the final damage for that type. - */ - public static Map calculateDamageBreakdown(ItemStack weapon, Iterable armors) { - Map breakdown = new HashMap(); - Map weaponDamage = getMagicDamageFromItem(weapon); - for (Map.Entry entry : weaponDamage.entrySet()) { - int magicId = entry.getKey(); - // Skip magic ID 0 (neutral) - if (magicId == 0) continue; - float dmg = entry.getValue(); - float finalDmg = calculateFinalMagicDamage(magicId, dmg, armors); - breakdown.put(magicId, finalDmg); - } - return breakdown; - } - - /** - * Calculates the total final magic damage of a weapon after applying the resistances of a set of armor pieces. - * This sums only the magic interactions (magic IDs other than 0). - */ - public static float calculateTotalDamage(ItemStack weapon, Iterable armors) { - float totalDamage = 0.0F; - Map breakdown = calculateDamageBreakdown(weapon, armors); - for (Float dmg : breakdown.values()) { - totalDamage += dmg; - } - return totalDamage; - } - - /** - * Prints all magic interactions (weaknesses) in the registry. - * For each magic (defender) that has weaknesses, prints the corresponding attacker and the extra damage percentage. - * Format: "Magic ID: [attacker id], Name: "[attacker name]" does [percentage*100]% extra damage to Magic ID: [defender id], Name: "[defender name]". - */ - public static void printAllMagicInteractions() { - MagicController mc = getInstance(); - for (Magic defender : mc.magics.values()) { - for (Map.Entry entry : defender.weaknesses.entrySet()) { - int attackerId = entry.getKey(); - float percentage = entry.getValue(); - Magic attacker = mc.getMagic(attackerId); - if (attacker != null) { - System.out.println("Magic ID: " + attacker.id + ", Name: \"" + attacker.name + "\" does " - + (percentage * 100) + "% extra damage to Magic ID: " + defender.id + ", Name: \"" + defender.name + "\""); - } - } - } + public void removeMagicFromCategory(int magicId, int categoryId) { + MagicCategory cat = categories.get(categoryId); + if (cat == null) return; + cat.associations.remove(magicId); + saveMagicData(); } } diff --git a/src/main/java/noppes/npcs/controllers/PlayerQuestController.java b/src/main/java/noppes/npcs/controllers/PlayerQuestController.java index 20d6236e3..f7d38a3b3 100644 --- a/src/main/java/noppes/npcs/controllers/PlayerQuestController.java +++ b/src/main/java/noppes/npcs/controllers/PlayerQuestController.java @@ -1,5 +1,6 @@ package noppes.npcs.controllers; +import kamkeel.npcs.controllers.ProfileController; import kamkeel.npcs.network.packets.data.AchievementPacket; import kamkeel.npcs.network.packets.data.ChatAlertPacket; import net.minecraft.entity.player.EntityPlayer; @@ -8,6 +9,8 @@ import net.minecraft.util.ChatComponentTranslation; import noppes.npcs.EventHooks; import noppes.npcs.NoppesStringUtils; import noppes.npcs.NoppesUtilServer; +import noppes.npcs.config.ConfigMain; +import noppes.npcs.constants.EnumProfileSync; import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.data.PlayerData; @@ -64,11 +67,7 @@ public class PlayerQuestController { PlayerQuestData data = playerdata.questData; QuestData questData = data.activeQuests.get(quest.id); data.activeQuests.remove(quest.id); - if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY) - data.finishedQuests.put(quest.id, System.currentTimeMillis()); - else - data.finishedQuests.put(quest.id,player.worldObj.getTotalWorldTime()); - + setQuestFinishedUtil(player, quest, data); if(quest.repeat != EnumQuestRepeat.NONE && quest.type == EnumQuestType.Dialog){ QuestDialog questdialog = (QuestDialog) quest.questInterface; for(int dialog : questdialog.dialogs.values()){ @@ -82,15 +81,25 @@ public class PlayerQuestController { playerdata.updateClient = true; } + public static void setQuestFinishedUtil(EntityPlayer player, Quest quest, PlayerQuestData questData){ + long completeTime; + if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY || quest.repeat == EnumQuestRepeat.RLCUSTOM){ + completeTime = System.currentTimeMillis(); + questData.finishedQuests.put(quest.id, completeTime); + } else { + completeTime = player.worldObj.getTotalWorldTime(); + questData.finishedQuests.put(quest.id, completeTime); + } + + if(ConfigMain.ProfilesEnabled && quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared) + ProfileController.Instance.shareQuestCompletion(player, quest.id, completeTime); + } + public static void setQuestPartyFinished(Quest quest, EntityPlayer player, QuestData questData ){ PlayerData playerdata = PlayerData.get(player); PlayerQuestData data = playerdata.questData; data.activeQuests.remove(quest.id); - if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY) - data.finishedQuests.put(quest.id, System.currentTimeMillis()); - else - data.finishedQuests.put(quest.id,player.worldObj.getTotalWorldTime()); - + setQuestFinishedUtil(player, quest, data); if(quest.repeat != EnumQuestRepeat.NONE && quest.type == EnumQuestType.Dialog){ QuestDialog questdialog = (QuestDialog) quest.questInterface; for(int dialog : questdialog.dialogs.values()){ diff --git a/src/main/java/noppes/npcs/controllers/QuestController.java b/src/main/java/noppes/npcs/controllers/QuestController.java index 51051bcb4..3b5616e4d 100644 --- a/src/main/java/noppes/npcs/controllers/QuestController.java +++ b/src/main/java/noppes/npcs/controllers/QuestController.java @@ -11,6 +11,7 @@ import noppes.npcs.NoppesStringUtils; import noppes.npcs.api.handler.IQuestHandler; import noppes.npcs.api.handler.data.IQuest; import noppes.npcs.api.handler.data.IQuestCategory; +import noppes.npcs.constants.EnumProfileSync; import noppes.npcs.controllers.data.Quest; import noppes.npcs.controllers.data.QuestCategory; import noppes.npcs.util.NBTJsonUtil; @@ -23,6 +24,7 @@ public class QuestController implements IQuestHandler { public HashMap categoriesSync = new HashMap(); public HashMap categories = new HashMap(); public HashMap quests = new HashMap(); + public HashMap sharedQuests = new HashMap<>(); public static QuestController Instance = new QuestController();; @@ -75,6 +77,9 @@ public class QuestController implements IQuestHandler { } else{ quests.put(id, quest); + if(quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared){ + sharedQuests.put(id, quest); + } } } lastUsedCatID++; @@ -209,9 +214,15 @@ public class QuestController implements IQuestHandler { lastUsedQuestID++; quest.id = lastUsedQuestID; } + quests.put(quest.id, quest); category.quests.put(quest.id, quest); + sharedQuests.remove(quest.id); + if(quest.profileOptions.enableOptions && quest.profileOptions.completeControl == EnumProfileSync.Shared){ + sharedQuests.put(quest.id, quest); + } + File dir = new File(getDir(), category.title); if(!dir.exists()) dir.mkdirs(); diff --git a/src/main/java/noppes/npcs/controllers/ScriptController.java b/src/main/java/noppes/npcs/controllers/ScriptController.java index 73b872e8f..4217f8668 100644 --- a/src/main/java/noppes/npcs/controllers/ScriptController.java +++ b/src/main/java/noppes/npcs/controllers/ScriptController.java @@ -4,7 +4,6 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import jdk.nashorn.api.scripting.ClassFilter; import jdk.nashorn.api.scripting.NashornScriptEngineFactory; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; @@ -25,7 +24,10 @@ import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; import java.util.*; import static noppes.npcs.util.CustomNPCsThreader.customNPCThread; diff --git a/src/main/java/noppes/npcs/controllers/data/CustomEffect.java b/src/main/java/noppes/npcs/controllers/data/CustomEffect.java index 03520eee8..75591a8c5 100644 --- a/src/main/java/noppes/npcs/controllers/data/CustomEffect.java +++ b/src/main/java/noppes/npcs/controllers/data/CustomEffect.java @@ -22,7 +22,6 @@ public class CustomEffect implements ICustomEffect { public int everyXTick = 20; public String icon = ""; - // CustomNpcPlusDBC.ID + ":textures/gui/icons.png"; public int iconX = 0, iconY = 0; /** diff --git a/src/main/java/noppes/npcs/controllers/data/EffectScript.java b/src/main/java/noppes/npcs/controllers/data/EffectScript.java index 16f8f1e63..f27232554 100644 --- a/src/main/java/noppes/npcs/controllers/data/EffectScript.java +++ b/src/main/java/noppes/npcs/controllers/data/EffectScript.java @@ -10,10 +10,8 @@ import noppes.npcs.config.ConfigScript; import noppes.npcs.constants.EnumScriptType; import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.ScriptController; -import noppes.npcs.scripted.NpcAPI; import noppes.npcs.scripted.event.PlayerEvent; -import javax.script.ScriptEngine; import java.io.IOException; import java.util.*; diff --git a/src/main/java/noppes/npcs/controllers/data/LinkedItemScript.java b/src/main/java/noppes/npcs/controllers/data/LinkedItemScript.java index 4c46a4e32..c88b880e2 100644 --- a/src/main/java/noppes/npcs/controllers/data/LinkedItemScript.java +++ b/src/main/java/noppes/npcs/controllers/data/LinkedItemScript.java @@ -10,10 +10,7 @@ import noppes.npcs.config.ConfigScript; import noppes.npcs.constants.EnumScriptType; import noppes.npcs.controllers.ScriptContainer; import noppes.npcs.controllers.ScriptController; -import noppes.npcs.scripted.NpcAPI; -import noppes.npcs.scripted.event.PlayerEvent; -import javax.script.ScriptEngine; import java.io.IOException; import java.util.*; diff --git a/src/main/java/noppes/npcs/controllers/data/Magic.java b/src/main/java/noppes/npcs/controllers/data/Magic.java index 1b5636bc1..25b5b1474 100644 --- a/src/main/java/noppes/npcs/controllers/data/Magic.java +++ b/src/main/java/noppes/npcs/controllers/data/Magic.java @@ -5,7 +5,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import noppes.npcs.api.handler.data.IMagic; import noppes.npcs.controllers.MagicController; - import java.util.HashMap; import java.util.Map; @@ -14,16 +13,9 @@ public class Magic implements IMagic { public int color = Integer.parseInt("FF00", 16); public int id = -1; - public int index; - public int priority; - - // Icon as an ItemStack or as a texture file public ItemStack iconItem = null; public String iconTexture = ""; - - // Weaknesses mapping: key = magic ID this magic is weak against, - // value = extra damage percentage (as a fraction, e.g. 0.2 for 20% extra damage) - public Map weaknesses = new HashMap(); + public Map weaknesses = new HashMap<>(); public Magic() {} @@ -33,14 +25,6 @@ public class Magic implements IMagic { this.id = id; } - public Magic(int id, String name, int color, int index, int priority) { - this.name = name; - this.color = color; - this.id = id; - this.index = index; - this.priority = priority; - } - public static String formatName(String name) { name = name.toLowerCase().trim(); return name.substring(0, 1).toUpperCase() + name.substring(1); @@ -50,19 +34,15 @@ public class Magic implements IMagic { name = compound.getString("Name"); color = compound.getInteger("Color"); id = compound.getInteger("Slot"); - index = compound.getInteger("Index"); - priority = compound.getInteger("Priority"); - + // No longer reading index/priority here. if(compound.hasKey("IconItem")){ NBTTagCompound itemTag = compound.getCompoundTag("IconItem"); iconItem = ItemStack.loadItemStackFromNBT(itemTag); } iconTexture = compound.getString("IconTexture"); - - // Read the weaknesses mapping from NBT. weaknesses.clear(); if(compound.hasKey("Weaknesses")) { - NBTTagList weaknessList = compound.getTagList("Weaknesses", 10); // compound tags + NBTTagList weaknessList = compound.getTagList("Weaknesses", 10); for(int i = 0; i < weaknessList.tagCount(); i++){ NBTTagCompound weaknessTag = weaknessList.getCompoundTagAt(i); int weakMagicId = weaknessTag.getInteger("MagicID"); @@ -76,9 +56,7 @@ public class Magic implements IMagic { compound.setInteger("Slot", id); compound.setString("Name", name); compound.setInteger("Color", color); - compound.setInteger("Index", index); - compound.setInteger("Priority", priority); - + // No longer writing index/priority here. if(iconItem != null) { NBTTagCompound itemTag = new NBTTagCompound(); iconItem.writeToNBT(itemTag); @@ -87,8 +65,6 @@ public class Magic implements IMagic { if(iconTexture != null && !iconTexture.isEmpty()){ compound.setString("IconTexture", iconTexture); } - - // Write the weaknesses mapping. NBTTagList weaknessList = new NBTTagList(); for(Map.Entry entry : weaknesses.entrySet()){ NBTTagCompound weaknessTag = new NBTTagCompound(); @@ -111,26 +87,11 @@ public class Magic implements IMagic { this.name = name; } - public int getPriority() { - return priority; - } - - public void setPriority(int priority) { - this.priority = priority; - } - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - public void setColor(int color) { - this.color = color; + public void setColor(int c) { + this.color = c; } + @Override public int getColor() { return this.color; } diff --git a/src/main/java/noppes/npcs/controllers/data/MagicAssociation.java b/src/main/java/noppes/npcs/controllers/data/MagicAssociation.java new file mode 100644 index 000000000..2589233c9 --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/MagicAssociation.java @@ -0,0 +1,11 @@ +package noppes.npcs.controllers.data; + +/** + * A helper class that represents the relationship between a Magic and a Category. + * It holds per-category ordering data. + */ +public class MagicAssociation { + public int magicId; + public int index; + public int priority; +} diff --git a/src/main/java/noppes/npcs/controllers/data/MagicCategory.java b/src/main/java/noppes/npcs/controllers/data/MagicCategory.java new file mode 100644 index 000000000..d3a3b029e --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/MagicCategory.java @@ -0,0 +1,46 @@ +package noppes.npcs.controllers.data; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import java.util.HashMap; + +/** + * Holds category information for magic. + * Each category can have many magic associations. + */ +public class MagicCategory { + public int id = -1; + public String title = ""; + public HashMap associations = new HashMap<>(); + + public MagicCategory() {} + + public void readNBT(NBTTagCompound compound) { + id = compound.getInteger("CategoryID"); + title = compound.getString("Title"); + associations.clear(); + NBTTagList list = compound.getTagList("Associations", 10); // compound tags + for (int i = 0; i < list.tagCount(); i++) { + NBTTagCompound assocTag = list.getCompoundTagAt(i); + MagicAssociation assoc = new MagicAssociation(); + assoc.magicId = assocTag.getInteger("MagicID"); + assoc.index = assocTag.getInteger("Index"); + assoc.priority = assocTag.getInteger("Priority"); + associations.put(assoc.magicId, assoc); + } + } + + public void writeNBT(NBTTagCompound compound) { + compound.setInteger("CategoryID", id); + compound.setString("Title", title); + NBTTagList list = new NBTTagList(); + for (MagicAssociation assoc : associations.values()) { + NBTTagCompound assocTag = new NBTTagCompound(); + assocTag.setInteger("MagicID", assoc.magicId); + assocTag.setInteger("Index", assoc.index); + assocTag.setInteger("Priority", assoc.priority); + list.appendTag(assocTag); + } + compound.setTag("Associations", list); + } +} diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerData.java b/src/main/java/noppes/npcs/controllers/data/PlayerData.java index 4f8731c96..041b15c0c 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerData.java @@ -1,6 +1,8 @@ package noppes.npcs.controllers.data; import kamkeel.npcs.addon.DBCAddon; +import kamkeel.npcs.controllers.ProfileController; +import kamkeel.npcs.controllers.data.Profile; import kamkeel.npcs.network.packets.data.AchievementPacket; import kamkeel.npcs.network.packets.data.ChatAlertPacket; import kamkeel.npcs.network.packets.request.party.PartyInvitePacket; @@ -17,6 +19,7 @@ import noppes.npcs.api.entity.ICustomNpc; import noppes.npcs.api.handler.*; import noppes.npcs.config.ConfigMain; import noppes.npcs.constants.EnumRoleType; +import noppes.npcs.controllers.CustomEffectController; import noppes.npcs.controllers.PartyController; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.entity.EntityCustomNpc; @@ -71,7 +74,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { public int profileSlot = 0; public void onLogin() { - //Continue playing animation for self when re-logging + // Continue playing animation for self when re-logging AnimationData animationData = this.animationData; if (animationData != null && animationData.isClientAnimating()) { Animation currentAnimation = animationData.currentClientAnimation; @@ -79,6 +82,13 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { animationData.viewAnimation(currentAnimation, animationData, compound, animationData.isClientAnimating(), currentAnimation.currentFrame, currentAnimation.currentFrameTime); } + + CustomEffectController controller = CustomEffectController.getInstance(); + UUID playerID = player.getPersistentID(); + // Only add if there are saved effects and none are registered yet. + if (!controller.playerEffects.containsKey(playerID)) { + controller.playerEffects.put(playerID, effectData.getEffects()); + } } public void onLogout() { @@ -365,6 +375,13 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { } public synchronized void save() { + // Don't Save this is a Modification of a Profile's PlayerData + Profile profile = ProfileController.Instance.getProfile(UUID.fromString(uuid)); + if(profile != null && profile.currentSlotId != this.profileSlot){ + ProfileController.Instance.saveOffline(profile, UUID.fromString(uuid)); + return; + } + final NBTTagCompound compound = getNBT(); final String filename; if(ConfigMain.DatFormat){ diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerEffect.java b/src/main/java/noppes/npcs/controllers/data/PlayerEffect.java index 6a02b4e06..45aa535f3 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerEffect.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerEffect.java @@ -1,7 +1,6 @@ package noppes.npcs.controllers.data; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.handler.data.IPlayerEffect; import noppes.npcs.controllers.CustomEffectController; diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerEffectData.java b/src/main/java/noppes/npcs/controllers/data/PlayerEffectData.java index 2675cd74e..93f69483f 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerEffectData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerEffectData.java @@ -2,6 +2,7 @@ package noppes.npcs.controllers.data; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; + import java.util.HashSet; import java.util.Iterator; import java.util.Map; diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerQuestData.java b/src/main/java/noppes/npcs/controllers/data/PlayerQuestData.java index 134f80312..cb91cfc7a 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerQuestData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerQuestData.java @@ -18,6 +18,7 @@ import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.PartyController; import noppes.npcs.controllers.PlayerDataController; +import noppes.npcs.controllers.PlayerQuestController; import noppes.npcs.controllers.QuestController; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.quests.QuestInterface; @@ -229,12 +230,7 @@ public class PlayerQuestData implements IPlayerQuestData { Quest quest = QuestController.Instance.quests.get(id); if (quest == null) return; - - if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY) - finishedQuests.put(quest.id, System.currentTimeMillis()); - else - finishedQuests.put(quest.id, parent.player.worldObj.getTotalWorldTime()); - + PlayerQuestController.setQuestFinished(quest, parent.player); parent.updateClient = true; } diff --git a/src/main/java/noppes/npcs/controllers/data/ProfileOptions.java b/src/main/java/noppes/npcs/controllers/data/ProfileOptions.java new file mode 100644 index 000000000..5605f1b63 --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/ProfileOptions.java @@ -0,0 +1,88 @@ +package noppes.npcs.controllers.data; + +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.api.handler.data.IProfileOptions; +import noppes.npcs.constants.EnumProfileSync; + +public class ProfileOptions implements IProfileOptions { + public boolean enableOptions = false; + + public EnumProfileSync cooldownControl = EnumProfileSync.Individual; + public EnumProfileSync completeControl = EnumProfileSync.Individual; + + public void readFromNBT(NBTTagCompound compound) + { + // Party Management + enableOptions = compound.getBoolean("EnableProfiles"); + if(enableOptions){ + cooldownControl = EnumProfileSync.values()[compound.getInteger("CooldownControl")]; + completeControl = EnumProfileSync.values()[compound.getInteger("CompleteControl")]; + } + else { + if(compound.hasKey("CooldownControl")){ + compound.removeTag("CooldownControl"); + } + if(compound.hasKey("CompleteControl")){ + compound.removeTag("CompleteControl"); + } + + cooldownControl = EnumProfileSync.Individual; + completeControl = EnumProfileSync.Individual; + } + } + public NBTTagCompound writeToNBT() + { + NBTTagCompound compound = new NBTTagCompound(); + compound.setBoolean("EnableProfiles", enableOptions); + if(enableOptions){ + compound.setInteger("CooldownControl", cooldownControl.ordinal()); + compound.setInteger("CompleteControl", completeControl.ordinal()); + } + else { + if(compound.hasKey("CooldownControl")){ + compound.removeTag("CooldownControl"); + } + if(compound.hasKey("CompleteControl")){ + compound.removeTag("CompleteControl"); + } + } + + return compound; + } + + @Override + public boolean hasProfileOptions() { + return enableOptions; + } + + @Override + public void setProfileOptions(boolean enable) { + this.enableOptions = enable; + } + + @Override + public void setCooldownControl(int profileType) { + if (profileType < 0 || profileType >= EnumProfileSync.values().length) { + return; + } + this.cooldownControl = EnumProfileSync.values()[profileType]; + } + + @Override + public int getCooldownControl(){ + return this.cooldownControl.ordinal(); + } + + @Override + public void setCompleteControl(int profileType) { + if (profileType < 0 || profileType >= EnumProfileSync.values().length) { + return; + } + this.completeControl = EnumProfileSync.values()[profileType]; + } + + @Override + public int getCompleteControl(){ + return this.completeControl.ordinal(); + } +} diff --git a/src/main/java/noppes/npcs/controllers/data/Quest.java b/src/main/java/noppes/npcs/controllers/data/Quest.java index 0643b20c9..aab2d65b9 100644 --- a/src/main/java/noppes/npcs/controllers/data/Quest.java +++ b/src/main/java/noppes/npcs/controllers/data/Quest.java @@ -1,5 +1,8 @@ package noppes.npcs.controllers.data; +import kamkeel.npcs.controllers.ProfileController; +import noppes.npcs.api.handler.data.ISlot; +import kamkeel.npcs.controllers.data.Profile; import kamkeel.npcs.network.packets.data.QuestCompletionPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -7,20 +10,19 @@ import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.*; import noppes.npcs.api.IContainer; import noppes.npcs.api.entity.IPlayer; +import noppes.npcs.api.handler.IPlayerData; +import noppes.npcs.api.handler.IPlayerQuestData; import noppes.npcs.api.handler.data.*; +import noppes.npcs.config.ConfigMain; +import noppes.npcs.constants.EnumProfileSync; import noppes.npcs.constants.EnumQuestCompletion; import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.controllers.QuestController; +import noppes.npcs.quests.*; import noppes.npcs.scripted.CustomNPCsException; import noppes.npcs.scripted.NpcAPI; -import noppes.npcs.quests.QuestDialog; -import noppes.npcs.quests.QuestInterface; -import noppes.npcs.quests.QuestItem; -import noppes.npcs.quests.QuestKill; -import noppes.npcs.quests.QuestLocation; -import noppes.npcs.quests.QuestManual; public class Quest implements ICompatibilty, IQuest { public int version = VersionCompatibility.ModRev; @@ -39,13 +41,14 @@ public class Quest implements ICompatibilty, IQuest { public String command = ""; public QuestInterface questInterface = new QuestItem(); + public long customCooldown = 0; public int rewardExp = 0; public NpcMiscInventory rewardItems = new NpcMiscInventory(9); public boolean randomReward = false; public FactionOptions factionOptions = new FactionOptions(); public PartyOptions partyOptions = new PartyOptions(); - + public ProfileOptions profileOptions = new ProfileOptions(); public void readNBT(NBTTagCompound compound) { id = compound.getInteger("Id"); @@ -73,11 +76,12 @@ public class Quest implements ICompatibilty, IQuest { completion = EnumQuestCompletion.values()[compound.getInteger("QuestCompletion")]; repeat = EnumQuestRepeat.values()[compound.getInteger("QuestRepeat")]; - + customCooldown = compound.getLong("CustomCooldown"); questInterface.readEntityFromNBT(compound); factionOptions.readFromNBT(compound.getCompoundTag("QuestFactionPoints")); partyOptions.readFromNBT(compound.getCompoundTag("PartyOptions")); + profileOptions.readFromNBT(compound.getCompoundTag("ProfileOptions")); mail.readNBT(compound.getCompoundTag("QuestMail")); } @@ -116,6 +120,7 @@ public class Quest implements ICompatibilty, IQuest { compound.setTag("Rewards", rewardItems.getToNBT()); compound.setString("QuestCommand", command); compound.setBoolean("RandomReward", randomReward); + compound.setLong("CustomCooldown", customCooldown); compound.setInteger("QuestCompletion", completion.ordinal()); compound.setInteger("QuestRepeat", repeat.ordinal()); @@ -123,6 +128,7 @@ public class Quest implements ICompatibilty, IQuest { this.questInterface.writeEntityToNBT(compound); compound.setTag("QuestFactionPoints", factionOptions.writeToNBT(new NBTTagCompound())); compound.setTag("PartyOptions", partyOptions.writeToNBT()); + compound.setTag("ProfileOptions", profileOptions.writeToNBT()); compound.setTag("QuestMail", mail.writeNBT()); return compound; @@ -155,23 +161,96 @@ public class Quest implements ICompatibilty, IQuest { return quest; } - public long getTimeUntilRepeat(EntityPlayer player) { - long questTime = PlayerDataController.Instance.getPlayerData(player).getQuestData().getLastCompletedTime(this.id); + public long getTimeUntilRepeat(EntityPlayer player) { + if(ConfigMain.ProfilesEnabled && profileOptions.enableOptions && profileOptions.cooldownControl == EnumProfileSync.Shared){ + Profile profile = ProfileController.Instance.getProfile(player); + IPlayer iPlayer = NoppesUtilServer.getIPlayer(player); + long timeRemaining = 0L; + for(ISlot slot : profile.getSlots().values()){ + IPlayerData playerData = ProfileController.Instance.getSlotPlayerData(iPlayer, slot.getId()); + IPlayerQuestData iPlayerQuestData = playerData.getQuestData(); + timeRemaining = Math.max(timeRemaining, getTimeUntilRepeatQuestData(player, iPlayerQuestData)); + } + return timeRemaining; + } + IPlayerQuestData questData = PlayerDataController.Instance.getPlayerData(player).getQuestData(); + return getTimeUntilRepeatQuestData(player, questData); + } - switch (repeat) { - case MCDAILY: - return Math.max(0, (questTime + 24000 - player.worldObj.getTotalWorldTime()) * 50); - case MCWEEKLY: - return Math.max(0, (questTime + 168000 - player.worldObj.getTotalWorldTime()) * 50); - case RLDAILY: - return Math.max(0, questTime + 86400000 - System.currentTimeMillis()); - case RLWEEKLY: - return Math.max(0, questTime + 604800000 - System.currentTimeMillis()); - } - return 0L; - } + public long getTimeUntilRepeatQuestData(EntityPlayer player, IPlayerQuestData questData){ + long questTime = questData.getLastCompletedTime(this.id); - @Override + switch (repeat) { + case MCDAILY: { + long now = player.worldObj.getTotalWorldTime(); + long allowedTicks = 24000; + // If questTime is in the future and the excess is greater than allowed, reset it. + if (questTime > now && (questTime - now) > allowedTicks) { + questTime = now; + questData.setLastCompletedTime(this.id, questTime); + } + long remainingTicks = questTime + allowedTicks - now; + return Math.max(0, remainingTicks * 50); + } + case MCWEEKLY: { + long now = player.worldObj.getTotalWorldTime(); + long allowedTicks = 168000; + if (questTime > now && (questTime - now) > allowedTicks) { + questTime = now; + questData.setLastCompletedTime(this.id, questTime); + } + long remainingTicks = questTime + allowedTicks - now; + return Math.max(0, remainingTicks * 50); + } + case RLDAILY: { + long now = System.currentTimeMillis(); + long allowedMillis = 86400000; + if (questTime > now && (questTime - now) > allowedMillis) { + questTime = now; + questData.setLastCompletedTime(this.id, questTime); + } + long remainingMillis = questTime + allowedMillis - now; + return Math.max(0, remainingMillis); + } + case RLWEEKLY: { + long now = System.currentTimeMillis(); + long allowedMillis = 604800000; + if (questTime > now && (questTime - now) > allowedMillis) { + questTime = now; + questData.setLastCompletedTime(this.id, questTime); + } + long remainingMillis = questTime + allowedMillis - now; + return Math.max(0, remainingMillis); + } + case MCCUSTOM: { + // For MCCUSTOM, customCooldown is assumed to be defined in ticks. + long now = player.worldObj.getTotalWorldTime(); + long allowedTicks = this.customCooldown; + if (questTime > now && (questTime - now) > allowedTicks) { + questTime = now; + questData.setLastCompletedTime(this.id, questTime); + } + long remainingTicks = questTime + allowedTicks - now; + return Math.max(0, remainingTicks * 50); + } + case RLCUSTOM: { + // For RLCUSTOM, customCooldown is assumed to be in milliseconds. + long now = System.currentTimeMillis(); + long allowedMillis = this.customCooldown; + if (questTime > now && (questTime - now) > allowedMillis) { + questTime = now; + questData.setLastCompletedTime(this.id, questTime); + } + long remainingMillis = questTime + allowedMillis - now; + return Math.max(0, remainingMillis); + } + default: + return 0L; + } + } + + + @Override public int getVersion() { return version; } @@ -289,4 +368,16 @@ public class Quest implements ICompatibilty, IQuest { public IPartyOptions getPartyOptions() { return this.partyOptions; } + + public IProfileOptions getProfileOptions() { + return this.profileOptions; + } + + public long getCustomCooldown() { + return this.customCooldown; + } + + public void setCustomCooldown(long newCooldown) { + this.customCooldown = newCooldown; + } } diff --git a/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java b/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java index 02f7919a7..2b6291bd8 100644 --- a/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java +++ b/src/main/java/noppes/npcs/controllers/data/RecipeAnvil.java @@ -5,7 +5,6 @@ import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.handler.data.IAnvilRecipe; -import noppes.npcs.controllers.data.Availability; public class RecipeAnvil implements IAnvilRecipe { public int id = -1; diff --git a/src/main/java/noppes/npcs/items/ItemNpcTool.java b/src/main/java/noppes/npcs/items/ItemNpcTool.java index fd7e49c9d..bc245e08f 100644 --- a/src/main/java/noppes/npcs/items/ItemNpcTool.java +++ b/src/main/java/noppes/npcs/items/ItemNpcTool.java @@ -31,7 +31,7 @@ public class ItemNpcTool extends Item { // Define our tool types based on metadata: // meta 0: Hammer, meta 1: Paintbrush, meta 2: Wrench - public static final String[] toolTypes = new String[] {"hammer", "paintbrush", "wrench"}; + public static final String[] toolTypes = new String[] {"hammer", "paintbrush"}; public static String BRUSH_COLOR_TAG = "BrushColor"; @SideOnly(Side.CLIENT) @@ -84,7 +84,7 @@ public class ItemNpcTool extends Item { if(world.isRemote) return stack; - if(isPaintbrush(stack) && !player.isSneaking()){ + if(isPaintbrush(stack) && player.isSneaking()){ if(CustomNpcsPermissions.hasPermission(player, CustomNpcsPermissions.PAINTBRUSH_GUI)){ NoppesUtil.requestOpenGUI(EnumGuiType.Paintbrush); } @@ -107,13 +107,7 @@ public class ItemNpcTool extends Item { TileEntity tile = world.getTileEntity(x, y, z); if(tile instanceof TileColorable) { - if(player.isSneaking()){ - int color = ((TileColorable) tile).color; - PacketClient.sendClient(new ColorBrushPacket(color)); - } - else { - PacketClient.sendClient(new ColorSetPacket(x, y, z)); - } + PacketClient.sendClient(new ColorSetPacket(x, y, z)); return true; } } @@ -121,6 +115,28 @@ public class ItemNpcTool extends Item { return false; } + public boolean onBlockStartBreak(ItemStack itemstack, int x, int y, int z, EntityPlayer player) + { + if(!player.worldObj.isRemote) + return true; + + if(isPaintbrush(itemstack)) { + Block block = player.worldObj.getBlock(x, y, z); + if(block instanceof BlockTallLamp || block instanceof BlockBanner){ + int meta = player.worldObj.getBlockMetadata(x, y, z); + if(meta >= 7) + y--; + } + + TileEntity tile = player.worldObj.getTileEntity(x, y, z); + if(tile instanceof TileColorable) { + int color = ((TileColorable) tile).color; + PacketClient.sendClient(new ColorBrushPacket(color)); + } + } + + return true; + } public static boolean isPaintbrush(ItemStack itemStack){ return itemStack.getItemDamage() == 1; diff --git a/src/main/java/noppes/npcs/quests/QuestManual.java b/src/main/java/noppes/npcs/quests/QuestManual.java index 9beb70a66..2bac92bef 100644 --- a/src/main/java/noppes/npcs/quests/QuestManual.java +++ b/src/main/java/noppes/npcs/quests/QuestManual.java @@ -2,7 +2,6 @@ package noppes.npcs.quests; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.StatCollector; import noppes.npcs.NBTTags; import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.handler.data.IQuestObjective; diff --git a/src/main/java/noppes/npcs/scripted/NpcAPI.java b/src/main/java/noppes/npcs/scripted/NpcAPI.java index e68dde801..1b5df256e 100644 --- a/src/main/java/noppes/npcs/scripted/NpcAPI.java +++ b/src/main/java/noppes/npcs/scripted/NpcAPI.java @@ -1,8 +1,8 @@ package noppes.npcs.scripted; import cpw.mods.fml.common.eventhandler.EventBus; -import cpw.mods.fml.relauncher.Side; import foxz.command.ScriptedCommand; +import kamkeel.npcs.controllers.ProfileController; import net.minecraft.block.Block; import net.minecraft.command.CommandHandler; import net.minecraft.entity.Entity; @@ -31,7 +31,6 @@ import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.biome.BiomeGenBase; import noppes.npcs.CustomNpcs; -import noppes.npcs.EventHooks; import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.*; import noppes.npcs.api.entity.ICustomNpc; @@ -50,7 +49,10 @@ import noppes.npcs.config.ConfigScript; import noppes.npcs.constants.EnumAnimationPart; import noppes.npcs.containers.ContainerNpcInterface; import noppes.npcs.controllers.*; -import noppes.npcs.controllers.data.*; +import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.Frame; +import noppes.npcs.controllers.data.FramePart; +import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.entity.EntityProjectile; @@ -240,6 +242,10 @@ public class NpcAPI extends AbstractNpcAPI { public INaturalSpawnsHandler getNaturalSpawns() { return SpawnController.Instance; } + public IProfileHandler getProfileHandler() { return ProfileController.Instance; } + + public ICustomEffectHandler getCustomEffectHandler() { return CustomEffectController.Instance; } + public ITransportHandler getLocations() { return TransportController.getInstance(); } diff --git a/src/main/java/noppes/npcs/scripted/ScriptWorld.java b/src/main/java/noppes/npcs/scripted/ScriptWorld.java index d19a2d27d..9921cf226 100644 --- a/src/main/java/noppes/npcs/scripted/ScriptWorld.java +++ b/src/main/java/noppes/npcs/scripted/ScriptWorld.java @@ -7,15 +7,11 @@ import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTBase.NBTPrimitive; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagString; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntitySign; import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.WorldServer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.BlockSnapshot; @@ -30,7 +26,6 @@ import noppes.npcs.api.handler.data.ISound; import noppes.npcs.api.item.IItemStack; import noppes.npcs.api.scoreboard.IScoreboard; import noppes.npcs.blocks.tiles.TileBigSign; -import noppes.npcs.controllers.ScriptController; import noppes.npcs.controllers.ServerCloneController; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.scripted.scoreboard.ScriptScoreboard; diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java b/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java index 86485c5b6..485e9cc21 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java @@ -1,5 +1,6 @@ package noppes.npcs.scripted.entity; +import kamkeel.npcs.controllers.ProfileController; import kamkeel.npcs.network.PacketHandler; import kamkeel.npcs.network.packets.data.AchievementPacket; import kamkeel.npcs.network.packets.data.ChatAlertPacket; @@ -18,7 +19,10 @@ import net.minecraft.util.ChatStyle; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.WorldSettings; -import noppes.npcs.*; +import noppes.npcs.CustomNpcsPermissions; +import noppes.npcs.NoppesStringUtils; +import noppes.npcs.NoppesUtilPlayer; +import noppes.npcs.NoppesUtilServer; import noppes.npcs.api.*; import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IPlayer; @@ -31,7 +35,9 @@ import noppes.npcs.api.handler.data.ISound; import noppes.npcs.api.item.IItemStack; import noppes.npcs.api.overlay.ICustomOverlay; import noppes.npcs.compat.PixelmonHelper; +import noppes.npcs.config.ConfigMain; import noppes.npcs.config.ConfigScript; +import noppes.npcs.constants.EnumProfileSync; import noppes.npcs.constants.EnumQuestRepeat; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.containers.ContainerCustomGui; @@ -281,10 +287,7 @@ public class ScriptPlayer extends ScriptLivingBase if (quest == null) return; PlayerData data = PlayerData.get(player); - if(quest.repeat == EnumQuestRepeat.RLDAILY || quest.repeat == EnumQuestRepeat.RLWEEKLY) - data.questData.finishedQuests.put(quest.id, System.currentTimeMillis()); - else - data.questData.finishedQuests.put(quest.id, player.worldObj.getTotalWorldTime()); + PlayerQuestController.setQuestFinishedUtil(player, quest, data.questData); data.updateClient = true; } diff --git a/src/main/java/noppes/npcs/scripted/gui/ScriptGuiItemSlot.java b/src/main/java/noppes/npcs/scripted/gui/ScriptGuiItemSlot.java index b33e2f204..8e48a585b 100644 --- a/src/main/java/noppes/npcs/scripted/gui/ScriptGuiItemSlot.java +++ b/src/main/java/noppes/npcs/scripted/gui/ScriptGuiItemSlot.java @@ -1,11 +1,8 @@ package noppes.npcs.scripted.gui; import net.minecraft.inventory.Slot; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import noppes.npcs.api.gui.IItemSlot; import noppes.npcs.api.item.IItemStack; -import noppes.npcs.scripted.NpcAPI; public class ScriptGuiItemSlot extends ScriptGuiComponent implements IItemSlot { IItemStack stack; diff --git a/src/main/java/noppes/npcs/scripted/item/ScriptItemStack.java b/src/main/java/noppes/npcs/scripted/item/ScriptItemStack.java index 5b15da052..11920d809 100644 --- a/src/main/java/noppes/npcs/scripted/item/ScriptItemStack.java +++ b/src/main/java/noppes/npcs/scripted/item/ScriptItemStack.java @@ -16,8 +16,6 @@ import net.minecraftforge.common.IPlantable; import noppes.npcs.NoppesUtilPlayer; import noppes.npcs.api.INbt; import noppes.npcs.api.item.IItemStack; -import noppes.npcs.controllers.LinkedItemController; -import noppes.npcs.controllers.data.LinkedItem; import noppes.npcs.items.ItemLinked; import noppes.npcs.items.ItemScripted; import noppes.npcs.scripted.CustomNPCsException; diff --git a/src/main/java/tconstruct/client/tabs/InventoryTabCustomNpc.java b/src/main/java/tconstruct/client/tabs/InventoryTabCustomNpc.java index 888bc77f1..983c2d495 100644 --- a/src/main/java/tconstruct/client/tabs/InventoryTabCustomNpc.java +++ b/src/main/java/tconstruct/client/tabs/InventoryTabCustomNpc.java @@ -1,6 +1,5 @@ package tconstruct.client.tabs; -import kamkeel.npcs.addon.client.DBCClient; import net.minecraft.client.Minecraft; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; @@ -17,8 +16,6 @@ public class InventoryTabCustomNpc extends AbstractTab { @Override public void onTabClicked() { - - Thread t = new Thread(){ @Override public void run(){ @@ -27,24 +24,7 @@ public class InventoryTabCustomNpc extends AbstractTab { } catch (InterruptedException e) { e.printStackTrace(); } - Minecraft mc = Minecraft.getMinecraft(); - switch (GuiCNPCInventory.activeTab){ - case 0: - mc.displayGuiScreen(new GuiQuestLog()); - break; - case 1: - mc.displayGuiScreen(new GuiParty()); - break; - case 2: - mc.displayGuiScreen(new GuiFaction()); - break; - case 3: - mc.displayGuiScreen(new GuiSettings()); - break; - case 4: - mc.displayGuiScreen(DBCClient.Instance.inventoryGUI()); - break; - } + tabHelper(); } }; t.start(); @@ -54,4 +34,24 @@ public class InventoryTabCustomNpc extends AbstractTab { public boolean shouldAddToList() { return true; } + + public static void tabHelper(){ + Minecraft mc = Minecraft.getMinecraft(); + int tab = GuiCNPCInventory.activeTab; + if(tab == -100){ + mc.displayGuiScreen(new GuiQuestLog()); + } + if(tab == -101){ + mc.displayGuiScreen(new GuiParty()); + } + if(tab == -102){ + mc.displayGuiScreen(new GuiFaction()); + } + if(tab == -103){ + mc.displayGuiScreen(new GuiSettings()); + } + if(tab == -104){ + mc.displayGuiScreen(new GuiProfiles()); + } + } } diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index b7723ab04..2e118025d 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -58,6 +58,7 @@ tile.npcScripted.name=Scripted Block gui.delete=Are you sure you want to delete this? gui.add=Add +gui.view=View gui.remove=Remove gui.save=Save gui.name=Name @@ -148,6 +149,10 @@ gui.sure=Are you sure? gui.available=Requirements Met gui.items=Items gui.npcs=NPCs +gui.change=Change +gui.create=Create +gui.rename=Rename +gui.playerMap=Regen PlayerMap party.accept=Accept party.allowParty=Allow Partying @@ -205,6 +210,7 @@ settings.dialogSound=Dialog Sound settings.dialogSpeed=Dialog Speed settings.chatAlerts=Chat Alerts settings.bannerAlerts=Banner Alerts +settings.effectsBar=Hide Effects Bar settings.alignmentX=Alignment X settings.alignmentY=Alignment Y settings.trackScale=Tracking Scale @@ -249,12 +255,13 @@ mailbox.name=Mailbox mailbox.sender=Sender mailbox.read=Read mailbox.timesend=%s ago -mailbox.day=day -mailbox.days=days -mailbox.hour=hour -mailbox.hours=hours -mailbox.minute=minute -mailbox.minutes=minutes +mailbox.day=Day +mailbox.days=Days +mailbox.hour=Hour +mailbox.hours=Hours +mailbox.minute=Minute +mailbox.minutes=Minutes +mailbox.seconds=Seconds mailbox.username=Username mailbox.subject=Subject mailbox.send=Send @@ -657,6 +664,9 @@ quest.mcdaily=MC Daily quest.mcweekly=MC Weekly quest.rldaily=RL Daily quest.rlweekly=RL Weekly +quest.rlcustom=RL Custom +quest.mccustom=MC Custom +quest.profile=Profile Options quest.instant=Instant Complete quest.npc=Complete by npc quest.next=Next Quest @@ -754,6 +764,10 @@ item.npcMounter.name=Mounter item.npcTeleporter.name=Teleporter item.npcScripter.name=Scripter item.scripted_item.name=Scripted Item +item.linked_item.name=Linked Item +item.npcTool.hammer.name=Npc Hammer +item.npcTool.paintbrush.name=Npc Brush + item.npcBanjo.name=Banjo item.npcViolin.name=Violin @@ -1303,3 +1317,15 @@ effect.editor.xPos=X Pos effect.editor.yPos=Y Pos effect.editor.lossOnDeath=Loss on Death +profile.lastLoaded=Last Loaded +profile.info.quest.active=Quests Active +profile.info.quest.finished=Quests Finished +profile.info.dialog.read=Dialogs Read +profile.change.message=Do you want to change? +profile.create.message=Creating a new profile will change you to it. +profile.rename.message=Do you want to rename your slot? +profile.operation.error=There was an error in your request +profile.enableOptions=Enable Options +profile.completion=Completion +profile.cooldown=Cooldown +profile.individual=Individual diff --git a/src/main/resources/assets/customnpcs/textures/gui/icons.png b/src/main/resources/assets/customnpcs/textures/gui/icons.png index a0bd71c26..49c1b77e9 100644 Binary files a/src/main/resources/assets/customnpcs/textures/gui/icons.png and b/src/main/resources/assets/customnpcs/textures/gui/icons.png differ diff --git a/src/main/resources/assets/customnpcs/textures/items/npcBrushHair.png b/src/main/resources/assets/customnpcs/textures/items/npcBrushHair.png new file mode 100644 index 000000000..f31bfc0f3 Binary files /dev/null and b/src/main/resources/assets/customnpcs/textures/items/npcBrushHair.png differ diff --git a/src/main/resources/assets/customnpcs/textures/items/npcBrushHandle.png b/src/main/resources/assets/customnpcs/textures/items/npcBrushHandle.png new file mode 100644 index 000000000..d15bd92c5 Binary files /dev/null and b/src/main/resources/assets/customnpcs/textures/items/npcBrushHandle.png differ diff --git a/src/main/resources/assets/customnpcs/textures/items/paintbrush_brush.png b/src/main/resources/assets/customnpcs/textures/items/paintbrush_brush.png deleted file mode 100644 index 7e6bec2d8..000000000 Binary files a/src/main/resources/assets/customnpcs/textures/items/paintbrush_brush.png and /dev/null differ diff --git a/src/main/resources/assets/customnpcs/textures/items/paintbrush_handle.png b/src/main/resources/assets/customnpcs/textures/items/paintbrush_handle.png deleted file mode 100644 index 1a60a0ad0..000000000 Binary files a/src/main/resources/assets/customnpcs/textures/items/paintbrush_handle.png and /dev/null differ