|
15 | 15 | import org.bukkit.inventory.EntityEquipment; |
16 | 16 | import org.bukkit.inventory.ItemStack; |
17 | 17 |
|
18 | | -import java.util.Arrays; |
19 | | -import java.util.Comparator; |
20 | | -import java.util.List; |
21 | | -import java.util.Map; |
| 18 | +import java.util.*; |
22 | 19 | import java.util.stream.Collectors; |
23 | 20 |
|
24 | 21 | public class NPCCommand { |
@@ -133,7 +130,7 @@ private void handleCreate(CommandContext ctx) { |
133 | 130 | .turnToPlayer(false) |
134 | 131 | .turnToPlayerDistance(3.0) |
135 | 132 | .attributes(new java.util.HashMap<>()) |
136 | | - .actions(new java.util.ArrayList<>()) |
| 133 | + .actions(new java.util.HashMap<>()) |
137 | 134 | .location(loc) |
138 | 135 | .build(); |
139 | 136 | npcManager.register(npc); |
@@ -170,7 +167,7 @@ private void handleCopy(CommandContext ctx) { |
170 | 167 | .turnToPlayer(orig.isTurnToPlayer()) |
171 | 168 | .turnToPlayerDistance(orig.getTurnToPlayerDistance()) |
172 | 169 | .attributes(new java.util.HashMap<>(orig.getAttributes())) |
173 | | - .actions(new java.util.ArrayList<>(orig.getActions())) |
| 170 | + .actions(new java.util.HashMap<>(orig.getActions())) |
174 | 171 | .location(orig.getLocation()) |
175 | 172 | .build(); |
176 | 173 | npcManager.register(copy); |
@@ -263,10 +260,12 @@ private void handleInfo(CommandContext ctx) { |
263 | 260 | if (npc.getActions().isEmpty()) { |
264 | 261 | textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.info.actions.empty", "<gold>│</gold> <gray>No actions defined.</gray>")); |
265 | 262 | } else { |
266 | | - for (String action : npc.getActions()) { |
267 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.info.actions.line", "<gold>│</gold> <gray>%action% (%trigger%)</gray>").replace("%action%", action) |
268 | | - .replace("%trigger%", action.split(" ")[0]) // Assuming the trigger is the first word in the action string |
269 | | - ); |
| 263 | + for (NPC.ClickType action : npc.getActions().keySet()) { |
| 264 | + textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.info.actions.line", "<gold>│</gold> <gray>%action% (%trigger%)</gray>").replace("%action%", npc.getActions().get(action).stream() |
| 265 | + // Aus jedem CommandAction nur den eigentlichen Befehl ziehen |
| 266 | + .map(NPC.CommandAction::getCommand) |
| 267 | + .collect(Collectors.joining(", ")) |
| 268 | + .replace("%trigger%", action.name()))); |
270 | 269 | } |
271 | 270 | } |
272 | 271 | textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.info.attributes.header", "<gold>│</gold> <gray>Attributes:</gray>")); |
@@ -843,55 +842,163 @@ private void handleTeleport(CommandContext ctx) { |
843 | 842 | } |
844 | 843 |
|
845 | 844 | private void handleAction(CommandContext ctx) { |
846 | | - if (ctx.args().length < 3) { |
847 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.usage", "%prefix% <red>Usage: /npc action (npc) add|remove|clear|list [params]</red>")); |
| 845 | + String[] args = ctx.args(); |
| 846 | + // /npc action <npcId> add|remove|clear|list [...] |
| 847 | + if (args.length < 2) { |
| 848 | + textManager.send(ctx.sender(), |
| 849 | + plugin.getMessagesFile() |
| 850 | + .getString("commands.npc.action.usage", |
| 851 | + "%prefix% <red>Usage: /npc action <npc> add|remove|clear|list [params]</red>")); |
848 | 852 | return; |
849 | 853 | } |
850 | | - String id = ctx.args()[0]; |
851 | | - String sub = ctx.args()[1]; |
852 | | - NPC npc = npcManager.getNpcs().get(id); |
853 | | - if (npc == null) { textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.not-found", "%prefix% <red>NPC '%name%' not found.</red>")); return; } |
854 | | - switch (sub.toLowerCase()) { |
855 | | - case "list": |
| 854 | + |
| 855 | + String id = args[0]; |
| 856 | + String sub = args[1].toLowerCase(); |
| 857 | + NPC npc = npcManager.getNpcs().get(id); |
| 858 | + |
| 859 | + if (npc == null) { |
| 860 | + textManager.send(ctx.sender(), |
| 861 | + plugin.getMessagesFile() |
| 862 | + .getString("commands.npc.action.not-found", |
| 863 | + "%prefix% <red>NPC '%name%' not found.</red>") |
| 864 | + .replace("%name%", id)); |
| 865 | + return; |
| 866 | + } |
| 867 | + |
| 868 | + switch (sub) { |
| 869 | + case "list" -> { |
856 | 870 | if (npc.getActions().isEmpty()) { |
857 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.list.empty", "%prefix% <yellow>NPC '%name%' has no actions.</yellow>").replace("%name%", id)); |
| 871 | + textManager.send(ctx.sender(), |
| 872 | + plugin.getMessagesFile() |
| 873 | + .getString("commands.npc.action.list.empty", |
| 874 | + "%prefix% <yellow>NPC '%name%' has no actions.</yellow>") |
| 875 | + .replace("%name%", id)); |
858 | 876 | } else { |
859 | | - for (String header : plugin.getMessagesFile().getStringList("commands.npc.action.list.header")) { |
860 | | - header = header.replace("%name%", id); |
861 | | - textManager.send(ctx.sender(), header); |
| 877 | + // Header |
| 878 | + for (String line : plugin.getMessagesFile().getStringList("commands.npc.action.list.header")) { |
| 879 | + textManager.send(ctx.sender(), line.replace("%name%", id)); |
862 | 880 | } |
863 | | - for (String action : npc.getActions()) { |
864 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.list.line", "<gold>│</gold> <gray>%action%</gray>").replace("%action%", action)); |
| 881 | + // Jede Click-Type einzeln listen |
| 882 | + for (NPC.ClickType click : npc.getActions().keySet()) { |
| 883 | + String joined = npc.getActions() |
| 884 | + .get(click) |
| 885 | + .stream() |
| 886 | + .map(ca -> ca.getActionType().name() + ":" + ca.getCommand()) |
| 887 | + .collect(Collectors.joining(", ")); |
| 888 | + String template = plugin.getMessagesFile() |
| 889 | + .getString("commands.npc.action.list.line", |
| 890 | + "<gold>│</gold> <gray>%trigger% – %action%</gray>"); |
| 891 | + String filled = template |
| 892 | + .replace("%trigger%", click.name()) |
| 893 | + .replace("%action%", joined); |
| 894 | + textManager.send(ctx.sender(), filled); |
865 | 895 | } |
866 | | - for (String footer : plugin.getMessagesFile().getStringList("commands.npc.action.list.footer")) { |
867 | | - footer = footer.replace("%name%", id); |
868 | | - textManager.send(ctx.sender(), footer); |
| 896 | + // Footer |
| 897 | + for (String line : plugin.getMessagesFile().getStringList("commands.npc.action.list.footer")) { |
| 898 | + textManager.send(ctx.sender(), line.replace("%name%", id)); |
869 | 899 | } |
870 | 900 | } |
871 | | - break; |
872 | | - case "clear": |
873 | | - npcManager.modify(id, n -> { n.getActions().clear(); return n; }); |
874 | | - npcManager.save(); |
875 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.clear.success", "%prefix% <green>All actions cleared for NPC '%name%'.</green>").replace("%name%", id)); |
876 | | - break; |
877 | | - case "add": |
878 | | - String action = ctx.args()[2]; |
879 | | - npcManager.modify(id, n -> { n.getActions().add(action); return n; }); |
| 901 | + } |
| 902 | + |
| 903 | + case "clear" -> { |
| 904 | + // Optional: /npc action <npc> clear [ClickType] |
| 905 | + if (args.length == 3) { |
| 906 | + try { |
| 907 | + NPC.ClickType click = NPC.ClickType.valueOf(args[2].toUpperCase()); |
| 908 | + npcManager.modify(id, n -> { n.getActions().remove(click); return n; }); |
| 909 | + } catch (IllegalArgumentException ex) { |
| 910 | + textManager.send(ctx.sender(), |
| 911 | + "<red>Unknown click type: " + args[2] + "</red>"); |
| 912 | + return; |
| 913 | + } |
| 914 | + } else { |
| 915 | + // Ohne ClickType → alle löschen |
| 916 | + npcManager.modify(id, n -> { n.getActions().clear(); return n; }); |
| 917 | + } |
880 | 918 | npcManager.save(); |
881 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.add.success", "%prefix% <green>Action '%action%' added to NPC '%name%'.</green>").replace("%action%", action).replace("%name%", id)); |
882 | | - break; |
883 | | - case "remove": |
884 | | - String rem = ctx.args()[2]; |
885 | | - npcManager.modify(id, n -> { n.getActions().remove(rem); return n; }); |
| 919 | + textManager.send(ctx.sender(), |
| 920 | + plugin.getMessagesFile() |
| 921 | + .getString("commands.npc.action.clear.success", |
| 922 | + "%prefix% <green>Actions cleared for NPC '%name%'.</green>") |
| 923 | + .replace("%name%", id)); |
| 924 | + } |
| 925 | + |
| 926 | + case "add" -> { |
| 927 | + // /npc action <npc> add <ClickType> <ActionType> <command...> |
| 928 | + if (args.length < 5) { |
| 929 | + textManager.send(ctx.sender(), |
| 930 | + "<red>Usage: /npc action " + id + " add <any_click|left_click|right_click> <player_command|console_command> <command...></red>"); |
| 931 | + return; |
| 932 | + } |
| 933 | + NPC.ClickType click; |
| 934 | + NPC.ActionType type; |
| 935 | + try { |
| 936 | + click = NPC.ClickType.valueOf(args[2].toUpperCase()); |
| 937 | + type = NPC.ActionType.valueOf(args[3].toUpperCase()); |
| 938 | + } catch (IllegalArgumentException ex) { |
| 939 | + textManager.send(ctx.sender(), |
| 940 | + "<red>Invalid click- or action-type!</red>"); |
| 941 | + return; |
| 942 | + } |
| 943 | + String command = String.join(" ", Arrays.copyOfRange(args, 4, args.length)); |
| 944 | + npcManager.modify(id, n -> { |
| 945 | + n.getActions() |
| 946 | + .computeIfAbsent(click, k -> new ArrayList<>()) |
| 947 | + .add(new NPC.CommandAction(type, command)); |
| 948 | + return n; |
| 949 | + }); |
886 | 950 | npcManager.save(); |
887 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.remove.success", "%prefix% <green>Action '%action%' removed from NPC '%name%'.</green>").replace("%action%", rem).replace("%name%", id)); |
888 | | - break; |
889 | | - default: |
890 | | - textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.action.usage", "%prefix% <red>Usage: /npc action (npc) add|remove|clear|list [params]</red>")); |
891 | | - break; |
| 951 | + textManager.send(ctx.sender(), |
| 952 | + plugin.getMessagesFile() |
| 953 | + .getString("commands.npc.action.add.success", |
| 954 | + "%prefix% <green>Action '%action%' added to NPC '%name%'.</green>") |
| 955 | + .replace("%action%", type.name() + ":" + command) |
| 956 | + .replace("%name%", id)); |
| 957 | + } |
| 958 | + |
| 959 | + case "remove" -> { |
| 960 | + // /npc action <npc> remove <ClickType> <index> |
| 961 | + if (args.length != 4) { |
| 962 | + textManager.send(ctx.sender(), |
| 963 | + "<red>Usage: /npc action " + id + " remove <any_click|left_click|right_click> <index></red>"); |
| 964 | + return; |
| 965 | + } |
| 966 | + NPC.ClickType click; |
| 967 | + int index; |
| 968 | + try { |
| 969 | + click = NPC.ClickType.valueOf(args[2].toUpperCase()); |
| 970 | + index = Integer.parseInt(args[3]); |
| 971 | + } catch (IllegalArgumentException ex) { |
| 972 | + textManager.send(ctx.sender(), |
| 973 | + "<red>Invalid click-type or index!</red>"); |
| 974 | + return; |
| 975 | + } |
| 976 | + final boolean removed = npcManager.getNpcs() |
| 977 | + .get(id) |
| 978 | + .removeAction(click, index); |
| 979 | + if (removed) { |
| 980 | + npcManager.save(); |
| 981 | + textManager.send(ctx.sender(), |
| 982 | + plugin.getMessagesFile() |
| 983 | + .getString("commands.npc.action.remove.success", |
| 984 | + "%prefix% <green>Action removed from NPC '%name%'.</green>") |
| 985 | + .replace("%name%", id)); |
| 986 | + } else { |
| 987 | + textManager.send(ctx.sender(), |
| 988 | + "<red>No action at index " + index + " for " + click.name() + "!</red>"); |
| 989 | + } |
| 990 | + } |
| 991 | + |
| 992 | + default -> { |
| 993 | + textManager.send(ctx.sender(), |
| 994 | + plugin.getMessagesFile() |
| 995 | + .getString("commands.npc.action.usage", |
| 996 | + "%prefix% <red>Usage: /npc action <npc> add|remove|clear|list [params]</red>")); |
| 997 | + } |
892 | 998 | } |
893 | 999 | } |
894 | 1000 |
|
| 1001 | + |
895 | 1002 | private void handleInteractionCooldown(CommandContext ctx) { |
896 | 1003 | if (ctx.args().length < 2) { |
897 | 1004 | textManager.send(ctx.sender(), plugin.getMessagesFile().getString("commands.npc.interaction_cooldown.usage", "%prefix% <red>Usage: /npc interaction_cooldown (npc) [disabled | ticks]</red>")); |
|
0 commit comments