From 734936d88201a6eb1dad292a907265773a73376c Mon Sep 17 00:00:00 2001 From: unurled Date: Mon, 29 Apr 2024 22:26:06 +0200 Subject: [PATCH] command to spawn an entity --- build.gradle.kts | 2 +- .../sr/commands/CommandManager.java | 2 + .../sr/commands/admin/SpawnEntityCommand.java | 176 ++++++++++++++++++ .../sr/components/entity/EntityManager.java | 7 + .../sr/components/entity/Spawner.java | 28 +++ src/main/resources/plugin.yml | 5 + 6 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/unurled/sacredrealms/sr/commands/admin/SpawnEntityCommand.java create mode 100644 src/main/java/me/unurled/sacredrealms/sr/components/entity/Spawner.java diff --git a/build.gradle.kts b/build.gradle.kts index 8f59332..f6f40e6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ description = "The main SR plugin." val mcVersion = "1.20.5-R0.1-SNAPSHOT" val redisVersion = "5.2.0-beta1" -val invuiVersion = "1.26" +val invuiVersion = "1.30" val javaVersion = 21 diff --git a/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java b/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java index a2190dc..96a294e 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/commands/CommandManager.java @@ -9,6 +9,7 @@ import me.unurled.sacredrealms.sr.commands.admin.ClientBuildCommand; import me.unurled.sacredrealms.sr.commands.admin.EntityTypeCommand; import me.unurled.sacredrealms.sr.commands.admin.ItemCommand; import me.unurled.sacredrealms.sr.commands.admin.LevelCommand; +import me.unurled.sacredrealms.sr.commands.admin.SpawnEntityCommand; import me.unurled.sacredrealms.sr.commands.player.ResetAdventureCommand; import me.unurled.sacredrealms.sr.managers.Manager; import org.bukkit.command.PluginCommand; @@ -43,6 +44,7 @@ public class CommandManager extends Manager { registerCommand("entitytype", EntityTypeCommand.class); registerCommand("item", ItemCommand.class); registerCommand("treasure", ItemCommand.class); + registerCommand("spawnentity", SpawnEntityCommand.class); registerCommand("resetadventure", ResetAdventureCommand.class); } diff --git a/src/main/java/me/unurled/sacredrealms/sr/commands/admin/SpawnEntityCommand.java b/src/main/java/me/unurled/sacredrealms/sr/commands/admin/SpawnEntityCommand.java new file mode 100644 index 0000000..74861ca --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/commands/admin/SpawnEntityCommand.java @@ -0,0 +1,176 @@ +package me.unurled.sacredrealms.sr.commands.admin; + +import static me.unurled.sacredrealms.sr.utils.Component.NO_PERMISSION; +import static me.unurled.sacredrealms.sr.utils.Component.textComp; + +import java.util.List; +import me.unurled.sacredrealms.sr.components.entity.EntityManager; +import me.unurled.sacredrealms.sr.components.entity.SREntityType; +import me.unurled.sacredrealms.sr.managers.Manager; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SpawnEntityCommand implements TabExecutor { + + private static final String USAGE = + "Usage: /spawnentity [amount] [x] [y] [z] " + "[world]"; + + /** + * Executes the given command, returning its success.
+ * If false is returned, then the "usage" plugin.yml entry for this command (if defined) will be + * sent to the player. + * + * @param sender Source of the command + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args Passed command arguments + * @return true if a valid command, otherwise false + */ + @Override + public boolean onCommand( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String label, + @NotNull String[] args) { + if (!sender.hasPermission("sr.spawn-entity")) { + sender.sendMessage(textComp(NO_PERMISSION)); + return true; + } + + if (args.length == 0) { + sender.sendMessage(USAGE); + return true; + } + double x; + double y; + double z; + World world; + if (args.length == 6) { + if (sender instanceof Player p) { + if (args[2].equals("~")) { + x = p.getLocation().getX(); + } else { + try { + x = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid x location."); + return true; + } + } + if (args[3].equals("~")) { + y = p.getLocation().getX(); + } else { + try { + y = Double.parseDouble(args[3]); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid y location."); + return true; + } + } + if (args[4].equals("~")) { + z = p.getLocation().getX(); + } else { + try { + z = Double.parseDouble(args[4]); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid z location."); + return true; + } + } + world = p.getWorld(); + } else { + try { + x = Double.parseDouble(args[2]); + y = Double.parseDouble(args[3]); + z = Double.parseDouble(args[4]); + world = sender.getServer().getWorld(args[5]); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid location."); + return true; + } + } + } else { + if (!(sender instanceof Player player)) { + sender.sendMessage("You must set the location if you are not a player."); + return true; + } + x = player.getLocation().getX(); + y = player.getLocation().getY(); + z = player.getLocation().getZ(); + world = player.getWorld(); + } + + int amount = 1; + if (args.length > 1 && (args.length < 5 || args.length > 6)) { + try { + amount = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + sender.sendMessage("Invalid amount."); + return true; + } + } + + if (world == null) { + sender.sendMessage("Invalid world."); + return true; + } + + // spawn entity + EntityManager em = Manager.getInstance(EntityManager.class); + if (em == null) { + sender.sendMessage("EntityManager is null."); + return true; + } + SREntityType type = em.getType(args[0]); + if (type == null) { + sender.sendMessage("Invalid entity type."); + return true; + } + em.spawnEntity(type, amount, x, y, z, world); + + return true; + } + + /** + * Requests a list of possible completions for a command argument. + * + * @param sender Source of the command. For players tab-completing a command inside of a command + * block, this will be the player, not the command block. + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args The arguments passed to the command, including final partial argument to be + * completed + * @return A List of possible completions for the final argument, or null to default to the + * command executor + */ + @Override + public @Nullable List onTabComplete( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String label, + @NotNull String[] args) { + if (sender.hasPermission("sr.spawn-entity")) { + if (args.length == 1) { + return Manager.getInstance(EntityManager.class).getTypes().stream() + .map(SREntityType::getId) + .toList(); + } else if (args.length == 2) { + return List.of("1", "2", "3", "4", "5"); + } else if (args.length == 3) { + return List.of("~"); + } else if (args.length == 4) { + return List.of("~"); + } else if (args.length == 5) { + return List.of("~"); + } else if (args.length == 6) { + return sender.getServer().getWorlds().stream().map(World::getName).toList(); + } + } + return List.of(); + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java b/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java index ffd6a2f..ba3e886 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/entity/EntityManager.java @@ -14,6 +14,7 @@ import me.unurled.sacredrealms.sr.components.player.PotionEffectDeserializer; import me.unurled.sacredrealms.sr.data.DataHandler; import me.unurled.sacredrealms.sr.data.DataManager; import me.unurled.sacredrealms.sr.managers.Manager; +import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Mob; import org.bukkit.entity.Player; @@ -114,6 +115,7 @@ public class EntityManager extends Manager { return types; } + @Nullable public SREntityType getType(@NotNull String id) { for (SREntityType type : types) { if (type.getId().equals(id)) return type; @@ -121,6 +123,11 @@ public class EntityManager extends Manager { return null; } + public void spawnEntity( + @NotNull SREntityType type, int amount, double x, double y, double z, @NotNull World world) { + // spawn entity + } + @EventHandler public void onEntitySpawn(@NotNull EntitySpawnEvent e) { if (e.getEntity() instanceof Player) return; diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/entity/Spawner.java b/src/main/java/me/unurled/sacredrealms/sr/components/entity/Spawner.java new file mode 100644 index 0000000..40efcfa --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/components/entity/Spawner.java @@ -0,0 +1,28 @@ +package me.unurled.sacredrealms.sr.components.entity; + +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.SpawnerSpawnEvent; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +public class Spawner implements Listener { + + private static final NamespacedKey ENTITY_TYPE = new NamespacedKey("SR", "ENTITY_TYPE"); + + @EventHandler(priority = EventPriority.HIGH) + public static void onEntitySpawn(@NotNull SpawnerSpawnEvent e) { + // get entity pdc and check if it has a custom entity type + Entity entity = e.getEntity(); + PersistentDataContainer pdc = entity.getPersistentDataContainer(); + if (pdc.has(ENTITY_TYPE)) { + String entityType = pdc.get(ENTITY_TYPE, PersistentDataType.STRING); + if (entityType != null) return; + } + e.setCancelled(true); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 598e5f9..3bf0385 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -26,6 +26,9 @@ permissions: sr.entitytype: default: op description: When the player has permission for the command /entitytype + sr.spawn-entity: + default: op + description: When the player has permission for the command /spawn sr.admin.item: default: op description: When the player has permission for the command /item @@ -45,6 +48,8 @@ commands: description: Set the level of the player. entitytype: description: Create a new entity type. + spawnentity: + description: Spawn an entity. item: description: Create/modify an item. resetadventure: