Add GiveSpawner command and enhance spawner functionalities
Implemented the GiveSpawner command to allow players to receive specific mob spawners. Added validation and namespaced key handling for mob types and entities to ensure proper functionality when placing spawners. Refactored existing code to use the new EntityTypeChecker utility.
This commit is contained in:
parent
8d804c95ba
commit
9d39e4cc7a
|
|
@ -6,6 +6,7 @@ import com.alttd.custommobs.config.Messages;
|
|||
import com.alttd.custommobs.config.MobTypes;
|
||||
import com.alttd.custommobs.listeners.SpawnerListener;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
@Slf4j
|
||||
|
|
@ -15,16 +16,20 @@ public class Main extends JavaPlugin {
|
|||
public void onEnable() {
|
||||
log.info("Plugin enabled!");
|
||||
reloadConfigs();
|
||||
registerEvents();
|
||||
registerCommands();
|
||||
|
||||
NamespacedKey mobTypeKey = new NamespacedKey(this, "mob-type");
|
||||
NamespacedKey entityKey = new NamespacedKey(this, "entity-type");
|
||||
|
||||
registerEvents(mobTypeKey, entityKey);
|
||||
registerCommands(mobTypeKey, entityKey);
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
new CommandManager(this);
|
||||
private void registerCommands(NamespacedKey mobTypeKey, NamespacedKey entityKey) {
|
||||
new CommandManager(this, mobTypeKey, entityKey);
|
||||
}
|
||||
|
||||
private void registerEvents() {
|
||||
getServer().getPluginManager().registerEvents(new SpawnerListener(this), this);
|
||||
private void registerEvents(NamespacedKey mobTypeKey, NamespacedKey entityKey) {
|
||||
getServer().getPluginManager().registerEvents(new SpawnerListener(this, mobTypeKey, entityKey), this);
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package com.alttd.custommobs.commands;
|
||||
|
||||
import com.alttd.custommobs.Main;
|
||||
import com.alttd.custommobs.commands.subcommands.GiveSpawner;
|
||||
import com.alttd.custommobs.commands.subcommands.Spawn;
|
||||
import com.alttd.custommobs.config.Messages;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -19,7 +21,7 @@ import java.util.stream.Collectors;
|
|||
public class CommandManager implements CommandExecutor, TabExecutor {
|
||||
private final List<SubCommand> subCommands;
|
||||
|
||||
public CommandManager(Main main) {
|
||||
public CommandManager(Main main, @NotNull NamespacedKey mobTypeKey, @NotNull NamespacedKey entityKey) {
|
||||
PluginCommand command = main.getCommand("custommobs");
|
||||
if (command == null) {
|
||||
subCommands = null;
|
||||
|
|
@ -31,7 +33,8 @@ public class CommandManager implements CommandExecutor, TabExecutor {
|
|||
command.setAliases(List.of("cm"));
|
||||
|
||||
subCommands = Arrays.asList(
|
||||
new Spawn(main)
|
||||
new Spawn(main),
|
||||
new GiveSpawner(main, mobTypeKey, entityKey)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
package com.alttd.custommobs.commands.subcommands;
|
||||
|
||||
import com.alttd.custommobs.Main;
|
||||
import com.alttd.custommobs.abilities.MobType;
|
||||
import com.alttd.custommobs.commands.SubCommand;
|
||||
import com.alttd.custommobs.config.Messages;
|
||||
import com.alttd.custommobs.config.MobTypes;
|
||||
import com.alttd.custommobs.utility.EntityTypeChecker;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
public class GiveSpawner extends SubCommand {
|
||||
|
||||
private final Main main;
|
||||
private final NamespacedKey mobTypeKey;
|
||||
private final NamespacedKey entityKey;
|
||||
|
||||
public GiveSpawner(Main main, @NotNull NamespacedKey mobTypeKey, @NotNull NamespacedKey entityKey) {
|
||||
this.main = main;
|
||||
this.mobTypeKey = mobTypeKey;
|
||||
this.entityKey = entityKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
|
||||
return true;
|
||||
}
|
||||
if (args.length != 3) {
|
||||
return false;
|
||||
}
|
||||
Optional<MobType> optionalMobType = MobTypes.MOB_TYPES.get(args[1]);
|
||||
if (optionalMobType.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
EntityType entityType = EntityType.valueOf(args[2]);
|
||||
if (!entityType.isSpawnable() || !EntityTypeChecker.isMob(entityType)) {
|
||||
return false;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.info("DEBUG: Invalid mob type {}", args[2]);
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemStack spawner = new ItemStack(Material.SPAWNER);
|
||||
ItemMeta meta = spawner.getItemMeta();
|
||||
meta.displayName(MiniMessage.miniMessage().deserialize(Messages.GIVE_SPAWNER.SPAWNER_NAME, TagResolver.resolver(
|
||||
Placeholder.parsed("entity", args[2]),
|
||||
Placeholder.parsed("mob_type", args[1])
|
||||
)));
|
||||
PersistentDataContainer persistentDataContainer = meta.getPersistentDataContainer();
|
||||
persistentDataContainer.set(mobTypeKey, PersistentDataType.STRING, args[1]);
|
||||
persistentDataContainer.set(entityKey, PersistentDataType.STRING, args[2]);
|
||||
spawner.setItemMeta(meta);
|
||||
|
||||
if (!player.getInventory().addItem(spawner).isEmpty()) {
|
||||
player.sendRichMessage(Messages.GIVE_SPAWNER.FULL_INVENTORY);
|
||||
return true;
|
||||
}
|
||||
player.sendRichMessage(Messages.GIVE_SPAWNER.GIVEN, TagResolver.resolver(
|
||||
Placeholder.parsed("entity", args[2]),
|
||||
Placeholder.parsed("mob_type", args[1])
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "give_spawner";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||
return switch (args.length) {
|
||||
case 2 -> MobTypes.MOB_TYPES.getAllMobTypes();
|
||||
case 3 -> Arrays.stream(EntityType.values()).map(EntityType::name).toList();
|
||||
default -> List.of();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpMessage() {
|
||||
return Messages.HELP.GIVE_SPAWNER;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.alttd.custommobs.abilities.MobTypeApplier;
|
|||
import com.alttd.custommobs.commands.SubCommand;
|
||||
import com.alttd.custommobs.config.Messages;
|
||||
import com.alttd.custommobs.config.MobTypes;
|
||||
import com.alttd.custommobs.utility.EntityTypeChecker;
|
||||
import com.alttd.custommobs.utility.SpawnableTargetBlock;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.Bukkit;
|
||||
|
|
@ -46,7 +47,7 @@ public class Spawn extends SubCommand {
|
|||
log.info("DEBUG: Invalid mob type {}", args[2]);
|
||||
return false;
|
||||
}
|
||||
if (!entityType.isSpawnable() || !isMob(entityType)) {
|
||||
if (!entityType.isSpawnable() || !EntityTypeChecker.isMob(entityType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -87,22 +88,6 @@ public class Spawn extends SubCommand {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isMob(EntityType entityType) {
|
||||
if (entityType == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Class<? extends Entity> entityClass = entityType.getEntityClass();
|
||||
if (entityClass == null) {
|
||||
return false;
|
||||
}
|
||||
Class<?> mobEntityClass = Class.forName("org.bukkit.entity." + entityClass.getSimpleName());
|
||||
return Mob.class.isAssignableFrom(mobEntityClass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnMob(World world, Location location, EntityType entityType, MobType mobType) {
|
||||
if (entityType.getEntityClass() == null) {
|
||||
log.warn("Tried to spawn entity with null entity class {}", entityType.name());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.alttd.custommobs.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
|
@ -29,12 +30,14 @@ public class Messages extends AbstractConfig {
|
|||
public static String HELP_MESSAGE_WRAPPER = "<gold>Main help:\n<commands></gold>";
|
||||
public static String HELP_MESSAGE = "<green>Show this menu: <gold>/cm help</gold></green>";
|
||||
public static String SPAWN = "<green>Spawn a mob of a specific type: <gold>/cm spawn <mob_type> <mob> [<world> <x> <y> <z>]</gold></green>";
|
||||
public static String GIVE_SPAWNER = "<green>Give a mob spawner for a mob of a specific type: <gold>/cm givespawner <mob_type> <mob></green>";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
HELP_MESSAGE_WRAPPER = config.getString(prefix, "help-wrapper", HELP_MESSAGE_WRAPPER);
|
||||
HELP_MESSAGE = config.getString(prefix, "help", HELP_MESSAGE);
|
||||
SPAWN = config.getString(prefix, "spawn", SPAWN);
|
||||
GIVE_SPAWNER = config.getString(prefix, "give-spawner", GIVE_SPAWNER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,4 +55,31 @@ public class Messages extends AbstractConfig {
|
|||
PLAYER_NOT_FOUND = config.getString(prefix, "player-only", PLAYER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GIVE_SPAWNER {
|
||||
private static final String prefix = "give-spawner.";
|
||||
|
||||
public static String FULL_INVENTORY = "<red>You inventory is full so the spawner was not given</red>";
|
||||
public static String GIVEN = "<green>You have been given a <entity> spawner for type <mob_type></green>";
|
||||
public static String SPAWNER_NAME = "<gold><entity> <mob_type> spawner</gold>";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
FULL_INVENTORY = config.getString(prefix, "full-inventory", FULL_INVENTORY);
|
||||
GIVEN = config.getString(prefix, "given", GIVEN);
|
||||
SPAWNER_NAME = config.getString(prefix, "spawner-name", SPAWNER_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
public static class PLACE_SPAWNER {
|
||||
private static final String prefix = "place-spawner.";
|
||||
public static String INVALID_MOB_TYPE = "<red>This spawner has an invalid mob type (<mob-type>)</red>";
|
||||
public static String INVALID_ENTITY_TYPE = "<red>This spawner has an invalid entity type (<entity-type>)</red>";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
INVALID_MOB_TYPE = config.getString(prefix, "invalid-mob-type", INVALID_MOB_TYPE);
|
||||
INVALID_ENTITY_TYPE = config.getString(prefix, "invalid-entity-type", INVALID_ENTITY_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,26 @@ package com.alttd.custommobs.listeners;
|
|||
import com.alttd.custommobs.Main;
|
||||
import com.alttd.custommobs.abilities.MobType;
|
||||
import com.alttd.custommobs.abilities.MobTypeApplier;
|
||||
import com.alttd.custommobs.config.Messages;
|
||||
import com.alttd.custommobs.config.MobTypes;
|
||||
import com.alttd.custommobs.utility.EntityTypeChecker;
|
||||
import io.papermc.paper.persistence.PersistentDataContainerView;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.SpawnerSpawnEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
|
@ -19,9 +31,13 @@ import java.util.Optional;
|
|||
public class SpawnerListener implements Listener {
|
||||
|
||||
private final MobTypeApplier mobTypeApplier;
|
||||
private final NamespacedKey mobTypeKey;
|
||||
private final NamespacedKey entityKey;
|
||||
|
||||
public SpawnerListener(Main main) {
|
||||
public SpawnerListener(Main main, @NotNull NamespacedKey mobTypeKey, @NotNull NamespacedKey entityKey) {
|
||||
mobTypeApplier = new MobTypeApplier(main);
|
||||
this.mobTypeKey = mobTypeKey;
|
||||
this.entityKey = entityKey;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
@ -48,4 +64,44 @@ public class SpawnerListener implements Listener {
|
|||
mobTypeApplier.apply(livingEntity, mobType);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSpawnerPlace(BlockPlaceEvent event) {
|
||||
ItemStack itemInHand = event.getItemInHand();
|
||||
if (!itemInHand.getType().equals(org.bukkit.Material.SPAWNER)) {
|
||||
return;
|
||||
}
|
||||
PersistentDataContainerView persistentDataContainer = itemInHand.getPersistentDataContainer();
|
||||
if (!persistentDataContainer.has(mobTypeKey) || !persistentDataContainer.has(entityKey)) {
|
||||
return;
|
||||
}
|
||||
String mobType = persistentDataContainer.get(mobTypeKey, PersistentDataType.STRING);
|
||||
String entityTypeName = persistentDataContainer.get(entityKey, PersistentDataType.STRING);
|
||||
if (mobType == null || entityTypeName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<MobType> optionalMobType = MobTypes.MOB_TYPES.get(mobType);
|
||||
if (optionalMobType.isEmpty()) {
|
||||
event.getPlayer().sendRichMessage(Messages.PLACE_SPAWNER.INVALID_MOB_TYPE, Placeholder.parsed("mob-type", mobType));
|
||||
return;
|
||||
}
|
||||
EntityType entityType;
|
||||
try {
|
||||
entityType = EntityType.valueOf(entityTypeName);
|
||||
if (!entityType.isSpawnable() || !EntityTypeChecker.isMob(entityType)) {
|
||||
event.getPlayer().sendRichMessage(Messages.PLACE_SPAWNER.INVALID_ENTITY_TYPE, Placeholder.parsed("entity-type", entityTypeName));
|
||||
return;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.info("DEBUG: Invalid mob type {}", entityTypeName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getBlock().getState() instanceof CreatureSpawner spawner) {
|
||||
spawner.setSpawnedType(entityType);
|
||||
} else {
|
||||
log.info("Actual bock state {}", event.getBlock().getState().getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package com.alttd.custommobs.utility;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Mob;
|
||||
|
||||
public class EntityTypeChecker {
|
||||
|
||||
public static boolean isMob(EntityType entityType) {
|
||||
if (entityType == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Class<? extends Entity> entityClass = entityType.getEntityClass();
|
||||
if (entityClass == null) {
|
||||
return false;
|
||||
}
|
||||
Class<?> mobEntityClass = Class.forName("org.bukkit.entity." + entityClass.getSimpleName());
|
||||
return Mob.class.isAssignableFrom(mobEntityClass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user