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.Rabbit;
import org.bukkit.entity.Villager.Profession;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zombie;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.InventoryHolder;
@ -3489,7 +3490,7 @@ public class NPCCommands {
@Command(
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 = "",
modifiers = { "wolf" },
min = 1,
@ -3498,7 +3499,11 @@ public class NPCCommands {
flags = "sati",
permission = "citizens.npc.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 {
WolfModifiers trait = npc.getOrAddTrait(WolfModifiers.class);
if (args.hasFlag('a')) {
@ -3510,6 +3515,15 @@ public class NPCCommands {
if (args.hasFlag('t')) {
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) {
String unparsed = collar;
DyeColor color = null;

View File

@ -1,7 +1,12 @@
package net.citizensnpcs.trait;
import java.util.Map;
import org.bukkit.DyeColor;
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.trait.Trait;
@ -14,14 +19,16 @@ import net.citizensnpcs.api.trait.TraitName;
*/
@TraitName("wolfmodifiers")
public class WolfModifiers extends Trait {
@Persist("angry")
@Persist
private boolean angry;
@Persist("collarColor")
private DyeColor collarColor = DyeColor.RED;
@Persist("sitting")
@Persist
private boolean sitting;
@Persist("tamed")
@Persist
private boolean tamed;
@Persist
private String variant;
public WolfModifiers() {
super("wolfmodifiers");
@ -31,6 +38,10 @@ public class WolfModifiers extends Trait {
return collarColor;
}
public String getVariant() {
return variant;
}
public boolean isAngry() {
return angry;
}
@ -68,6 +79,11 @@ public class WolfModifiers extends Trait {
updateModifiers();
}
public void setVariant(String variant) {
this.variant = variant;
updateModifiers();
}
private void updateModifiers() {
if (npc.getEntity() instanceof Wolf) {
Wolf wolf = (Wolf) npc.getEntity();
@ -77,7 +93,19 @@ public class WolfModifiers extends Trait {
if (angry) {
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);
}
}
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 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 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 AXOLOTL_NOT_PLAYING_DEAD = "citizens.commands.npc.axolotl.playing-dead-stopped";
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.trait.MirrorTrait;
import net.citizensnpcs.trait.PacketNPC;
import net.citizensnpcs.trait.versioned.ArmadilloTrait.ArmadilloState;
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState;
import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator;
@ -790,6 +791,10 @@ public class NMS {
BRIDGE.setAllayDancing(entity, dancing);
}
public static void setArmadilloState(Entity entity, ArmadilloState state) {
BRIDGE.setArmadilloState(entity, state);
}
public static void setBodyYaw(Entity entity, float 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.MCTargetStrategy.TargetNavigator;
import net.citizensnpcs.trait.MirrorTrait;
import net.citizensnpcs.trait.versioned.ArmadilloTrait.ArmadilloState;
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState;
import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator;
@ -195,6 +196,9 @@ public interface NMSBridge {
throw new UnsupportedOperationException();
}
public default void setArmadilloState(Entity entity, ArmadilloState state) {
}
public void setBodyYaw(Entity entity, float yaw);
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.description" : "Sets allay modifiers",
"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.already-exists" : "The anchor [[{0}]] already exists.",
"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.RotationTrait;
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.BeeTrait;
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.Turtle;
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.camel.Camel;
import net.minecraft.world.entity.animal.horse.AbstractHorse;
@ -945,6 +948,7 @@ public class NMSImpl implements NMSBridge {
registerTraitWithCommand(manager, EnderDragonTrait.class);
registerTraitWithCommand(manager, AllayTrait.class);
registerTraitWithCommand(manager, AxolotlTrait.class);
registerTraitWithCommand(manager, ArmadilloTrait.class);
registerTraitWithCommand(manager, BeeTrait.class);
registerTraitWithCommand(manager, BossBarTrait.class);
registerTraitWithCommand(manager, CamelTrait.class);
@ -1447,6 +1451,26 @@ public class NMSImpl implements NMSBridge {
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
public void setBodyYaw(org.bukkit.entity.Entity entity, float yaw) {
Entity handle = getHandle(entity);