Add /npc wolf --variant and /npc armadillo

This commit is contained in:
fullwall 2024-04-24 06:04:02 +08:00
parent 70c40dcb22
commit 245d76a78c
8 changed files with 157 additions and 5 deletions

View File

@ -41,6 +41,7 @@ import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Rabbit; import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Villager.Profession; import org.bukkit.entity.Villager.Profession;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zombie; import org.bukkit.entity.Zombie;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
@ -3489,7 +3490,7 @@ public class NPCCommands {
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "wolf (-s(itting) a(ngry) t(amed) i(nfo)) --collar [hex rgb color|name]", usage = "wolf (-s(itting) a(ngry) t(amed) i(nfo)) --collar [hex rgb color|name] --variant [variant]",
desc = "", desc = "",
modifiers = { "wolf" }, modifiers = { "wolf" },
min = 1, min = 1,
@ -3498,7 +3499,11 @@ public class NPCCommands {
flags = "sati", flags = "sati",
permission = "citizens.npc.wolf") permission = "citizens.npc.wolf")
@Requirements(selected = true, ownership = true, types = EntityType.WOLF) @Requirements(selected = true, ownership = true, types = EntityType.WOLF)
public void wolf(CommandContext args, CommandSender sender, NPC npc, @Flag("collar") String collar) public void wolf(CommandContext args, CommandSender sender, NPC npc, @Flag("collar") String collar,
@Flag(
value = "variant",
completions = { "ASHEN", "BLACK", "CHESTNUT", "PALE", "RUSTY", "SNOWY", "STRIPED", "WOODS",
"SPOTTED" }) String variant)
throws CommandException { throws CommandException {
WolfModifiers trait = npc.getOrAddTrait(WolfModifiers.class); WolfModifiers trait = npc.getOrAddTrait(WolfModifiers.class);
if (args.hasFlag('a')) { if (args.hasFlag('a')) {
@ -3510,6 +3515,15 @@ public class NPCCommands {
if (args.hasFlag('t')) { if (args.hasFlag('t')) {
trait.setTamed(!trait.isTamed()); trait.setTamed(!trait.isTamed());
} }
if (variant != null) {
variant = variant.toUpperCase();
try {
Wolf.Variant.class.getField(variant);
} catch (Throwable t) {
throw new CommandUsageException();
}
trait.setVariant(variant);
}
if (collar != null) { if (collar != null) {
String unparsed = collar; String unparsed = collar;
DyeColor color = null; DyeColor color = null;

View File

@ -1,7 +1,12 @@
package net.citizensnpcs.trait; package net.citizensnpcs.trait;
import java.util.Map;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.entity.Wolf; import org.bukkit.entity.Wolf;
import org.bukkit.entity.Wolf.Variant;
import com.google.common.collect.Maps;
import net.citizensnpcs.api.persistence.Persist; import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.Trait;
@ -14,14 +19,16 @@ import net.citizensnpcs.api.trait.TraitName;
*/ */
@TraitName("wolfmodifiers") @TraitName("wolfmodifiers")
public class WolfModifiers extends Trait { public class WolfModifiers extends Trait {
@Persist("angry") @Persist
private boolean angry; private boolean angry;
@Persist("collarColor") @Persist("collarColor")
private DyeColor collarColor = DyeColor.RED; private DyeColor collarColor = DyeColor.RED;
@Persist("sitting") @Persist
private boolean sitting; private boolean sitting;
@Persist("tamed") @Persist
private boolean tamed; private boolean tamed;
@Persist
private String variant;
public WolfModifiers() { public WolfModifiers() {
super("wolfmodifiers"); super("wolfmodifiers");
@ -31,6 +38,10 @@ public class WolfModifiers extends Trait {
return collarColor; return collarColor;
} }
public String getVariant() {
return variant;
}
public boolean isAngry() { public boolean isAngry() {
return angry; return angry;
} }
@ -68,6 +79,11 @@ public class WolfModifiers extends Trait {
updateModifiers(); updateModifiers();
} }
public void setVariant(String variant) {
this.variant = variant;
updateModifiers();
}
private void updateModifiers() { private void updateModifiers() {
if (npc.getEntity() instanceof Wolf) { if (npc.getEntity() instanceof Wolf) {
Wolf wolf = (Wolf) npc.getEntity(); Wolf wolf = (Wolf) npc.getEntity();
@ -77,7 +93,19 @@ public class WolfModifiers extends Trait {
if (angry) { if (angry) {
wolf.setTarget(wolf); wolf.setTarget(wolf);
} }
if (variant != null) {
wolf.setVariant((Variant) VARIANT_CACHE.computeIfAbsent(variant, v -> {
try {
return Wolf.Variant.class.getField(variant).get(null);
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}));
}
wolf.setTamed(tamed); wolf.setTamed(tamed);
} }
} }
private static final Map<String, Object> VARIANT_CACHE = Maps.newHashMap();
} }

View File

@ -0,0 +1,75 @@
package net.citizensnpcs.trait.versioned;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Armadillo;
import org.bukkit.entity.EntityType;
import net.citizensnpcs.api.command.Command;
import net.citizensnpcs.api.command.CommandContext;
import net.citizensnpcs.api.command.Flag;
import net.citizensnpcs.api.command.Requirements;
import net.citizensnpcs.api.command.exception.CommandException;
import net.citizensnpcs.api.command.exception.CommandUsageException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.NMS;
@TraitName("armadillotrait")
public class ArmadilloTrait extends Trait {
@Persist
private ArmadilloState state = ArmadilloState.IDLE;
public ArmadilloTrait() {
super("armadillotrait");
}
public ArmadilloState getState() {
return state;
}
@Override
public void run() {
if (!npc.isSpawned() || !(npc.getEntity() instanceof Armadillo))
return;
NMS.setArmadilloState(npc.getEntity(), state);
}
public void setState(ArmadilloState state) {
this.state = state;
}
public enum ArmadilloState {
IDLE,
ROLLING_OUT,
ROLLING_UP,
SCARED;
}
@Command(
aliases = { "npc" },
usage = "armadillo --state [state]",
desc = "",
modifiers = { "armadillo" },
min = 1,
max = 1,
flags = "",
permission = "citizens.npc.armadillo")
@Requirements(selected = true, ownership = true, types = EntityType.ARMADILLO)
public static void allay(CommandContext args, CommandSender sender, NPC npc, @Flag("state") ArmadilloState state)
throws CommandException {
ArmadilloTrait trait = npc.getOrAddTrait(ArmadilloTrait.class);
String output = "";
if (state != null) {
trait.setState(state);
output += Messaging.tr(Messages.ARMADILLO_STATE_SET, state);
}
if (!output.isEmpty()) {
Messaging.send(sender, output.trim());
} else
throw new CommandUsageException();
}
}

View File

@ -19,6 +19,7 @@ public class Messages {
public static final String ANCHOR_REMOVED = "citizens.commands.npc.anchor.removed"; public static final String ANCHOR_REMOVED = "citizens.commands.npc.anchor.removed";
public static final String ANIMATION_ADDED = "citizens.editors.waypoints.triggers.animation.added"; public static final String ANIMATION_ADDED = "citizens.editors.waypoints.triggers.animation.added";
public static final String ANIMATION_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.animation.prompt"; public static final String ANIMATION_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.animation.prompt";
public static final String ARMADILLO_STATE_SET = "citizens.commands.npc.armadillo.state-set";
public static final String AVAILABLE_WAYPOINT_PROVIDERS = "citizens.waypoints.available-providers-header"; public static final String AVAILABLE_WAYPOINT_PROVIDERS = "citizens.waypoints.available-providers-header";
public static final String AXOLOTL_NOT_PLAYING_DEAD = "citizens.commands.npc.axolotl.playing-dead-stopped"; public static final String AXOLOTL_NOT_PLAYING_DEAD = "citizens.commands.npc.axolotl.playing-dead-stopped";
public static final String AXOLOTL_PLAYING_DEAD = "citizens.commands.npc.axolotl.playing-dead"; public static final String AXOLOTL_PLAYING_DEAD = "citizens.commands.npc.axolotl.playing-dead";

View File

@ -61,6 +61,7 @@ import net.citizensnpcs.npc.ai.MCTargetStrategy.TargetNavigator;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.MirrorTrait; import net.citizensnpcs.trait.MirrorTrait;
import net.citizensnpcs.trait.PacketNPC; import net.citizensnpcs.trait.PacketNPC;
import net.citizensnpcs.trait.versioned.ArmadilloTrait.ArmadilloState;
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose; import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState; import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState;
import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator;
@ -790,6 +791,10 @@ public class NMS {
BRIDGE.setAllayDancing(entity, dancing); BRIDGE.setAllayDancing(entity, dancing);
} }
public static void setArmadilloState(Entity entity, ArmadilloState state) {
BRIDGE.setArmadilloState(entity, state);
}
public static void setBodyYaw(Entity entity, float yaw) { public static void setBodyYaw(Entity entity, float yaw) {
BRIDGE.setBodyYaw(entity, yaw); BRIDGE.setBodyYaw(entity, yaw);
} }

View File

@ -41,6 +41,7 @@ import net.citizensnpcs.api.util.EntityDim;
import net.citizensnpcs.npc.ai.MCNavigationStrategy.MCNavigator; import net.citizensnpcs.npc.ai.MCNavigationStrategy.MCNavigator;
import net.citizensnpcs.npc.ai.MCTargetStrategy.TargetNavigator; import net.citizensnpcs.npc.ai.MCTargetStrategy.TargetNavigator;
import net.citizensnpcs.trait.MirrorTrait; import net.citizensnpcs.trait.MirrorTrait;
import net.citizensnpcs.trait.versioned.ArmadilloTrait.ArmadilloState;
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose; import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState; import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState;
import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator; import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator;
@ -195,6 +196,9 @@ public interface NMSBridge {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public default void setArmadilloState(Entity entity, ArmadilloState state) {
}
public void setBodyYaw(Entity entity, float yaw); public void setBodyYaw(Entity entity, float yaw);
public void setBoundingBox(Entity entity, BoundingBox box); public void setBoundingBox(Entity entity, BoundingBox box);

View File

@ -38,6 +38,7 @@
"citizens.commands.npc.allay.dancing-unset" : "[[{0}]] is no longer dancing.", "citizens.commands.npc.allay.dancing-unset" : "[[{0}]] is no longer dancing.",
"citizens.commands.npc.allay.description" : "Sets allay modifiers", "citizens.commands.npc.allay.description" : "Sets allay modifiers",
"citizens.commands.npc.allay.help" : "", "citizens.commands.npc.allay.help" : "",
"citizens.commands.npc.armadillo.state-set": "State set to [[{0}]]",
"citizens.commands.npc.anchor.added" : "Anchor added.", "citizens.commands.npc.anchor.added" : "Anchor added.",
"citizens.commands.npc.anchor.already-exists" : "The anchor [[{0}]] already exists.", "citizens.commands.npc.anchor.already-exists" : "The anchor [[{0}]] already exists.",
"citizens.commands.npc.anchor.description" : "Manages the NPC''s location anchor(s)", "citizens.commands.npc.anchor.description" : "Manages the NPC''s location anchor(s)",

View File

@ -225,6 +225,8 @@ import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.MirrorTrait; import net.citizensnpcs.trait.MirrorTrait;
import net.citizensnpcs.trait.RotationTrait; import net.citizensnpcs.trait.RotationTrait;
import net.citizensnpcs.trait.versioned.AllayTrait; import net.citizensnpcs.trait.versioned.AllayTrait;
import net.citizensnpcs.trait.versioned.ArmadilloTrait;
import net.citizensnpcs.trait.versioned.ArmadilloTrait.ArmadilloState;
import net.citizensnpcs.trait.versioned.AxolotlTrait; import net.citizensnpcs.trait.versioned.AxolotlTrait;
import net.citizensnpcs.trait.versioned.BeeTrait; import net.citizensnpcs.trait.versioned.BeeTrait;
import net.citizensnpcs.trait.versioned.BossBarTrait; import net.citizensnpcs.trait.versioned.BossBarTrait;
@ -330,6 +332,7 @@ import net.minecraft.world.entity.animal.Pufferfish;
import net.minecraft.world.entity.animal.Rabbit; import net.minecraft.world.entity.animal.Rabbit;
import net.minecraft.world.entity.animal.Turtle; import net.minecraft.world.entity.animal.Turtle;
import net.minecraft.world.entity.animal.allay.Allay; import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.animal.armadillo.Armadillo;
import net.minecraft.world.entity.animal.axolotl.Axolotl; import net.minecraft.world.entity.animal.axolotl.Axolotl;
import net.minecraft.world.entity.animal.camel.Camel; import net.minecraft.world.entity.animal.camel.Camel;
import net.minecraft.world.entity.animal.horse.AbstractHorse; import net.minecraft.world.entity.animal.horse.AbstractHorse;
@ -945,6 +948,7 @@ public class NMSImpl implements NMSBridge {
registerTraitWithCommand(manager, EnderDragonTrait.class); registerTraitWithCommand(manager, EnderDragonTrait.class);
registerTraitWithCommand(manager, AllayTrait.class); registerTraitWithCommand(manager, AllayTrait.class);
registerTraitWithCommand(manager, AxolotlTrait.class); registerTraitWithCommand(manager, AxolotlTrait.class);
registerTraitWithCommand(manager, ArmadilloTrait.class);
registerTraitWithCommand(manager, BeeTrait.class); registerTraitWithCommand(manager, BeeTrait.class);
registerTraitWithCommand(manager, BossBarTrait.class); registerTraitWithCommand(manager, BossBarTrait.class);
registerTraitWithCommand(manager, CamelTrait.class); registerTraitWithCommand(manager, CamelTrait.class);
@ -1447,6 +1451,26 @@ public class NMSImpl implements NMSBridge {
allay.setDancing(dancing); allay.setDancing(dancing);
} }
@Override
public void setArmadilloState(org.bukkit.entity.Entity entity, ArmadilloState state) {
Armadillo.ArmadilloState s = Armadillo.ArmadilloState.IDLE;
switch (state) {
case IDLE:
s = Armadillo.ArmadilloState.IDLE;
break;
case ROLLING_UP:
s = Armadillo.ArmadilloState.ROLLING;
break;
case ROLLING_OUT:
s = Armadillo.ArmadilloState.UNROLLING;
break;
case SCARED:
s = Armadillo.ArmadilloState.SCARED;
break;
}
((Armadillo) getHandle(entity)).switchToState(s);
}
@Override @Override
public void setBodyYaw(org.bukkit.entity.Entity entity, float yaw) { public void setBodyYaw(org.bukkit.entity.Entity entity, float yaw) {
Entity handle = getHandle(entity); Entity handle = getHandle(entity);