mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-09-28 23:27:40 +02:00
Add /npc skin
This commit is contained in:
parent
a82dd10eef
commit
fc835aa9dc
@ -42,6 +42,7 @@ import net.citizensnpcs.trait.HorseModifiers;
|
|||||||
import net.citizensnpcs.trait.LookClose;
|
import net.citizensnpcs.trait.LookClose;
|
||||||
import net.citizensnpcs.trait.NPCSkeletonType;
|
import net.citizensnpcs.trait.NPCSkeletonType;
|
||||||
import net.citizensnpcs.trait.OcelotModifiers;
|
import net.citizensnpcs.trait.OcelotModifiers;
|
||||||
|
import net.citizensnpcs.trait.PlayerSkin;
|
||||||
import net.citizensnpcs.trait.Poses;
|
import net.citizensnpcs.trait.Poses;
|
||||||
import net.citizensnpcs.trait.Powered;
|
import net.citizensnpcs.trait.Powered;
|
||||||
import net.citizensnpcs.trait.SlimeSize;
|
import net.citizensnpcs.trait.SlimeSize;
|
||||||
@ -446,8 +447,8 @@ public class NPCCommands {
|
|||||||
public void flyable(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
public void flyable(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||||
boolean flyable = args.argsLength() == 2 ? args.getString(1).equals("true") : !npc.isFlyable();
|
boolean flyable = args.argsLength() == 2 ? args.getString(1).equals("true") : !npc.isFlyable();
|
||||||
npc.setFlyable(flyable);
|
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);
|
Messaging.sendTr(sender, flyable ? Messages.FLYABLE_SET : Messages.FLYABLE_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,6 +953,24 @@ public class NPCCommands {
|
|||||||
npc.getName());
|
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(
|
@Command(
|
||||||
aliases = { "npc" },
|
aliases = { "npc" },
|
||||||
usage = "pose (--save [name]|--assume [name]|--remove [name]) (-a)",
|
usage = "pose (--save [name]|--assume [name]|--remove [name]) (-a)",
|
||||||
|
@ -26,6 +26,7 @@ import net.citizensnpcs.trait.HorseModifiers;
|
|||||||
import net.citizensnpcs.trait.LookClose;
|
import net.citizensnpcs.trait.LookClose;
|
||||||
import net.citizensnpcs.trait.NPCSkeletonType;
|
import net.citizensnpcs.trait.NPCSkeletonType;
|
||||||
import net.citizensnpcs.trait.OcelotModifiers;
|
import net.citizensnpcs.trait.OcelotModifiers;
|
||||||
|
import net.citizensnpcs.trait.PlayerSkin;
|
||||||
import net.citizensnpcs.trait.Poses;
|
import net.citizensnpcs.trait.Poses;
|
||||||
import net.citizensnpcs.trait.Powered;
|
import net.citizensnpcs.trait.Powered;
|
||||||
import net.citizensnpcs.trait.Saddle;
|
import net.citizensnpcs.trait.Saddle;
|
||||||
@ -59,9 +60,9 @@ public class CitizensTraitFactory implements TraitFactory {
|
|||||||
registerTrait(TraitInfo.create(LookClose.class).withName("lookclose"));
|
registerTrait(TraitInfo.create(LookClose.class).withName("lookclose"));
|
||||||
registerTrait(TraitInfo.create(OcelotModifiers.class).withName("ocelotmodifiers"));
|
registerTrait(TraitInfo.create(OcelotModifiers.class).withName("ocelotmodifiers"));
|
||||||
registerTrait(TraitInfo.create(Owner.class).withName("owner"));
|
registerTrait(TraitInfo.create(Owner.class).withName("owner"));
|
||||||
|
registerTrait(TraitInfo.create(PlayerSkin.class).withName("playerskin"));
|
||||||
registerTrait(TraitInfo.create(Poses.class).withName("poses"));
|
registerTrait(TraitInfo.create(Poses.class).withName("poses"));
|
||||||
registerTrait(TraitInfo.create(Powered.class).withName("powered"));
|
registerTrait(TraitInfo.create(Powered.class).withName("powered"));
|
||||||
registerTrait(TraitInfo.create(VillagerProfession.class).withName("profession"));
|
|
||||||
registerTrait(TraitInfo.create(Saddle.class).withName("saddle"));
|
registerTrait(TraitInfo.create(Saddle.class).withName("saddle"));
|
||||||
registerTrait(TraitInfo.create(Sheared.class).withName("sheared"));
|
registerTrait(TraitInfo.create(Sheared.class).withName("sheared"));
|
||||||
registerTrait(TraitInfo.create(NPCSkeletonType.class).withName("skeletontype"));
|
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(Waypoints.class).withName("waypoints"));
|
||||||
registerTrait(TraitInfo.create(WoolColor.class).withName("woolcolor"));
|
registerTrait(TraitInfo.create(WoolColor.class).withName("woolcolor"));
|
||||||
registerTrait(TraitInfo.create(WolfModifiers.class).withName("wolfmodifiers"));
|
registerTrait(TraitInfo.create(WolfModifiers.class).withName("wolfmodifiers"));
|
||||||
|
registerTrait(TraitInfo.create(VillagerProfession.class).withName("profession"));
|
||||||
registerTrait(TraitInfo.create(ZombieModifier.class).withName("zombiemodifier"));
|
registerTrait(TraitInfo.create(ZombieModifier.class).withName("zombiemodifier"));
|
||||||
|
|
||||||
for (String trait : registered.keySet()) {
|
for (String trait : registered.keySet()) {
|
||||||
|
@ -7,6 +7,7 @@ import net.citizensnpcs.api.CitizensAPI;
|
|||||||
import net.citizensnpcs.api.npc.NPC;
|
import net.citizensnpcs.api.npc.NPC;
|
||||||
import net.citizensnpcs.api.util.Colorizer;
|
import net.citizensnpcs.api.util.Colorizer;
|
||||||
import net.citizensnpcs.npc.AbstractEntityController;
|
import net.citizensnpcs.npc.AbstractEntityController;
|
||||||
|
import net.citizensnpcs.trait.PlayerSkin;
|
||||||
import net.citizensnpcs.util.NMS;
|
import net.citizensnpcs.util.NMS;
|
||||||
import net.minecraft.server.v1_7_R2.PlayerInteractManager;
|
import net.minecraft.server.v1_7_R2.PlayerInteractManager;
|
||||||
import net.minecraft.server.v1_7_R2.WorldServer;
|
import net.minecraft.server.v1_7_R2.WorldServer;
|
||||||
@ -26,9 +27,10 @@ public class HumanController extends AbstractEntityController {
|
|||||||
@Override
|
@Override
|
||||||
protected Entity createEntity(final Location at, final NPC npc) {
|
protected Entity createEntity(final Location at, final NPC npc) {
|
||||||
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
|
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
|
||||||
String parseColors = Colorizer.parseColors(npc.getFullName());
|
String parseColors = Colorizer.parseColors(npc.getTrait(PlayerSkin.class).getSkinName());
|
||||||
if (parseColors.length() > 16)
|
if (parseColors.length() > 16) {
|
||||||
parseColors = parseColors.substring(0, 16);
|
parseColors = parseColors.substring(0, 16);
|
||||||
|
}
|
||||||
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, new GameProfile(UUID
|
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, new GameProfile(UUID
|
||||||
.randomUUID().toString(), parseColors), new PlayerInteractManager(ws), npc);
|
.randomUUID().toString(), parseColors), new PlayerInteractManager(ws), npc);
|
||||||
handle.setPositionRotation(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
|
handle.setPositionRotation(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
|
||||||
|
106
src/main/java/net/citizensnpcs/trait/PlayerSkin.java
Normal file
106
src/main/java/net/citizensnpcs/trait/PlayerSkin.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -183,6 +183,8 @@ public class Messages {
|
|||||||
public static final String SIZE_DESCRIPTION = "citizens.commands.npc.size.description";
|
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 SIZE_SET = "citizens.commands.npc.size.set";
|
||||||
public static final String SKELETON_TYPE_SET = "citizens.commands.npc.skeletontype.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_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_ANCHOR = "citizens.notifications.skipping-invalid-anchor";
|
||||||
public static final String SKIPPING_INVALID_POSE = "citizens.notifications.skipping-invalid-pose";
|
public static final String SKIPPING_INVALID_POSE = "citizens.notifications.skipping-invalid-pose";
|
||||||
|
@ -176,7 +176,7 @@ public class NMS {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private static Constructor<?> getCustomEntityConstructor(Class<?> clazz, EntityType type) throws SecurityException,
|
private static Constructor<?> getCustomEntityConstructor(Class<?> clazz, EntityType type) throws SecurityException,
|
||||||
NoSuchMethodException {
|
NoSuchMethodException {
|
||||||
Constructor<?> constructor = ENTITY_CONSTRUCTOR_CACHE.get(clazz);
|
Constructor<?> constructor = ENTITY_CONSTRUCTOR_CACHE.get(clazz);
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
constructor = clazz.getConstructor(World.class);
|
constructor = clazz.getConstructor(World.class);
|
||||||
|
@ -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.delay-set=Respawn delay set to [[{0}]].
|
||||||
citizens.commands.npc.respawn.describe=Respawn delay is currently [[{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.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.description={0}''s size is [[{1}]].
|
||||||
citizens.commands.npc.size.set={0}''s size set to [[{1}]].
|
citizens.commands.npc.size.set={0}''s size set to [[{1}]].
|
||||||
citizens.commands.npc.sound.invalid-sound=Invalid sound.
|
citizens.commands.npc.sound.invalid-sound=Invalid sound.
|
||||||
|
Loading…
Reference in New Issue
Block a user