Add /npc skin

This commit is contained in:
fullwall 2014-04-03 23:01:27 +08:00
parent a82dd10eef
commit fc835aa9dc
7 changed files with 139 additions and 6 deletions

View File

@ -42,6 +42,7 @@ import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.NPCSkeletonType;
import net.citizensnpcs.trait.OcelotModifiers;
import net.citizensnpcs.trait.PlayerSkin;
import net.citizensnpcs.trait.Poses;
import net.citizensnpcs.trait.Powered;
import net.citizensnpcs.trait.SlimeSize;
@ -446,8 +447,8 @@ public class NPCCommands {
public void flyable(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
boolean flyable = args.argsLength() == 2 ? args.getString(1).equals("true") : !npc.isFlyable();
npc.setFlyable(flyable);
flyable = npc.isFlyable(); // may not have applied
flyable = npc.isFlyable(); // may not have applied, eg bats always
// flyable
Messaging.sendTr(sender, flyable ? Messages.FLYABLE_SET : Messages.FLYABLE_UNSET);
}
@ -952,6 +953,24 @@ public class NPCCommands {
npc.getName());
}
@Command(
aliases = { "npc" },
usage = "skin [skin|-c]",
desc = "Sets a player NPC's skin",
flags = "c",
modifiers = { "skin" },
min = 1,
max = 2,
permission = "citizens.npc.skin")
@Requirements(selected = true, ownership = true, types = EntityType.PLAYER)
public void playerSkin(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
if (!args.hasFlag('c') && args.argsLength() == 0)
throw new CommandException();
String skin = args.hasFlag('c') ? "" : args.getString(1);
npc.getTrait(PlayerSkin.class).setSkinName(skin);
Messaging.sendTr(sender, skin.isEmpty() ? Messages.SKIN_CLEARED : Messages.SKIN_SET, npc.getFullName(), skin);
}
@Command(
aliases = { "npc" },
usage = "pose (--save [name]|--assume [name]|--remove [name]) (-a)",

View File

@ -26,6 +26,7 @@ import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.NPCSkeletonType;
import net.citizensnpcs.trait.OcelotModifiers;
import net.citizensnpcs.trait.PlayerSkin;
import net.citizensnpcs.trait.Poses;
import net.citizensnpcs.trait.Powered;
import net.citizensnpcs.trait.Saddle;
@ -59,9 +60,9 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(LookClose.class).withName("lookclose"));
registerTrait(TraitInfo.create(OcelotModifiers.class).withName("ocelotmodifiers"));
registerTrait(TraitInfo.create(Owner.class).withName("owner"));
registerTrait(TraitInfo.create(PlayerSkin.class).withName("playerskin"));
registerTrait(TraitInfo.create(Poses.class).withName("poses"));
registerTrait(TraitInfo.create(Powered.class).withName("powered"));
registerTrait(TraitInfo.create(VillagerProfession.class).withName("profession"));
registerTrait(TraitInfo.create(Saddle.class).withName("saddle"));
registerTrait(TraitInfo.create(Sheared.class).withName("sheared"));
registerTrait(TraitInfo.create(NPCSkeletonType.class).withName("skeletontype"));
@ -73,6 +74,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(Waypoints.class).withName("waypoints"));
registerTrait(TraitInfo.create(WoolColor.class).withName("woolcolor"));
registerTrait(TraitInfo.create(WolfModifiers.class).withName("wolfmodifiers"));
registerTrait(TraitInfo.create(VillagerProfession.class).withName("profession"));
registerTrait(TraitInfo.create(ZombieModifier.class).withName("zombiemodifier"));
for (String trait : registered.keySet()) {

View File

@ -7,6 +7,7 @@ import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.Colorizer;
import net.citizensnpcs.npc.AbstractEntityController;
import net.citizensnpcs.trait.PlayerSkin;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_7_R2.PlayerInteractManager;
import net.minecraft.server.v1_7_R2.WorldServer;
@ -26,9 +27,10 @@ public class HumanController extends AbstractEntityController {
@Override
protected Entity createEntity(final Location at, final NPC npc) {
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
String parseColors = Colorizer.parseColors(npc.getFullName());
if (parseColors.length() > 16)
String parseColors = Colorizer.parseColors(npc.getTrait(PlayerSkin.class).getSkinName());
if (parseColors.length() > 16) {
parseColors = parseColors.substring(0, 16);
}
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, new GameProfile(UUID
.randomUUID().toString(), parseColors), new PlayerInteractManager(ws), npc);
handle.setPositionRotation(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());

View File

@ -0,0 +1,106 @@
package net.citizensnpcs.trait;
import java.util.List;
import net.citizensnpcs.api.event.DespawnReason;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.trait.MobType;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Slime;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.google.common.collect.Lists;
public class PlayerSkin extends Trait {
private final List<Entity> nameCarriers = Lists.newArrayList();
public PlayerSkin() {
super("playerskin");
}
private void despawnNameCarriers() {
if (nameCarriers.isEmpty())
return;
for (Entity entity : nameCarriers) {
entity.remove();
}
nameCarriers.clear();
}
public String getSkinName() {
String skin = npc.data().get(NPC.PLAYER_SKIN_NAME_METADATA, "");
if (skin.isEmpty())
skin = npc.getFullName();
return skin;
}
public boolean isEnabled() {
return npc.getTrait(MobType.class).getType() == EntityType.PLAYER
&& !npc.data().get(NPC.PLAYER_SKIN_NAME_METADATA, "").isEmpty();
}
@Override
public void onDespawn() {
despawnNameCarriers();
}
@Override
public void onRemove() {
despawnNameCarriers();
}
private Entity prepareEntity(String name, EntityType type) {
NPC npcEntity = npc.getOwningRegistry().createNPC(type, name);
npcEntity.data().set(NPC.SHOULD_SAVE_METADATA, false);
npcEntity.spawn(npc.getStoredLocation());
if (name.isEmpty() || !(npcEntity.getEntity() instanceof Slime)) {
((LivingEntity) npcEntity.getEntity()).addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20
* 60 * 60 * 24 * 7, 1));
} else {
((Slime) npcEntity.getEntity()).setSize(-2);
}
return npcEntity.getEntity();
}
private void refreshPlayer() {
despawnNameCarriers();
Location last = npc.getEntity().getLocation();
npc.despawn(DespawnReason.PENDING_RESPAWN);
npc.spawn(last);
}
@Override
public void run() {
if (!npc.isSpawned() || npc.getEntity().getType() != EntityType.PLAYER
|| npc.data().get(NPC.PLAYER_SKIN_NAME_METADATA, "").isEmpty()) {
despawnNameCarriers();
return;
}
if (nameCarriers.size() == 0) {
Entity previous = npc.getEntity();
for (int i = 0; i < 2; i++) {
Entity heightCarrier = prepareEntity("", EntityType.SKELETON);
previous.setPassenger(heightCarrier);
nameCarriers.add(previous = heightCarrier);
}
Entity nameCarrier = prepareEntity(npc.getFullName(), EntityType.SLIME);
previous.setPassenger(nameCarrier);
nameCarriers.add(nameCarrier);
}
}
public void setSkinName(String name) {
npc.data().setPersistent(NPC.PLAYER_SKIN_NAME_METADATA, name);
if (npc.isSpawned()) {
refreshPlayer();
}
}
}

View File

@ -183,6 +183,8 @@ public class Messages {
public static final String SIZE_DESCRIPTION = "citizens.commands.npc.size.description";
public static final String SIZE_SET = "citizens.commands.npc.size.set";
public static final String SKELETON_TYPE_SET = "citizens.commands.npc.skeletontype.set";
public static final String SKIN_CLEARED = "citizens.commands.npc.skin.cleared";
public static final String SKIN_SET = "citizens.commands.npc.skin.set";
public static final String SKIPPING_BROKEN_TRAIT = "citizens.notifications.skipping-broken-trait";
public static final String SKIPPING_INVALID_ANCHOR = "citizens.notifications.skipping-invalid-anchor";
public static final String SKIPPING_INVALID_POSE = "citizens.notifications.skipping-invalid-pose";

View File

@ -176,7 +176,7 @@ public class NMS {
@SuppressWarnings("deprecation")
private static Constructor<?> getCustomEntityConstructor(Class<?> clazz, EntityType type) throws SecurityException,
NoSuchMethodException {
NoSuchMethodException {
Constructor<?> constructor = ENTITY_CONSTRUCTOR_CACHE.get(clazz);
if (constructor == null) {
constructor = clazz.getConstructor(World.class);

View File

@ -90,6 +90,8 @@ citizens.commands.npc.rename.renamed=You renamed [[{0}]] to [[{1}]].
citizens.commands.npc.respawn.delay-set=Respawn delay set to [[{0}]].
citizens.commands.npc.respawn.describe=Respawn delay is currently [[{0}]].
citizens.commands.npc.select.already-selected=You already have that NPC selected.
citizens.commands.npc.skin.set=[[{0}]]''s skin name set to [[{1}]].
citizens.commands.npc.skin.cleared=[[{0}]]''s skin name was cleared.
citizens.commands.npc.size.description={0}''s size is [[{1}]].
citizens.commands.npc.size.set={0}''s size set to [[{1}]].
citizens.commands.npc.sound.invalid-sound=Invalid sound.