From 9e3c401dc3f772414bf26da8eaf2c8575bf2cd86 Mon Sep 17 00:00:00 2001 From: JCThePants Date: Wed, 16 Sep 2015 21:06:49 -0700 Subject: [PATCH] add SkinLayers trait and commands --- .../citizensnpcs/commands/NPCCommands.java | 38 +++ .../npc/CitizensTraitFactory.java | 2 + .../net/citizensnpcs/trait/SkinLayers.java | 262 ++++++++++++++++++ .../java/net/citizensnpcs/util/Messages.java | 1 + src/main/resources/messages_en.properties | 1 + src/main/resources/plugin.yml | 2 + 6 files changed, 306 insertions(+) create mode 100644 src/main/java/net/citizensnpcs/trait/SkinLayers.java diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index b65bcaad5..fcecb7a6c 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -79,6 +79,8 @@ import net.citizensnpcs.trait.Powered; import net.citizensnpcs.trait.RabbitType; import net.citizensnpcs.trait.RabbitType.RabbitTypes; import net.citizensnpcs.trait.SheepTrait; +import net.citizensnpcs.trait.SkinLayers; +import net.citizensnpcs.trait.SkinLayers.Layer; import net.citizensnpcs.trait.SlimeSize; import net.citizensnpcs.trait.VillagerProfession; import net.citizensnpcs.trait.WolfModifiers; @@ -1322,6 +1324,42 @@ public class NPCCommands { } } + @Command( + aliases = { "npc" }, + usage = "skinlayers (--cape [true|false]) (--hat [true|false]) (--jacket [true|false]) (--sleeves [true|false]) (--pants [true|false])", + desc = "Sets an NPC's skin layers visibility.", + modifiers = { "skinlayers" }, + min = 1, + max = 5, + permission = "citizens.npc.skinlayers") + @Requirements(types = EntityType.PLAYER, selected = true, ownership = true) + public void skinLayers(final CommandContext args, final CommandSender sender, final NPC npc) throws CommandException { + SkinLayers trait = npc.getTrait(SkinLayers.class); + if (args.hasValueFlag("cape")) { + trait.setVisible(Layer.CAPE, Boolean.valueOf(args.getFlag("cape"))); + } + if (args.hasValueFlag("hat")) { + trait.setVisible(Layer.HAT, Boolean.valueOf(args.getFlag("hat"))); + } + if (args.hasValueFlag("jacket")) { + trait.setVisible(Layer.JACKET, Boolean.valueOf(args.getFlag("jacket"))); + } + if (args.hasValueFlag("sleeves")) { + boolean hasSleeves = Boolean.valueOf(args.getFlag("sleeves")); + trait.setVisible(Layer.LEFT_SLEEVE, hasSleeves); + trait.setVisible(Layer.RIGHT_SLEEVE, hasSleeves); + } + if (args.hasValueFlag("pants")) { + boolean hasPants = Boolean.valueOf(args.getFlag("pants")); + trait.setVisible(Layer.LEFT_PANTS, hasPants); + trait.setVisible(Layer.RIGHT_PANTS, hasPants); + } + Messaging.sendTr(sender, Messages.SKIN_LAYERS_SET, npc.getName(), + trait.isVisible(Layer.CAPE), trait.isVisible(Layer.HAT), trait.isVisible(Layer.JACKET), + trait.isVisible(Layer.LEFT_SLEEVE) || trait.isVisible(Layer.RIGHT_SLEEVE), + trait.isVisible(Layer.LEFT_PANTS) || trait.isVisible(Layer.RIGHT_PANTS)); + } + @Command( aliases = { "npc" }, usage = "size [size]", diff --git a/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java b/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java index 107a5f47e..085bce124 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java @@ -31,6 +31,7 @@ import net.citizensnpcs.trait.Powered; import net.citizensnpcs.trait.RabbitType; import net.citizensnpcs.trait.Saddle; import net.citizensnpcs.trait.SheepTrait; +import net.citizensnpcs.trait.SkinLayers; import net.citizensnpcs.trait.SlimeSize; import net.citizensnpcs.trait.VillagerProfession; import net.citizensnpcs.trait.WolfModifiers; @@ -65,6 +66,7 @@ public class CitizensTraitFactory implements TraitFactory { registerTrait(TraitInfo.create(RabbitType.class).withName("rabbittype")); registerTrait(TraitInfo.create(Saddle.class).withName("saddle")); registerTrait(TraitInfo.create(SheepTrait.class).withName("sheeptrait")); + registerTrait(TraitInfo.create(SkinLayers.class).withName("skinlayers")); registerTrait(TraitInfo.create(NPCSkeletonType.class).withName("skeletontype")); registerTrait(TraitInfo.create(SlimeSize.class).withName("slimesize")); registerTrait(TraitInfo.create(Spawned.class).withName("spawned")); diff --git a/src/main/java/net/citizensnpcs/trait/SkinLayers.java b/src/main/java/net/citizensnpcs/trait/SkinLayers.java new file mode 100644 index 000000000..40c594d3e --- /dev/null +++ b/src/main/java/net/citizensnpcs/trait/SkinLayers.java @@ -0,0 +1,262 @@ +package net.citizensnpcs.trait; + +import net.citizensnpcs.api.persistence.Persist; +import net.citizensnpcs.api.trait.Trait; +import net.citizensnpcs.npc.skin.SkinnableEntity; +import net.citizensnpcs.util.NMS; + +public class SkinLayers extends Trait { + + @Persist("cape") + private boolean cape = true; + @Persist("hat") + private boolean hat = true; + @Persist("jacket") + private boolean jacket = true; + @Persist("left-pants") + private boolean leftPants = true; + @Persist("left-sleeve") + private boolean leftSleeve = true; + @Persist("right-pants") + private boolean rightPants = true; + @Persist("right-sleeve") + private boolean rightSleeve = true; + + public SkinLayers() { + super("skinlayers"); + } + + public SkinLayers show() { + cape = true; + hat = true; + jacket = true; + leftSleeve = true; + rightSleeve = true; + leftPants = true; + rightPants = true; + setFlags(); + return this; + } + + public SkinLayers showCape() { + cape = true; + setFlags(); + return this; + } + + public SkinLayers showHat() { + hat = true; + setFlags(); + return this; + } + + public SkinLayers showJacket() { + jacket = true; + setFlags(); + return this; + } + + public SkinLayers showLeftPants() { + leftPants = true; + setFlags(); + return this; + } + + public SkinLayers showLeftSleeve() { + leftSleeve = true; + setFlags(); + return this; + } + + public SkinLayers showPants() { + leftPants = true; + rightPants = true; + setFlags(); + return this; + } + + public SkinLayers showRightPants() { + rightPants = true; + setFlags(); + return this; + } + + public SkinLayers showRightSleeve() { + rightSleeve = true; + setFlags(); + return this; + } + + public SkinLayers showSleeves() { + leftSleeve = true; + rightSleeve = true; + setFlags(); + return this; + } + + public SkinLayers hide() { + cape = false; + hat = false; + jacket = false; + leftSleeve = false; + rightSleeve = false; + leftPants = false; + rightPants = false; + setFlags(); + return this; + } + + public SkinLayers hideCape() { + cape = false; + setFlags(); + return this; + } + + public SkinLayers hideHat() { + hat = false; + setFlags(); + return this; + } + + public SkinLayers hideJacket() { + jacket = false; + setFlags(); + return this; + } + + public SkinLayers hideLeftPants() { + leftPants = false; + setFlags(); + return this; + } + + public SkinLayers hideLeftSleeve() { + leftSleeve = false; + setFlags(); + return this; + } + + public SkinLayers hidePants() { + leftPants = false; + rightPants = false; + setFlags(); + return this; + } + + public SkinLayers hideRightPants() { + rightPants = false; + setFlags(); + return this; + } + + public SkinLayers hideRightSleeve() { + rightSleeve = false; + setFlags(); + return this; + } + + public SkinLayers hideSleeves() { + leftSleeve = false; + rightSleeve = false; + setFlags(); + return this; + } + + public boolean isVisible(Layer layer) { + switch (layer) { + case CAPE: + return cape; + case JACKET: + return jacket; + case LEFT_SLEEVE: + return leftSleeve; + case RIGHT_SLEEVE: + return rightSleeve; + case LEFT_PANTS: + return leftPants; + case RIGHT_PANTS: + return rightPants; + case HAT: + return hat; + default: + return false; + } + } + + @Override + public void onAttach() { + setFlags(); + } + + @Override + public void onSpawn() { + setFlags(); + } + + public SkinLayers setVisible(Layer layer, boolean isVisible) { + switch (layer) { + case CAPE: + cape = isVisible; + break; + case JACKET: + jacket = isVisible; + break; + case LEFT_SLEEVE: + leftSleeve = isVisible; + break; + case RIGHT_SLEEVE: + rightSleeve = isVisible; + break; + case LEFT_PANTS: + leftPants = isVisible; + break; + case RIGHT_PANTS: + rightPants = isVisible; + break; + case HAT: + hat = isVisible; + break; + } + setFlags(); + return this; + } + + @Override + public String toString() { + return "SkinLayers{cape:" + cape + ", hat:" + hat + ", jacket:" + jacket + ", leftSleeve:" + leftSleeve + + ", rightSleeve:" + rightSleeve + ", leftPants:" + leftPants + ", rightPants:" + rightPants + "}"; + } + + private void setFlags() { + if (!npc.isSpawned()) + return; + + SkinnableEntity skinnable = NMS.getSkinnable(npc.getEntity()); + if (skinnable == null) + return; + + int flags = 0xFF; + for (Layer layer : Layer.values()) { + if (!isVisible(layer)) { + flags &= ~layer.flag; + } + } + skinnable.setSkinFlags((byte)flags); + } + + public enum Layer { + CAPE (0), + JACKET (1), + LEFT_SLEEVE (2), + RIGHT_SLEEVE (3), + LEFT_PANTS (4), + RIGHT_PANTS (5), + HAT (6); + + final int flag; + + Layer(int offset) { + this.flag = 1 << offset; + } + } +} diff --git a/src/main/java/net/citizensnpcs/util/Messages.java b/src/main/java/net/citizensnpcs/util/Messages.java index 1bf9b7b1e..2b5c72241 100644 --- a/src/main/java/net/citizensnpcs/util/Messages.java +++ b/src/main/java/net/citizensnpcs/util/Messages.java @@ -192,6 +192,7 @@ public class Messages { 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_LAYERS_SET = "citizens.commands.npc.skin.layers-set"; 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"; diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 988c24685..831fa5a60 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -96,6 +96,7 @@ 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.skin.layers-set=[[{0}]]''s skin layers: cape - [[{1}]], hat - [[{2}]], jacket - [[{3}]], sleeves - [[{4}]], pants - [[{5}]]. 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. diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5b6f9127d..49f8425f2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -646,6 +646,7 @@ permissions: citizens.npc.size: true citizens.npc.skeletontype: true citizens.npc.skin: true + citizens.npc.skinlayers: true citizens.npc.sound: true citizens.npc.spawn: true citizens.npc.speak: true @@ -994,6 +995,7 @@ permissions: citizens.npc.size: true citizens.npc.skeletontype: true citizens.npc.skin: true + citizens.npc.skinlayers: true citizens.npc.sound: true citizens.npc.spawn: true citizens.npc.speak: true