Skip to content

Commit 7a6c636

Browse files
committed
Implemented a few subcommands
1 parent e2ac688 commit 7a6c636

File tree

14 files changed

+337
-136
lines changed

14 files changed

+337
-136
lines changed

src/main/java/de/pascalpex/pexnpc/PexNPC.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,18 @@ public static PlaceableNPC findNPCbyMinecraftID(int id) {
114114
return null;
115115
}
116116

117+
public static PlaceableNPC findNPCbyID(long id) {
118+
for(PlaceableNPC placeableNPC : PexNPC.getPlacedNpcs()) {
119+
if(placeableNPC.getNpc().getId() == id) {
120+
return placeableNPC;
121+
}
122+
}
123+
return null;
124+
}
125+
117126
private static void loadAllNPCs() {
127+
placedNPCs.clear();
128+
118129
List<NPC> npcs = NPCData.getAllNpcs();
119130
for(NPC npc : npcs) {
120131
PlaceableNPC placeableNPC = new PlaceableNPC(npc);
@@ -124,6 +135,14 @@ private static void loadAllNPCs() {
124135
Bukkit.getConsoleSender().sendMessage(MessageHandler.prefixedMini("Loaded <gold>" + npcs.size() + " <aqua>NPCs"));
125136
}
126137

138+
public static void reload() {
139+
NPCSender.removeEverything();
140+
141+
Config.load();
142+
NPCData.load();
143+
loadAllNPCs();
144+
}
145+
127146
public static String getPluginVersion() {
128147
return pluginVersion;
129148
}

src/main/java/de/pascalpex/pexnpc/PexNPCBootstrap.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package de.pascalpex.pexnpc;
22

33
import com.mojang.brigadier.arguments.IntegerArgumentType;
4+
import com.mojang.brigadier.arguments.LongArgumentType;
45
import com.mojang.brigadier.arguments.StringArgumentType;
56
import com.mojang.brigadier.tree.LiteralCommandNode;
67
import de.pascalpex.pexnpc.commands.IDSuggestionProvider;
78
import de.pascalpex.pexnpc.commands.NPCSlotArgument;
9+
import de.pascalpex.pexnpc.commands.subcommands.*;
810
import io.papermc.paper.command.brigadier.CommandSourceStack;
911
import io.papermc.paper.command.brigadier.Commands;
1012
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
@@ -20,28 +22,35 @@ public class PexNPCBootstrap implements PluginBootstrap {
2022
public void bootstrap(BootstrapContext context) {
2123
context.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> {
2224
IDSuggestionProvider idSuggestionProvider = new IDSuggestionProvider();
25+
HelpSubcommand helpSubcommand = new HelpSubcommand();
2326

24-
LiteralCommandNode<CommandSourceStack> advancedCommandRoot = Commands.literal("pexnpc").requires(commandSourceStack -> commandSourceStack.getSender().hasPermission("pexnpc.command"))
25-
.then(Commands.literal("help"))
26-
.then(Commands.literal("reload"))
27+
LiteralCommandNode<CommandSourceStack> advancedCommandRoot = Commands.literal("pexnpc")
28+
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission("pexnpc.command"))
29+
.then(Commands.literal("help")
30+
.executes(helpSubcommand))
31+
.then(Commands.literal("reload")
32+
.executes(new ReloadSubcommand()))
2733
.then(Commands.literal("create")
28-
.then(Commands.argument("name", StringArgumentType.greedyString())))
29-
.then(Commands.literal("list"))
34+
.then(Commands.argument("name", StringArgumentType.greedyString())
35+
.executes(new CreateSubcommand())))
36+
.then(Commands.literal("list")
37+
.executes(new ListSubcommand()))
3038
.then(Commands.literal("delete")
31-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
39+
.then(Commands.argument("id", LongArgumentType.longArg(1))
3240
.suggests(idSuggestionProvider::getSuggestions)))
3341
.then(Commands.literal("name")
34-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
42+
.then(Commands.argument("id", LongArgumentType.longArg(1))
3543
.suggests(idSuggestionProvider::getSuggestions)
3644
.then(Commands.argument("name", StringArgumentType.greedyString()))))
3745
.then(Commands.literal("movehere")
38-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
46+
.then(Commands.argument("id", LongArgumentType.longArg(1))
3947
.suggests(idSuggestionProvider::getSuggestions)))
4048
.then(Commands.literal("tp")
41-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
42-
.suggests(idSuggestionProvider::getSuggestions)))
49+
.then(Commands.argument("id", LongArgumentType.longArg(1))
50+
.suggests(idSuggestionProvider::getSuggestions)
51+
.executes(new TpSubcommand())))
4352
.then(Commands.literal("skin")
44-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
53+
.then(Commands.argument("id", LongArgumentType.longArg(1))
4554
.suggests(idSuggestionProvider::getSuggestions)
4655
.then(Commands.argument("skin", StringArgumentType.greedyString())
4756
.suggests((cmdContext, builder) -> {
@@ -51,20 +60,21 @@ public void bootstrap(BootstrapContext context) {
5160
return builder.buildFuture();
5261
}))))
5362
.then(Commands.literal("cmd")
54-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
63+
.then(Commands.argument("id", LongArgumentType.longArg(1))
5564
.suggests(idSuggestionProvider::getSuggestions)
5665
.then(Commands.argument("cmd", StringArgumentType.greedyString()))))
5766
.then(Commands.literal("msg")
58-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
67+
.then(Commands.argument("id", LongArgumentType.longArg(1))
5968
.suggests(idSuggestionProvider::getSuggestions)
6069
.then(Commands.argument("msg", StringArgumentType.greedyString()))))
6170
.then(Commands.literal("item")
62-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
71+
.then(Commands.argument("id", LongArgumentType.longArg(1))
6372
.suggests(idSuggestionProvider::getSuggestions)
6473
.then(Commands.argument("slot", new NPCSlotArgument()))))
6574
.then(Commands.literal("clear")
66-
.then(Commands.argument("id", IntegerArgumentType.integer(1))
75+
.then(Commands.argument("id", LongArgumentType.longArg(1))
6776
.suggests(idSuggestionProvider::getSuggestions)))
77+
.executes(helpSubcommand)
6878
.build();
6979

7080
commands.registrar().register(advancedCommandRoot);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package de.pascalpex.pexnpc.commands.subcommands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.arguments.StringArgumentType;
5+
import com.mojang.brigadier.context.CommandContext;
6+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
7+
import de.pascalpex.pexnpc.PexNPC;
8+
import de.pascalpex.pexnpc.files.NPCData;
9+
import de.pascalpex.pexnpc.npc.NPC;
10+
import de.pascalpex.pexnpc.npc.NPCSender;
11+
import de.pascalpex.pexnpc.npc.PlaceableNPC;
12+
import de.pascalpex.pexnpc.util.MessageHandler;
13+
import de.pascalpex.pexnpc.util.Util;
14+
import io.papermc.paper.command.brigadier.CommandSourceStack;
15+
import org.bukkit.command.CommandSender;
16+
import org.bukkit.entity.Entity;
17+
import org.bukkit.entity.Player;
18+
19+
public class CreateSubcommand implements Command<CommandSourceStack> {
20+
@Override
21+
public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
22+
CommandSender sender = context.getSource().getSender();
23+
Entity executor = context.getSource().getExecutor();
24+
25+
if(!(executor instanceof Player target)) {
26+
sender.sendMessage(MessageHandler.errorMessage("The command executor must be a player"));
27+
return SINGLE_SUCCESS;
28+
}
29+
30+
String name = StringArgumentType.getString(context, "name").replace("&", "§");
31+
if(!Util.checkName(name)) {
32+
sender.sendMessage(MessageHandler.errorMessage("The first 16 characters of this name are already in use"));
33+
return SINGLE_SUCCESS;
34+
}
35+
36+
NPC npc = new NPC(target.getLocation(), name, name, target);
37+
PlaceableNPC placeableNPC = new PlaceableNPC(npc);
38+
39+
NPCSender.sendNpcToPlayers(placeableNPC);
40+
PexNPC.getPlacedNpcs().add(placeableNPC);
41+
NPCData.saveNpc(npc);
42+
43+
sender.sendMessage(MessageHandler.prefixedMini("The NPC got created with the ID <gold>" + npc.getId()));
44+
45+
return SINGLE_SUCCESS;
46+
}
47+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package de.pascalpex.pexnpc.commands.subcommands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.context.CommandContext;
5+
import de.pascalpex.pexnpc.PexNPC;
6+
import de.pascalpex.pexnpc.util.MessageHandler;
7+
import io.papermc.paper.command.brigadier.CommandSourceStack;
8+
import org.bukkit.command.CommandSender;
9+
10+
public class HelpSubcommand implements Command<CommandSourceStack> {
11+
@Override
12+
public int run(CommandContext<CommandSourceStack> context) {
13+
CommandSender sender = context.getSource().getSender();
14+
15+
sender.sendMessage(MessageHandler.prefixedMini("PexNPC " + PexNPC.getPluginVersion() + " von Pascalpex"));
16+
sender.sendMessage(MessageHandler.prefixedMini("Verfügbare Befehle:"));
17+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc help <dark_gray>| <gold>Zeigt diese Seite an"));
18+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc reload <dark_gray>| <gold>Lädt die NPCs und Dateien neu"));
19+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc create [NAME] <dark_gray>| <gold>Erstellt einen NPC"));
20+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc list <dark_gray>| <gold>Zeigt alle NPCs und ihre IDs an"));
21+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc delete [ID] <dark_gray>| <gold>Löscht einen NPC"));
22+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc name [ID] [NAME] <dark_gray>| <gold>Ändert einen Namen"));
23+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc movehere [ID] <dark_gray>| <gold>Bewegt einen NPC zu dir"));
24+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc skin [ID] [NAME] <dark_gray>| <gold>Ändert den Skin"));
25+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc cmd [ID] [CMD] <dark_gray>| <gold>Gibt einem NPC einen Befehl"));
26+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc msg [ID] [MSG] <dark_gray>| <gold>Legt die Nachricht eines NPC fest"));
27+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc item [ID] [SLOT] <dark_gray>| <gold>Gibt einem NPC ein Item"));
28+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc clear [ID] <dark_gray>| <gold>Löscht die Befehle, Nachrichten und Items eines NPC"));
29+
sender.sendMessage(MessageHandler.prefixedMini("/pexnpc tp [ID] <dark_gray>| <gold>Teleportiert dich zu einem NPC"));
30+
return SINGLE_SUCCESS;
31+
}
32+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package de.pascalpex.pexnpc.commands.subcommands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.context.CommandContext;
5+
import de.pascalpex.pexnpc.PexNPC;
6+
import de.pascalpex.pexnpc.npc.NPC;
7+
import de.pascalpex.pexnpc.npc.PlaceableNPC;
8+
import de.pascalpex.pexnpc.util.MessageHandler;
9+
import io.papermc.paper.command.brigadier.CommandSourceStack;
10+
import net.kyori.adventure.text.Component;
11+
import net.kyori.adventure.text.event.ClickEvent;
12+
import net.kyori.adventure.text.event.HoverEvent;
13+
import org.bukkit.Location;
14+
import org.bukkit.command.CommandSender;
15+
import org.bukkit.entity.Player;
16+
17+
public class ListSubcommand implements Command<CommandSourceStack> {
18+
@Override
19+
public int run(CommandContext<CommandSourceStack> context) {
20+
CommandSender sender = context.getSource().getSender();
21+
22+
sender.sendMessage(MessageHandler.basicMessage("All loaded NPCs:"));
23+
for (PlaceableNPC placeableNPC : PexNPC.getPlacedNpcs()) {
24+
NPC npc = placeableNPC.getNpc();
25+
String name = npc.getName();
26+
Location loc = npc.getLocation();
27+
Component component = MessageHandler.prefixedMini("- ID:" + npc.getId() + " <gold>Name: <white>").append(MessageHandler.parseSection(name)).append(MessageHandler.parse(" <red>World: " + (loc.getWorld() == null ? "INVALID" : loc.getWorld().getName()) + " <green>X: " + loc.getBlockX() + " Y: " + loc.getBlockY() + " Z: " + loc.getBlockZ()));
28+
29+
if(sender instanceof Player) {
30+
component = component
31+
.hoverEvent(HoverEvent.showText(MessageHandler.parse("<aqua>Click to teleport\nID: <gold>" + npc.getId())))
32+
.clickEvent(ClickEvent.runCommand("/pexnpc tp " + npc.getId()));
33+
}
34+
sender.sendMessage(component);
35+
}
36+
37+
return SINGLE_SUCCESS;
38+
}
39+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package de.pascalpex.pexnpc.commands.subcommands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.context.CommandContext;
5+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
6+
import de.pascalpex.pexnpc.PexNPC;
7+
import de.pascalpex.pexnpc.util.MessageHandler;
8+
import io.papermc.paper.command.brigadier.CommandSourceStack;
9+
import org.bukkit.command.CommandSender;
10+
11+
public class ReloadSubcommand implements Command<CommandSourceStack> {
12+
@Override
13+
public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
14+
CommandSender sender = context.getSource().getSender();
15+
16+
PexNPC.reload();
17+
sender.sendMessage(MessageHandler.basicMessage("The plugin got reloaded"));
18+
return SINGLE_SUCCESS;
19+
}
20+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package de.pascalpex.pexnpc.commands.subcommands;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.arguments.LongArgumentType;
5+
import com.mojang.brigadier.context.CommandContext;
6+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
7+
import de.pascalpex.pexnpc.PexNPC;
8+
import de.pascalpex.pexnpc.files.Config;
9+
import de.pascalpex.pexnpc.npc.NPC;
10+
import de.pascalpex.pexnpc.npc.PlaceableNPC;
11+
import de.pascalpex.pexnpc.util.MessageHandler;
12+
import io.papermc.paper.command.brigadier.CommandSourceStack;
13+
import org.bukkit.GameMode;
14+
import org.bukkit.Sound;
15+
import org.bukkit.command.CommandSender;
16+
import org.bukkit.entity.Entity;
17+
import org.bukkit.entity.Player;
18+
19+
public class TpSubcommand implements Command<CommandSourceStack> {
20+
@Override
21+
public int run(CommandContext<CommandSourceStack> context) {
22+
CommandSender sender = context.getSource().getSender();
23+
Entity executor = context.getSource().getExecutor();
24+
long id = LongArgumentType.getLong(context, "id");
25+
26+
PlaceableNPC placeableNPC = PexNPC.findNPCbyID(id);
27+
if(placeableNPC == null) {
28+
sender.sendMessage(MessageHandler.errorMessage("The provided ID is invalid"));
29+
return SINGLE_SUCCESS;
30+
}
31+
NPC npc = placeableNPC.getNpc();
32+
33+
if(Config.getSpectatorModeOnTeleport() && executor instanceof Player player) {
34+
player.setGameMode(GameMode.SPECTATOR);
35+
}
36+
if(executor != null) {
37+
executor.teleport(npc.getLocation());
38+
}
39+
if(executor instanceof Player player) {
40+
player.playSound(player, Sound.ENTITY_ITEM_PICKUP, 1, 1);
41+
}
42+
43+
sender.sendMessage(MessageHandler.prefixedMini("Teleported to the NPC with the ID <gold>" + npc.getId()));
44+
return SINGLE_SUCCESS;
45+
}
46+
}

src/main/java/de/pascalpex/pexnpc/events/PacketReader.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,17 @@ public void readPacket(Player player, Packet<?> packet) {
6161
if (packet instanceof ServerboundInteractPacket serverboundInteractPacket) {
6262
int id = serverboundInteractPacket.getEntityId();
6363

64-
for (ServerPlayer npc : PexNPC.getPlacedNpcs().stream().map(PlaceableNPC::getServerPlayer).toList()) {
65-
if (npc.getId() == id) {
66-
if (!clicking.containsKey(player.getUniqueId())) {
67-
clicking.put(player.getUniqueId(), true);
68-
Bukkit.getScheduler().scheduleSyncDelayedTask(PexNPC.getInstance(), () -> {
69-
clicking.remove(player.getUniqueId());
70-
Bukkit.getPluginManager().callEvent(new RightClickNPC(player, npc));
71-
}, 1);
72-
}
64+
PlaceableNPC placeableNPC = PexNPC.findNPCbyMinecraftID(id);
65+
if(placeableNPC != null) {
66+
ServerPlayer serverPlayer = placeableNPC.getServerPlayer();
67+
if (!clicking.containsKey(player.getUniqueId())) {
68+
clicking.put(player.getUniqueId(), true);
69+
Bukkit.getScheduler().scheduleSyncDelayedTask(PexNPC.getInstance(), () -> {
70+
clicking.remove(player.getUniqueId());
71+
Bukkit.getPluginManager().callEvent(new RightClickNPC(player, serverPlayer));
72+
}, 1);
7373
}
7474
}
75-
7675
}
7776
}
78-
7977
}

src/main/java/de/pascalpex/pexnpc/files/NPCData.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import de.pascalpex.pexnpc.PexNPC;
44
import de.pascalpex.pexnpc.npc.NPC;
5+
import de.pascalpex.pexnpc.npc.NPCEquipment;
56
import de.pascalpex.pexnpc.npc.NPCSkin;
67
import org.bukkit.Bukkit;
78
import org.bukkit.Location;
@@ -65,12 +66,12 @@ public static void saveNpc(NPC npc) {
6566
config.set("npcs" + "." + id + ".location" + ".pitch", loc.getPitch());
6667
config.set("npcs" + "." + id + ".location" + ".yaw", loc.getYaw());
6768
config.set("npcs" + "." + id + ".location" + ".world", loc.getWorld().getName());
68-
config.set("npcs" + "." + id + ".items" + ".HAND", NPC.nullStack);
69-
config.set("npcs" + "." + id + ".items" + ".OFFHAND", NPC.nullStack);
70-
config.set("npcs" + "." + id + ".items" + ".HELMET", NPC.nullStack);
71-
config.set("npcs" + "." + id + ".items" + ".CHESTPLATE", NPC.nullStack);
72-
config.set("npcs" + "." + id + ".items" + ".LEGGINGS", NPC.nullStack);
73-
config.set("npcs" + "." + id + ".items" + ".BOOTS", NPC.nullStack);
69+
config.set("npcs" + "." + id + ".items" + ".HAND", NPCEquipment.EMPTY_STACK);
70+
config.set("npcs" + "." + id + ".items" + ".OFFHAND", NPCEquipment.EMPTY_STACK);
71+
config.set("npcs" + "." + id + ".items" + ".HELMET", NPCEquipment.EMPTY_STACK);
72+
config.set("npcs" + "." + id + ".items" + ".CHESTPLATE", NPCEquipment.EMPTY_STACK);
73+
config.set("npcs" + "." + id + ".items" + ".LEGGINGS", NPCEquipment.EMPTY_STACK);
74+
config.set("npcs" + "." + id + ".items" + ".BOOTS", NPCEquipment.EMPTY_STACK);
7475
config.set("npcs" + "." + id + ".skin" + ".texture", npc.getSkin().texture());
7576
config.set("npcs" + "." + id + ".skin" + ".signature", npc.getSkin().signature());
7677
save();
@@ -117,8 +118,9 @@ public static NPC getNpc(long id) {
117118
String skinSignature = config.getString("npcs" + "." + id + ".skin" + ".signature");
118119

119120
NPCSkin skin = new NPCSkin(skinTexture, skinSignature);
121+
NPCEquipment equipment = new NPCEquipment(handItem, offhandItem, helmetItem, chestplateItem, leggingsItem, bootsItem);
120122

121-
return new NPC(id, loc, name, skin, cmd, msg, handItem, offhandItem, helmetItem, chestplateItem, leggingsItem, bootsItem);
123+
return new NPC(id, loc, name, skin, cmd, msg, equipment);
122124
}
123125

124126
public static List<NPC> getAllNpcs() {

0 commit comments

Comments
 (0)