diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 8aac6cf33..96b46f95e 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -29,6 +29,7 @@ import net.citizensnpcs.api.trait.trait.Speech; import net.citizensnpcs.api.util.Colorizer; import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.api.util.Paginator; +import net.citizensnpcs.npc.EntityControllers; import net.citizensnpcs.npc.NPCSelector; import net.citizensnpcs.npc.Template; import net.citizensnpcs.trait.Age; @@ -299,11 +300,9 @@ public class NPCCommands { String inputType = args.getFlag("type"); type = Util.matchEntityType(inputType); if (type == null) { - Messaging.sendErrorTr(sender, Messages.NPC_CREATE_INVALID_MOBTYPE, inputType); - type = EntityType.PLAYER; - } else if (!LivingEntity.class.isAssignableFrom(type.getEntityClass())) { - Messaging.sendErrorTr(sender, Messages.NOT_LIVING_MOBTYPE, type); - type = EntityType.PLAYER; + throw new CommandException(Messaging.tr(Messages.NPC_CREATE_INVALID_MOBTYPE, inputType)); + } else if (!EntityControllers.controllerExistsForType(type)) { + throw new CommandException(Messaging.tr(Messages.NPC_CREATE_MISSING_MOBTYPE, inputType)); } } if (!sender.hasPermission("citizens.npc.create.*") && !sender.hasPermission("citizens.npc.createall") diff --git a/src/main/java/net/citizensnpcs/npc/AbstractEntityController.java b/src/main/java/net/citizensnpcs/npc/AbstractEntityController.java index b3041b065..1962a5971 100644 --- a/src/main/java/net/citizensnpcs/npc/AbstractEntityController.java +++ b/src/main/java/net/citizensnpcs/npc/AbstractEntityController.java @@ -3,15 +3,15 @@ package net.citizensnpcs.npc; import net.citizensnpcs.api.npc.NPC; import org.bukkit.Location; -import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Entity; public abstract class AbstractEntityController implements EntityController { - private LivingEntity bukkitEntity; + private Entity bukkitEntity; - protected abstract LivingEntity createEntity(Location at, NPC npc); + protected abstract Entity createEntity(Location at, NPC npc); @Override - public LivingEntity getBukkitEntity() { + public Entity getBukkitEntity() { return bukkitEntity; } diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index 312442107..73de11cb9 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -26,7 +26,7 @@ import net.minecraft.server.v1_6_R3.Packet34EntityTeleport; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_6_R3.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -86,6 +86,18 @@ public class CitizensNPC extends AbstractNPC { @Override @Deprecated public LivingEntity getBukkitEntity() { + if (entityController == null) { + return null; + } + Entity entity = entityController.getBukkitEntity(); + if (entity instanceof LivingEntity) { + return (LivingEntity) entity; + } + throw new IllegalStateException("getBukkitEntity() called on a non-living NPC"); + } + + @Override + public Entity getEntity() { return entityController == null ? null : entityController.getBukkitEntity(); } @@ -166,7 +178,7 @@ public class CitizensNPC extends AbstractNPC { at = at.clone(); entityController.spawn(at, this); - net.minecraft.server.v1_6_R3.Entity mcEntity = ((CraftLivingEntity) getEntity()).getHandle(); + net.minecraft.server.v1_6_R3.Entity mcEntity = ((CraftEntity) getEntity()).getHandle(); boolean couldSpawn = !Util.isLoaded(at) ? false : mcEntity.world.addEntity(mcEntity, SpawnReason.CUSTOM); mcEntity.setPositionRotation(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch()); if (!couldSpawn) { diff --git a/src/main/java/net/citizensnpcs/npc/EntityController.java b/src/main/java/net/citizensnpcs/npc/EntityController.java index 28c2f6194..65259c6c8 100644 --- a/src/main/java/net/citizensnpcs/npc/EntityController.java +++ b/src/main/java/net/citizensnpcs/npc/EntityController.java @@ -3,10 +3,10 @@ package net.citizensnpcs.npc; import net.citizensnpcs.api.npc.NPC; import org.bukkit.Location; -import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Entity; public interface EntityController { - LivingEntity getBukkitEntity(); + Entity getBukkitEntity(); void remove(); diff --git a/src/main/java/net/citizensnpcs/npc/EntityControllers.java b/src/main/java/net/citizensnpcs/npc/EntityControllers.java index c077e1aa6..a9d552f00 100644 --- a/src/main/java/net/citizensnpcs/npc/EntityControllers.java +++ b/src/main/java/net/citizensnpcs/npc/EntityControllers.java @@ -39,6 +39,10 @@ import com.google.common.base.Throwables; import com.google.common.collect.Maps; public class EntityControllers { + public static boolean controllerExistsForType(EntityType type) { + return TYPES.containsKey(type); + } + public static EntityController createForType(EntityType type) { Class controllerClass = TYPES.get(type); if (controllerClass == null) diff --git a/src/main/java/net/citizensnpcs/npc/MobEntityController.java b/src/main/java/net/citizensnpcs/npc/MobEntityController.java index 59364ef02..35937b350 100644 --- a/src/main/java/net/citizensnpcs/npc/MobEntityController.java +++ b/src/main/java/net/citizensnpcs/npc/MobEntityController.java @@ -5,13 +5,12 @@ import java.util.Map; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.util.NMS; -import net.minecraft.server.v1_6_R3.EntityLiving; import net.minecraft.server.v1_6_R3.World; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_6_R3.CraftWorld; -import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Entity; import com.google.common.collect.Maps; @@ -24,8 +23,9 @@ public abstract class MobEntityController extends AbstractEntityController { } @Override - protected LivingEntity createEntity(Location at, NPC npc) { - EntityLiving entity = createEntityFromClass(((CraftWorld) at.getWorld()).getHandle(), npc); + protected Entity createEntity(Location at, NPC npc) { + net.minecraft.server.v1_6_R3.Entity entity = createEntityFromClass(((CraftWorld) at.getWorld()).getHandle(), + npc); entity.setPositionRotation(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch()); // entity.onGround isn't updated right away - we approximate here so @@ -33,12 +33,12 @@ public abstract class MobEntityController extends AbstractEntityController { org.bukkit.Material beneath = at.getBlock().getRelative(BlockFace.DOWN).getType(); if (beneath.isBlock()) entity.onGround = true; - return (LivingEntity) entity.getBukkitEntity(); + return entity.getBukkitEntity(); } - private EntityLiving createEntityFromClass(Object... args) { + private net.minecraft.server.v1_6_R3.Entity createEntityFromClass(Object... args) { try { - return (EntityLiving) constructor.newInstance(args); + return (net.minecraft.server.v1_6_R3.Entity) constructor.newInstance(args); } catch (Exception ex) { ex.printStackTrace(); return null; diff --git a/src/main/java/net/citizensnpcs/npc/entity/HumanController.java b/src/main/java/net/citizensnpcs/npc/entity/HumanController.java index 49cbe0cd9..6e21970b3 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/HumanController.java +++ b/src/main/java/net/citizensnpcs/npc/entity/HumanController.java @@ -12,12 +12,12 @@ import net.minecraft.server.v1_6_R3.World; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v1_6_R3.CraftWorld; -import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public class HumanController extends AbstractEntityController { @Override - protected LivingEntity createEntity(final Location at, final NPC npc) { + protected Entity createEntity(final Location at, final NPC npc) { World ws = ((CraftWorld) at.getWorld()).getHandle(); final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, Colorizer.parseColors(npc .getFullName()), new PlayerInteractManager(ws), npc); diff --git a/src/main/java/net/citizensnpcs/util/Messages.java b/src/main/java/net/citizensnpcs/util/Messages.java index 1018bcbb4..513311692 100644 --- a/src/main/java/net/citizensnpcs/util/Messages.java +++ b/src/main/java/net/citizensnpcs/util/Messages.java @@ -136,6 +136,7 @@ public class Messages { public static final String NPC_ALREADY_SPAWNED = "citizens.commands.npc.spawn.already-spawned"; public static final String NPC_COPIED = "citizens.commands.npc.copy.copied"; public static final String NPC_CREATE_INVALID_MOBTYPE = "citizens.commands.npc.create.invalid-mobtype"; + public static final String NPC_CREATE_MISSING_MOBTYPE = "citizens.commands.npc.create.mobtype-missing"; public static final String NPC_DESPAWNED = "citizens.commands.npc.despawn.despawned"; public static final String NPC_NAME_TOO_LONG = "citizens.commands.npc.create.npc-name-too-long"; public static final String NPC_NOT_CONTROLLABLE = "citizens.commands.npc.controllable.not-controllable"; diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index d27a0bdf6..c13ca6e10 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -29,9 +29,9 @@ citizens.commands.npc.controllable.not-controllable=[[{0}]] is not controllable. citizens.commands.npc.controllable.removed=[[{0}]] can no longer be controlled. citizens.commands.npc.controllable.set=[[{0}]] can now be controlled. citizens.commands.npc.copy.copied=[[{0}]] has been copied. +citizens.commands.npc.create.mobtype-missing=[[{0}]] is not supported as an NPC mobtype. citizens.commands.npc.create.invalid-location=Spawn location could not be parsed or was not found. -citizens.commands.npc.create.invalid-mobtype={0} is not a valid mob type. Using default type. -citizens.commands.npc.create.not-living-mobtype={0} is not a living entity type. Using default type. +citizens.commands.npc.create.invalid-mobtype=[[{0}]] is not a valid mob type. citizens.commands.npc.create.npc-name-too-long=NPC names cannot be longer than 16 characters. The name has been shortened. citizens.commands.npc.create.no-player-for-spawn=No player could be found by that name to spawn an NPC at. citizens.commands.npc.despawn.despawned=You despawned [[{0}]]. @@ -89,7 +89,7 @@ citizens.commands.npc.size.description={0}''s size is [[{1}]]. citizens.commands.npc.size.set={0}''s size set to [[{1}]]. citizens.commands.npc.skeletontype.set={0}''s skeleton type set to [[{1}]]. citizens.commands.npc.skeletontype.invalid-type=Invalid skeleton type. -citizens.commands.npc.spawn.already-spawned={0} is already spawned at another location. Use ''/npc tphere'' to teleport the NPC to your location. +citizens.commands.npc.spawn.already-spawned=[[{0}]] is already spawned at another location. Use ''/npc tphere'' to teleport the NPC to your location. citizens.commands.npc.spawn.missing-npc-id=No NPC with the ID {0} exists. citizens.commands.npc.spawn.no-location=No stored location available - command must be used ingame. citizens.commands.npc.spawn.spawned=You spawned [[{0}]]. @@ -113,10 +113,10 @@ citizens.commands.npc.zombiemod.villager-unset=[[{0}]] is no longer a villager. citizens.commands.npc.zombiemod.baby-set=[[{0}]] is now a baby. citizens.commands.npc.zombiemod.baby-unset=[[{0}]] is no longer a baby. citizens.commands.page-missing=The page [[{0}]] does not exist. -citizens.commands.requirements.disallowed-mobtype=The NPC cannot be the mob type {0} to use that command. +citizens.commands.requirements.disallowed-mobtype=The NPC cannot be the mob type [[{0}]] for that command. citizens.commands.requirements.living-entity=The NPC must be a living entity. citizens.commands.requirements.missing-permission=You don't have permission to execute that command. -citizens.commands.requirements.missing-required-trait=Missing required trait {0}. +citizens.commands.requirements.missing-required-trait=Missing required trait [[{0}]]. citizens.commands.requirements.must-be-ingame=You must be ingame to use that command. citizens.commands.requirements.must-be-owner=You must be the owner of this NPC to execute that command. citizens.commands.requirements.must-have-selected=You must have an NPC selected to execute that command. @@ -124,7 +124,7 @@ citizens.commands.requirements.too-few-arguments=Too few arguments. citizens.commands.requirements.too-many-arguments=Too many arguments. citizens.commands.script.compiled=Script compiled. citizens.commands.script.compiling=Script compiling... -citizens.commands.script.file-missing=The file {0} doesn''t exist! +citizens.commands.script.file-missing=The file [[{0}]] doesn''t exist! citizens.commands.template.applied=Template applied to [[{0}]] NPCs. citizens.commands.template.conflict=A template by that name already exists. citizens.commands.template.created=Template created. @@ -140,7 +140,7 @@ citizens.commands.traitc.not-on-npc=The NPC doesn''t have that trait. citizens.commands.unknown-command=Unknown command. Did you mean: citizens.conversations.selection.invalid-choice=[[{0}]] is not a valid option. citizens.economy.error-loading=Unable to use economy handling. Has Vault been enabled? -citizens.economy.minimum-cost-required=Need at least {0}. +citizens.economy.minimum-cost-required=Need at least [[{0}]]. citizens.economy.money-withdrawn=Withdrew [[{0}]] for your NPC. citizens.editors.already-in-editor=You''re already in an editor! citizens.editors.copier.begin=Entered the NPC copier!
Click anywhere to copy the currently selected NPC. @@ -165,7 +165,7 @@ citizens.editors.text.edit-prompt=Enter text to edit the entry. citizens.editors.text.edited-text=Changed entry at index [[{0}]]to [[{1}]]. citizens.editors.text.end=Exited the text editor. citizens.editors.text.invalid-edit-type=Invalid edit type. -citizens.editors.text.invalid-index={0} is not a valid index! +citizens.editors.text.invalid-index=[[{0}]] is not a valid index! citizens.editors.text.invalid-input=Invalid input. citizens.editors.text.invalid-page=Invalid page number. citizens.editors.text.invalid-range=Invalid range.