mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-12-23 01:27:33 +01:00
Rework /npc controllable, add /npc shop copyfrom, add /npc entitypose, add /npc forcefield, add /npc display
This commit is contained in:
parent
c6207e6d99
commit
468703fe79
@ -93,6 +93,7 @@ import net.citizensnpcs.api.npc.NPC.NPCUpdate;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.templates.Template;
|
||||
import net.citizensnpcs.api.npc.templates.TemplateRegistry;
|
||||
import net.citizensnpcs.api.persistence.PersistenceLoader;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot;
|
||||
@ -101,7 +102,9 @@ import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.trait.trait.PlayerFilter;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.EntityDim;
|
||||
import net.citizensnpcs.api.util.MemoryDataKey;
|
||||
import net.citizensnpcs.api.util.Messaging;
|
||||
import net.citizensnpcs.api.util.Paginator;
|
||||
import net.citizensnpcs.api.util.Placeholders;
|
||||
@ -126,11 +129,15 @@ import net.citizensnpcs.trait.CommandTrait.ExecutionMode;
|
||||
import net.citizensnpcs.trait.CommandTrait.ItemRequirementGUI;
|
||||
import net.citizensnpcs.trait.CommandTrait.NPCCommandBuilder;
|
||||
import net.citizensnpcs.trait.Controllable;
|
||||
import net.citizensnpcs.trait.Controllable.BuiltInControls;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.DropsTrait;
|
||||
import net.citizensnpcs.trait.EnderCrystalTrait;
|
||||
import net.citizensnpcs.trait.EndermanTrait;
|
||||
import net.citizensnpcs.trait.EntityPoseTrait;
|
||||
import net.citizensnpcs.trait.EntityPoseTrait.EntityPose;
|
||||
import net.citizensnpcs.trait.FollowTrait;
|
||||
import net.citizensnpcs.trait.ForcefieldTrait;
|
||||
import net.citizensnpcs.trait.GameModeTrait;
|
||||
import net.citizensnpcs.trait.Gravity;
|
||||
import net.citizensnpcs.trait.HologramTrait;
|
||||
@ -434,13 +441,11 @@ public class NPCCommands {
|
||||
public void boat(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Flag(value = "type", completionsProvider = OptionalBoatTypeCompletions.class) String stype)
|
||||
throws CommandException {
|
||||
if (stype != null) {
|
||||
Boat.Type type = Boat.Type.valueOf(stype);
|
||||
npc.getOrAddTrait(BoatTrait.class).setType(type);
|
||||
Messaging.sendTr(sender, Messages.BOAT_TYPE_SET, type);
|
||||
return;
|
||||
}
|
||||
throw new CommandUsageException();
|
||||
if (stype == null)
|
||||
throw new CommandUsageException();
|
||||
Boat.Type type = Boat.Type.valueOf(stype);
|
||||
npc.getOrAddTrait(BoatTrait.class).setType(type);
|
||||
Messaging.sendTr(sender, Messages.BOAT_TYPE_SET, type);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -452,7 +457,7 @@ public class NPCCommands {
|
||||
max = 1,
|
||||
valueFlags = "location",
|
||||
permission = "citizens.npc.breakblock")
|
||||
@Requirements(selected = true, ownership = true, livingEntity = true)
|
||||
@Requirements(selected = true, ownership = true)
|
||||
public void breakblock(CommandContext args, CommandSender sender, NPC npc, @Flag("radius") Double radius)
|
||||
throws CommandException {
|
||||
BlockBreakerConfiguration cfg = new BlockBreakerConfiguration();
|
||||
@ -694,31 +699,34 @@ public class NPCCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "controllable|control (-m(ount),-y,-n,-o(wner required))",
|
||||
usage = "controllable|control (-m(ount),-o(wner required)) (--controls [controls]) (--enabled [true|false])",
|
||||
desc = "",
|
||||
modifiers = { "controllable", "control" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
flags = "myno")
|
||||
public void controllable(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
flags = "mo")
|
||||
public void controllable(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Flag("controls") BuiltInControls controls, @Flag("enabled") Boolean enabled) throws CommandException {
|
||||
if ((npc.isSpawned() && !sender.hasPermission(
|
||||
"citizens.npc.controllable." + npc.getEntity().getType().name().toLowerCase().replace("_", "")))
|
||||
|| !sender.hasPermission("citizens.npc.controllable"))
|
||||
throw new NoPermissionsException();
|
||||
if (!npc.hasTrait(Controllable.class)) {
|
||||
if (!npc.hasTrait(Controllable.class) && enabled == null) {
|
||||
npc.getOrAddTrait(Controllable.class).setEnabled(false);
|
||||
}
|
||||
Controllable trait = npc.getOrAddTrait(Controllable.class);
|
||||
boolean enabled = trait.toggle();
|
||||
if (args.hasFlag('y')) {
|
||||
enabled = trait.setEnabled(true);
|
||||
} else if (args.hasFlag('n')) {
|
||||
enabled = trait.setEnabled(false);
|
||||
if (enabled != null) {
|
||||
trait.setEnabled(enabled);
|
||||
} else {
|
||||
enabled = trait.toggle();
|
||||
}
|
||||
if (controls != null) {
|
||||
trait.setControls(controls);
|
||||
}
|
||||
trait.setOwnerRequired(args.hasFlag('o'));
|
||||
String key = enabled ? Messages.CONTROLLABLE_SET : Messages.CONTROLLABLE_REMOVED;
|
||||
Messaging.sendTr(sender, key, npc.getName());
|
||||
if (enabled && args.hasFlag('m') && sender instanceof Player) {
|
||||
if (trait.isEnabled() && args.hasFlag('m') && sender instanceof Player) {
|
||||
trait.mount((Player) sender);
|
||||
}
|
||||
}
|
||||
@ -1045,6 +1053,22 @@ public class NPCCommands {
|
||||
throw new CommandUsageException();
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "entitypose [pose]",
|
||||
desc = "",
|
||||
modifiers = { "entitypose" },
|
||||
min = 2,
|
||||
max = 2,
|
||||
permission = "citizens.npc.entitypose")
|
||||
public void entitypose(CommandContext args, CommandSender sender, NPC npc, @Arg(1) EntityPose pose)
|
||||
throws CommandException {
|
||||
if (pose == null)
|
||||
throw new CommandUsageException();
|
||||
npc.getOrAddTrait(EntityPoseTrait.class).setPose(pose);
|
||||
Messaging.sendTr(sender, Messages.ENTITYPOSE_SET, pose);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "flyable (true|false)",
|
||||
@ -1112,6 +1136,38 @@ public class NPCCommands {
|
||||
player.getName());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "forcefield --width [width] --height [height] --strength [strength]",
|
||||
desc = "",
|
||||
modifiers = { "forcefield" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "citizens.npc.forcefield")
|
||||
public void forcefield(CommandContext args, CommandSender sender, NPC npc, @Flag("width") Double width,
|
||||
@Flag("height") Double height, @Flag("strength") Double strength) throws CommandException {
|
||||
ForcefieldTrait trait = npc.getOrAddTrait(ForcefieldTrait.class);
|
||||
String output = "";
|
||||
if (width != null) {
|
||||
trait.setWidth(width);
|
||||
output += Messaging.tr(Messages.FORCEFIELD_WIDTH_SET, width);
|
||||
}
|
||||
if (height != null) {
|
||||
trait.setHeight(height);
|
||||
output += Messaging.tr(Messages.FORCEFIELD_HEIGHT_SET, height);
|
||||
}
|
||||
if (strength != null) {
|
||||
trait.setStrength(strength);
|
||||
output += Messaging.tr(Messages.FORCEFIELD_STRENGTH_SET, strength);
|
||||
}
|
||||
if (!output.isEmpty()) {
|
||||
Messaging.send(sender, output);
|
||||
} else {
|
||||
Messaging.sendTr(sender, Messages.FORCEFIELD_DESCRIBE, npc.getName(), trait.getHeight(), trait.getWidth(),
|
||||
trait.getStrength());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "gamemode [gamemode]",
|
||||
@ -2374,8 +2430,6 @@ public class NPCCommands {
|
||||
}
|
||||
npc.data().setPersistent(NPC.Metadata.REMOVE_FROM_PLAYERLIST, remove);
|
||||
if (npc.isSpawned()) {
|
||||
npc.despawn(DespawnReason.PENDING_RESPAWN);
|
||||
npc.spawn(npc.getOrAddTrait(CurrentLocation.class).getLocation(), SpawnReason.RESPAWN);
|
||||
NMS.addOrRemoveFromPlayerList(npc.getEntity(), remove);
|
||||
}
|
||||
Messaging.sendTr(sender, remove ? Messages.REMOVED_FROM_PLAYERLIST : Messages.ADDED_TO_PLAYERLIST,
|
||||
@ -2805,7 +2859,7 @@ public class NPCCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "shop (edit|show|delete) (name)",
|
||||
usage = "shop (edit|show|delete|copyfrom) (name)",
|
||||
desc = "",
|
||||
modifiers = { "shop" },
|
||||
min = 1,
|
||||
@ -2813,7 +2867,8 @@ public class NPCCommands {
|
||||
permission = "citizens.npc.shop")
|
||||
@Requirements(selected = false, ownership = true)
|
||||
public void shop(CommandContext args, Player sender, NPC npc,
|
||||
@Arg(value = 1, completions = { "edit", "show", "delete" }) String action) throws CommandException {
|
||||
@Arg(value = 1, completions = { "edit", "show", "delete", "copyfrom" }) String action)
|
||||
throws CommandException {
|
||||
if (args.argsLength() == 1) {
|
||||
if (npc != null) {
|
||||
npc.getOrAddTrait(ShopTrait.class).getDefaultShop().display(sender);
|
||||
@ -2836,6 +2891,13 @@ public class NPCCommands {
|
||||
if (!shop.canEdit(npc, sender))
|
||||
throw new NoPermissionsException();
|
||||
shop.displayEditor(npc == null ? null : npc.getOrAddTrait(ShopTrait.class), sender);
|
||||
} else if (action.equalsIgnoreCase("copyfrom")) {
|
||||
if (!shop.canEdit(npc, sender) || !npc.getOrAddTrait(ShopTrait.class).getDefaultShop().canEdit(npc, sender))
|
||||
throw new NoPermissionsException();
|
||||
DataKey key = new MemoryDataKey();
|
||||
PersistenceLoader.save(shop, key);
|
||||
NPCShop copy = PersistenceLoader.load(NPCShop.class, key);
|
||||
npc.getOrAddTrait(ShopTrait.class).setDefaultShop(copy);
|
||||
} else if (action.equalsIgnoreCase("show")) {
|
||||
shop.display(sender);
|
||||
} else
|
||||
@ -3235,9 +3297,9 @@ public class NPCCommands {
|
||||
permission = "citizens.npc.swim")
|
||||
public void swim(CommandContext args, CommandSender sender, NPC npc, @Flag("set") Boolean set)
|
||||
throws CommandException {
|
||||
boolean swim = set != null ? set : !npc.data().get(NPC.Metadata.SWIMMING, true);
|
||||
npc.data().setPersistent(NPC.Metadata.SWIMMING, swim);
|
||||
Messaging.sendTr(sender, swim ? Messages.SWIMMING_SET : Messages.SWIMMING_UNSET, npc.getName());
|
||||
boolean swim = set != null ? set : !npc.data().get(NPC.Metadata.SWIM, true);
|
||||
npc.data().setPersistent(NPC.Metadata.SWIM, swim);
|
||||
Messaging.sendTr(sender, swim ? Messages.SWIM_SET : Messages.SWIM_UNSET, npc.getName());
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -3276,12 +3338,24 @@ public class NPCCommands {
|
||||
flags = "t",
|
||||
permission = "citizens.npc.targetable")
|
||||
public void targetable(CommandContext args, CommandSender sender, NPC npc) {
|
||||
boolean targetable = !npc.data().get(NPC.Metadata.TARGETABLE, !npc.isProtected());
|
||||
boolean targetable = !npc.data().get(NPC.Metadata.TARGETABLE, npc.isProtected());
|
||||
if (args.hasFlag('t')) {
|
||||
npc.data().set(NPC.Metadata.TARGETABLE, targetable);
|
||||
} else {
|
||||
npc.data().setPersistent(NPC.Metadata.TARGETABLE, targetable);
|
||||
}
|
||||
if (targetable && npc.getOrAddTrait(MobType.class).getType() == EntityType.PLAYER
|
||||
&& npc.data().get(NPC.Metadata.REMOVE_FROM_PLAYERLIST, true)) {
|
||||
Messaging.sendTr(sender, Messages.TARGETABLE_PLAYERLIST_WARNING);
|
||||
if (args.hasFlag('t')) {
|
||||
npc.data().set(NPC.Metadata.REMOVE_FROM_PLAYERLIST, false);
|
||||
} else {
|
||||
npc.data().setPersistent(NPC.Metadata.REMOVE_FROM_PLAYERLIST, false);
|
||||
}
|
||||
if (npc.isSpawned()) {
|
||||
NMS.addOrRemoveFromPlayerList(npc.getEntity(), false);
|
||||
}
|
||||
}
|
||||
Messaging.sendTr(sender, targetable ? Messages.TARGETABLE_SET : Messages.TARGETABLE_UNSET, npc.getName());
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,9 @@ import com.google.common.collect.Lists;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.command.Command;
|
||||
import net.citizensnpcs.api.command.CommandConfigurable;
|
||||
import net.citizensnpcs.api.command.CommandContext;
|
||||
import net.citizensnpcs.api.command.Requirements;
|
||||
import net.citizensnpcs.api.command.exception.CommandException;
|
||||
import net.citizensnpcs.api.command.exception.NoPermissionsException;
|
||||
import net.citizensnpcs.api.event.NPCTraitCommandAttachEvent;
|
||||
import net.citizensnpcs.api.event.NPCTraitCommandDetachEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
@ -67,30 +65,6 @@ public class TraitCommands {
|
||||
Bukkit.getPluginManager().callEvent(new NPCTraitCommandAttachEvent(npc, clazz, sender));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "traitc", "trc" },
|
||||
usage = "[trait name] (flags)",
|
||||
desc = "",
|
||||
modifiers = { "*" },
|
||||
min = 1,
|
||||
flags = "*",
|
||||
permission = "citizens.npc.trait-configure")
|
||||
public void configure(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
String traitName = args.getString(0);
|
||||
if (!sender.hasPermission("citizens.npc.trait-configure." + traitName)
|
||||
&& !sender.hasPermission("citizens.npc.trait-configure.*"))
|
||||
throw new NoPermissionsException();
|
||||
Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(args.getString(0));
|
||||
if (clazz == null)
|
||||
throw new CommandException(Messages.TRAIT_NOT_FOUND);
|
||||
if (!CommandConfigurable.class.isAssignableFrom(clazz))
|
||||
throw new CommandException(Messages.TRAIT_NOT_CONFIGURABLE);
|
||||
if (!npc.hasTrait(clazz))
|
||||
throw new CommandException(Messages.TRAIT_NOT_FOUND_ON_NPC);
|
||||
CommandConfigurable trait = (CommandConfigurable) npc.getOrAddTrait(clazz);
|
||||
trait.configure(args);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "trait" },
|
||||
usage = "remove [trait names]...",
|
||||
|
@ -486,7 +486,7 @@ public class CitizensNPC extends AbstractNPC {
|
||||
NMS.activate(getEntity());
|
||||
}
|
||||
}
|
||||
boolean shouldSwim = data().get(NPC.Metadata.SWIMMING, SwimmingExaminer.isWaterMob(getEntity()))
|
||||
boolean shouldSwim = data().get(NPC.Metadata.SWIM, SwimmingExaminer.isWaterMob(getEntity()))
|
||||
&& MinecraftBlockExaminer.isLiquid(getEntity().getLocation().getBlock().getType());
|
||||
if (navigator.isNavigating()) {
|
||||
if (shouldSwim) {
|
||||
|
@ -34,6 +34,7 @@ import net.citizensnpcs.trait.EnderCrystalTrait;
|
||||
import net.citizensnpcs.trait.EndermanTrait;
|
||||
import net.citizensnpcs.trait.EntityPoseTrait;
|
||||
import net.citizensnpcs.trait.FollowTrait;
|
||||
import net.citizensnpcs.trait.ForcefieldTrait;
|
||||
import net.citizensnpcs.trait.GameModeTrait;
|
||||
import net.citizensnpcs.trait.Gravity;
|
||||
import net.citizensnpcs.trait.HologramTrait;
|
||||
@ -90,6 +91,7 @@ public class CitizensTraitFactory implements TraitFactory {
|
||||
registerTrait(TraitInfo.create(EntityPoseTrait.class));
|
||||
registerTrait(TraitInfo.create(Equipment.class));
|
||||
registerTrait(TraitInfo.create(FollowTrait.class).optInToStats());
|
||||
registerTrait(TraitInfo.create(ForcefieldTrait.class).optInToStats());
|
||||
registerTrait(TraitInfo.create(GameModeTrait.class));
|
||||
registerTrait(TraitInfo.create(Gravity.class));
|
||||
registerTrait(TraitInfo.create(HomeTrait.class).optInToStats());
|
||||
|
@ -45,9 +45,10 @@ public class Anchors extends Trait {
|
||||
}
|
||||
|
||||
public Anchor getAnchor(String name) {
|
||||
for (Anchor anchor : anchors)
|
||||
for (Anchor anchor : anchors) {
|
||||
if (anchor.getName().equalsIgnoreCase(name))
|
||||
return anchor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -75,11 +76,7 @@ public class Anchors extends Trait {
|
||||
}
|
||||
|
||||
public boolean removeAnchor(Anchor anchor) {
|
||||
if (anchors.contains(anchor)) {
|
||||
anchors.remove(anchor);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return anchors.remove(anchor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,13 +1,10 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
@ -17,19 +14,13 @@ import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.command.CommandConfigurable;
|
||||
import net.citizensnpcs.api.command.CommandContext;
|
||||
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
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.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
||||
@ -40,11 +31,12 @@ import net.citizensnpcs.util.Util;
|
||||
* e.g. arrow keys.
|
||||
*/
|
||||
@TraitName("controllable")
|
||||
public class Controllable extends Trait implements Toggleable, CommandConfigurable {
|
||||
public class Controllable extends Trait implements Toggleable {
|
||||
private MovementController controller = new GroundController();
|
||||
@Persist
|
||||
private BuiltInControls controls;
|
||||
@Persist
|
||||
private boolean enabled = true;
|
||||
private EntityType explicitType;
|
||||
@Persist("owner_required")
|
||||
private boolean ownerRequired;
|
||||
|
||||
@ -52,29 +44,6 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
super("controllable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the explicit type parameter.
|
||||
*
|
||||
* @see #setExplicitType(EntityType)
|
||||
*/
|
||||
@Override
|
||||
public void configure(CommandContext args) {
|
||||
if (args.hasFlag('f')) {
|
||||
explicitType = EntityType.BLAZE;
|
||||
} else if (args.hasFlag('g')) {
|
||||
explicitType = EntityType.OCELOT;
|
||||
} else if (args.hasFlag('o')) {
|
||||
explicitType = EntityType.UNKNOWN;
|
||||
} else if (args.hasFlag('r')) {
|
||||
explicitType = null;
|
||||
} else if (args.hasValueFlag("explicittype")) {
|
||||
explicitType = Util.matchEnum(EntityType.values(), args.getFlag("explicittype"));
|
||||
}
|
||||
if (npc.isSpawned()) {
|
||||
loadController();
|
||||
}
|
||||
}
|
||||
|
||||
private void enterOrLeaveVehicle(Player player) {
|
||||
List<Entity> passengers = NMS.getPassengers(player);
|
||||
if (passengers.size() > 0) {
|
||||
@ -96,36 +65,18 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) throws NPCLoadException {
|
||||
if (key.keyExists("explicittype")) {
|
||||
explicitType = Util.matchEnum(EntityType.values(), key.getString("explicittype"));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadController() {
|
||||
EntityType type = npc.getEntity().getType();
|
||||
if (explicitType != null) {
|
||||
type = explicitType;
|
||||
if (controls != null) {
|
||||
controller = controls.create(this);
|
||||
return;
|
||||
}
|
||||
if (!(npc.getEntity() instanceof LivingEntity) && !(npc.getEntity() instanceof Vehicle) && (explicitType == null
|
||||
|| explicitType == EntityType.UNKNOWN || npc.getEntity().getType() == explicitType)) {
|
||||
if (!(npc.getEntity() instanceof LivingEntity) && !(npc.getEntity() instanceof Vehicle)) {
|
||||
controller = new LookAirController();
|
||||
return;
|
||||
}
|
||||
Constructor<? extends MovementController> innerConstructor = CONTROLLER_TYPES.get(type);
|
||||
if (innerConstructor == null) {
|
||||
controller = new GroundController();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (innerConstructor.getParameterCount() == 0) {
|
||||
controller = innerConstructor.newInstance();
|
||||
} else {
|
||||
controller = innerConstructor.newInstance(this);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (Util.isAlwaysFlyable(npc.getEntity().getType())) {
|
||||
controller = new PlayerInputAirController();
|
||||
} else {
|
||||
controller = new GroundController();
|
||||
}
|
||||
}
|
||||
@ -202,13 +153,8 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
controller.run((Player) passengers.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
if (explicitType == null) {
|
||||
key.removeKey("explicittype");
|
||||
} else {
|
||||
key.setString("explicittype", explicitType.name());
|
||||
}
|
||||
public void setControls(BuiltInControls controls) {
|
||||
this.controls = controls;
|
||||
}
|
||||
|
||||
public boolean setEnabled(boolean enabled) {
|
||||
@ -216,16 +162,6 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the explicit typei.e. whether the NPC should be controlled as if it was a certain {@link EntityType}.
|
||||
*
|
||||
* @param type
|
||||
* the explicit type
|
||||
*/
|
||||
public void setExplicitType(EntityType type) {
|
||||
explicitType = type;
|
||||
}
|
||||
|
||||
private void setMountedYaw(Entity entity) {
|
||||
if (entity instanceof EnderDragon || !Setting.USE_BOAT_CONTROLS.asBoolean())
|
||||
return; // EnderDragon handles this separately
|
||||
@ -297,6 +233,35 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
}
|
||||
}
|
||||
|
||||
public enum BuiltInControls {
|
||||
AIR {
|
||||
@Override
|
||||
MovementController create(Controllable trait) {
|
||||
return trait.new PlayerInputAirController();
|
||||
}
|
||||
},
|
||||
GROUND {
|
||||
@Override
|
||||
MovementController create(Controllable trait) {
|
||||
return trait.new GroundController();
|
||||
}
|
||||
},
|
||||
GROUND_JUMPLESS {
|
||||
@Override
|
||||
MovementController create(Controllable trait) {
|
||||
return trait.new JumplessGroundController();
|
||||
}
|
||||
},
|
||||
LOOK_AIR {
|
||||
@Override
|
||||
MovementController create(Controllable trait) {
|
||||
return trait.new LookAirController();
|
||||
}
|
||||
};
|
||||
|
||||
abstract MovementController create(Controllable trait);
|
||||
}
|
||||
|
||||
public class GroundController implements MovementController {
|
||||
private int jumpTicks = 0;
|
||||
private double speed = 0.07D;
|
||||
@ -336,6 +301,38 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
private static final float JUMP_VELOCITY = 0.5F;
|
||||
}
|
||||
|
||||
public class JumplessGroundController implements MovementController {
|
||||
private double speed = 0.07D;
|
||||
|
||||
@Override
|
||||
public void leftClick(PlayerInteractEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rightClick(PlayerInteractEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rightClickEntity(NPCRightClickEvent event) {
|
||||
enterOrLeaveVehicle(event.getClicker());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player rider) {
|
||||
boolean onGround = NMS.isOnGround(npc.getEntity());
|
||||
float impulse = npc.getNavigator().getDefaultParameters()
|
||||
.modifiedSpeed(onGround ? GROUND_SPEED : AIR_SPEED);
|
||||
if (!Util.isHorse(npc.getEntity().getType())) {
|
||||
speed = updateHorizontalSpeed(npc.getEntity(), rider, speed, impulse,
|
||||
Setting.MAX_CONTROLLABLE_GROUND_SPEED.asDouble());
|
||||
}
|
||||
setMountedYaw(npc.getEntity());
|
||||
}
|
||||
|
||||
private static final float AIR_SPEED = 0.5F;
|
||||
private static final float GROUND_SPEED = 0.5F;
|
||||
}
|
||||
|
||||
public class LookAirController implements MovementController {
|
||||
private boolean paused = false;
|
||||
|
||||
@ -412,44 +409,4 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
||||
setMountedYaw(npc.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a movement controller for a certain {@link EntityType} to be used for {@link NPC}s with that type.
|
||||
*
|
||||
* Default controllers are registered for BAT, BLAZE, ENDER_DRAGON, GHAST, WITHER and PARROT using
|
||||
* {@link PlayerInputAirController}.
|
||||
*
|
||||
* @param type
|
||||
* the entity type
|
||||
* @param clazz
|
||||
* the controller class
|
||||
*/
|
||||
public static void registerControllerType(EntityType type, Class<? extends MovementController> clazz) {
|
||||
try {
|
||||
Constructor<? extends MovementController> constructor = clazz.getConstructor(Controllable.class);
|
||||
constructor.setAccessible(true);
|
||||
CONTROLLER_TYPES.put(type, constructor);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Constructor<? extends MovementController> constructor = clazz.getConstructor();
|
||||
constructor.setAccessible(true);
|
||||
CONTROLLER_TYPES.put(type, constructor);
|
||||
} catch (Exception e2) {
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<EntityType, Constructor<? extends MovementController>> CONTROLLER_TYPES = Maps
|
||||
.newEnumMap(EntityType.class);
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
if (Util.isAlwaysFlyable(type)) {
|
||||
registerControllerType(type, PlayerInputAirController.class);
|
||||
}
|
||||
}
|
||||
registerControllerType(EntityType.UNKNOWN, LookAirController.class);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
|
||||
@TraitName("forcefieldtrait")
|
||||
public class ForcefieldTrait extends Trait {
|
||||
@Persist
|
||||
private Double height;
|
||||
@Persist
|
||||
private Double strength;
|
||||
@Persist
|
||||
private Double width;
|
||||
|
||||
public ForcefieldTrait() {
|
||||
super("forcefieldtrait");
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return height == null ? npc.getEntity().getHeight() : height;
|
||||
}
|
||||
|
||||
public double getStrength() {
|
||||
return strength == null ? 0.1 : strength;
|
||||
}
|
||||
|
||||
public double getWidth() {
|
||||
return width == null ? npc.getEntity().getWidth() : width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!npc.isSpawned())
|
||||
return;
|
||||
double height = getHeight();
|
||||
double width = getWidth();
|
||||
double strength = getStrength();
|
||||
Location base = npc.getEntity().getLocation();
|
||||
for (Player player : CitizensAPI.getLocationLookup().getNearbyVisiblePlayers(npc.getEntity(),
|
||||
new double[] { base.getX() - width / 1.9, base.getY(), base.getZ() - width / 1.9 },
|
||||
new double[] { base.getX() + width / 1.9, base.getY() + height, base.getZ() + width / 1.9 })) {
|
||||
Vector diff = player.getLocation().subtract(base).toVector();
|
||||
if (diff.isZero())
|
||||
continue;
|
||||
diff = diff.normalize().setY(0);
|
||||
Vector force = player.getVelocity().add(diff.multiply(strength));
|
||||
player.setVelocity(force);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHeight(Double height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setStrength(Double strength) {
|
||||
this.strength = strength;
|
||||
}
|
||||
|
||||
public void setWidth(Double width) {
|
||||
this.width = width;
|
||||
}
|
||||
}
|
@ -457,12 +457,11 @@ public class HologramTrait extends Trait {
|
||||
mb = 0.21;
|
||||
mt = 0.07;
|
||||
hr = new ItemRenderer();
|
||||
} else if (SUPPORTS_DISPLAY && backgroundColor != null) {
|
||||
renderer = new TextDisplayRenderer(backgroundColor);
|
||||
}
|
||||
this.persist = persist;
|
||||
this.ticks = ticks;
|
||||
this.renderer = hr;
|
||||
renderer.setBackgroundColor(backgroundColor);
|
||||
if (renderer instanceof SingleEntityHologramRenderer) {
|
||||
SingleEntityHologramRenderer sr = (SingleEntityHologramRenderer) renderer;
|
||||
sr.setViewRange(viewRange);
|
||||
|
@ -117,6 +117,10 @@ public class ShopTrait extends Trait {
|
||||
shop.display(player);
|
||||
}
|
||||
|
||||
public void setDefaultShop(NPCShop shop) {
|
||||
shops.npcShops.put(npc.getUniqueId().toString(), shop);
|
||||
}
|
||||
|
||||
public static class NPCShop {
|
||||
@Persist(value = "")
|
||||
private String name;
|
||||
|
@ -0,0 +1,175 @@
|
||||
package net.citizensnpcs.trait.versioned;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Display;
|
||||
import org.bukkit.entity.Display.Billboard;
|
||||
import org.bukkit.entity.Display.Brightness;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.util.Transformation;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.joml.Quaternionf;
|
||||
|
||||
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;
|
||||
|
||||
@TraitName("displaytrait")
|
||||
public class DisplayTrait extends Trait {
|
||||
@Persist
|
||||
private Billboard billboard;
|
||||
@Persist
|
||||
private Integer blockLight;
|
||||
@Persist
|
||||
private Float height;
|
||||
@Persist
|
||||
private Integer interpolationDelay;
|
||||
@Persist
|
||||
private Integer interpolationDuration;
|
||||
@Persist
|
||||
private Quaternionf leftRotation;
|
||||
@Persist
|
||||
private Quaternionf rightRotation;
|
||||
@Persist
|
||||
private Vector scale;
|
||||
@Persist
|
||||
private Integer skyLight;
|
||||
@Persist
|
||||
private Float viewRange;
|
||||
@Persist
|
||||
private Float width;
|
||||
|
||||
public DisplayTrait() {
|
||||
super("displaytrait");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn() {
|
||||
Display display = (Display) npc.getEntity();
|
||||
if (billboard != null) {
|
||||
display.setBillboard(billboard);
|
||||
}
|
||||
if (blockLight != null && skyLight != null) {
|
||||
display.setBrightness(new Brightness(blockLight, skyLight));
|
||||
}
|
||||
if (interpolationDelay != null) {
|
||||
display.setInterpolationDelay(interpolationDelay);
|
||||
}
|
||||
if (interpolationDuration != null) {
|
||||
display.setInterpolationDuration(interpolationDuration);
|
||||
}
|
||||
if (height != null) {
|
||||
display.setDisplayHeight(height);
|
||||
}
|
||||
if (width != null) {
|
||||
display.setDisplayWidth(width);
|
||||
}
|
||||
Transformation tf = display.getTransformation();
|
||||
if (scale != null) {
|
||||
tf.getScale().set(scale.getX(), scale.getY(), scale.getZ());
|
||||
}
|
||||
if (leftRotation != null) {
|
||||
tf.getLeftRotation().set(leftRotation);
|
||||
}
|
||||
if (rightRotation != null) {
|
||||
tf.getRightRotation().set(rightRotation);
|
||||
}
|
||||
display.setTransformation(tf);
|
||||
if (viewRange != null) {
|
||||
display.setViewRange(viewRange);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBillboard(Billboard billboard) {
|
||||
this.billboard = billboard;
|
||||
}
|
||||
|
||||
public void setBrightness(Brightness brightness) {
|
||||
this.blockLight = brightness.getBlockLight();
|
||||
this.skyLight = brightness.getSkyLight();
|
||||
}
|
||||
|
||||
public void setHeight(Float height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setInterpolationDelay(Integer interpolationDelay) {
|
||||
this.interpolationDelay = interpolationDelay;
|
||||
}
|
||||
|
||||
public void setInterpolationDuration(Integer interpolationDuration) {
|
||||
this.interpolationDuration = interpolationDuration;
|
||||
}
|
||||
|
||||
public void setScale(Vector scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public void setViewRange(Float viewRange) {
|
||||
this.viewRange = viewRange;
|
||||
}
|
||||
|
||||
public void setWidth(Float width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "display --billboard [billboard] --brightness [blockLight,skyLight] --interpolationdelay [delay] --interpolationduration [duration] --height [height] --width [width] --scale [x,y,z] --viewrange [range] --leftrotation [x,y,z,w] --rightrotation [x,y,z,w]",
|
||||
desc = "",
|
||||
modifiers = { "display" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "citizens.npc.display")
|
||||
@Requirements(
|
||||
selected = true,
|
||||
ownership = true,
|
||||
types = { EntityType.ITEM_DISPLAY, EntityType.TEXT_DISPLAY, EntityType.BLOCK_DISPLAY })
|
||||
public static void display(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Flag("billboard") Billboard billboard, @Flag("leftrotation") Quaternionf leftrotation,
|
||||
@Flag("rightrotation") Quaternionf rightrotation, @Flag("scale") Vector scale,
|
||||
@Flag("viewrange") Float viewRange, @Flag("brightness") String brightness,
|
||||
@Flag("interpolationdelay") Integer interpolationDelay,
|
||||
@Flag("interpolationduration") Integer interpolationDuration, @Flag("height") Float height,
|
||||
@Flag("width") Float width) throws CommandException {
|
||||
DisplayTrait trait = npc.getOrAddTrait(DisplayTrait.class);
|
||||
String output = "";
|
||||
if (billboard != null) {
|
||||
trait.setBillboard(billboard);
|
||||
}
|
||||
if (brightness != null) {
|
||||
trait.setBrightness(new Brightness(Integer.parseInt(brightness.split(",")[0]),
|
||||
Integer.parseInt(brightness.split(",")[1])));
|
||||
}
|
||||
if (interpolationDelay != null) {
|
||||
trait.setInterpolationDelay(interpolationDelay);
|
||||
}
|
||||
if (interpolationDuration != null) {
|
||||
trait.setInterpolationDuration(interpolationDuration);
|
||||
}
|
||||
if (width != null) {
|
||||
trait.setWidth(width);
|
||||
}
|
||||
if (height != null) {
|
||||
trait.setHeight(height);
|
||||
}
|
||||
if (viewRange != null) {
|
||||
trait.setViewRange(viewRange);
|
||||
}
|
||||
if (scale != null) {
|
||||
trait.setScale(scale);
|
||||
}
|
||||
trait.onSpawn();
|
||||
if (!output.isEmpty()) {
|
||||
Messaging.send(sender, output.trim());
|
||||
} else
|
||||
throw new CommandUsageException();
|
||||
}
|
||||
}
|
@ -103,6 +103,7 @@ public class Messages {
|
||||
public static final String ENDERMAN_ANGRY_SET = "citizens.commands.npc.enderman.angry-set";
|
||||
public static final String ENDERMAN_ANGRY_UNSET = "citizens.commands.npc.enderman.angry-unset";
|
||||
public static final String ENTITY_TYPE_SET = "citizens.commands.npc.type.set";
|
||||
public static final String ENTITYPOSE_SET = "citizens.commands.npc.entitypose.set";
|
||||
public static final String EQUIPMENT_EDITOR_BEGIN = "citizens.editors.equipment.begin";
|
||||
public static final String EQUIPMENT_EDITOR_END = "citizens.editors.equipment.end";
|
||||
public static final String EQUIPMENT_EDITOR_SHEEP_COLOURED = "citizens.editors.equipment.sheep-coloured";
|
||||
@ -126,6 +127,10 @@ public class Messages {
|
||||
public static final String FOLLOW_PLAYER_NOT_INGAME = "citizens.commands.npc.follow.player-not-ingame";
|
||||
public static final String FOLLOW_SET = "citizens.commands.npc.follow.set";
|
||||
public static final String FOLLOW_UNSET = "citizens.commands.npc.follow.unset";
|
||||
public static final String FORCEFIELD_DESCRIBE = "citizens.commands.npc.forcefield.describe";
|
||||
public static final String FORCEFIELD_HEIGHT_SET = "citizens.commands.npc.forcefield.height-set";
|
||||
public static final String FORCEFIELD_STRENGTH_SET = "citizens.commands.npc.forcefield.strength-set";
|
||||
public static final String FORCEFIELD_WIDTH_SET = "citizens.commands.npc.forcefield.width-set";
|
||||
public static final String FOX_CROUCHING_SET = "citizens.commands.npc.fox.crouching-set";
|
||||
public static final String FOX_CROUCHING_UNSET = "citizens.commands.npc.fox.crouching-unset";
|
||||
public static final String FOX_FACEPLANTED_SET = "citizens.commands.npc.fox.faceplanted-set";
|
||||
@ -407,8 +412,9 @@ public class Messages {
|
||||
public static final String SPEED_MODIFIER_SET = "citizens.commands.npc.speed.set";
|
||||
public static final String SPEED_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.speed.prompt";
|
||||
public static final String SPELL_SET = "citizens.commands.npc.spellcaster.spell-set";
|
||||
public static final String SWIMMING_SET = "citizens.commands.npc.swim.set";
|
||||
public static final String SWIMMING_UNSET = "citizens.commands.npc.swim.unset";
|
||||
public static final String SWIM_SET = "citizens.commands.npc.swim.set";
|
||||
public static final String SWIM_UNSET = "citizens.commands.npc.swim.unset";
|
||||
public static final String TARGETABLE_PLAYERLIST_WARNING = "citizens.commands.npc.targetable.playerlist-warning";
|
||||
public static final String TARGETABLE_SET = "citizens.commands.npc.targetable.set";
|
||||
public static final String TARGETABLE_UNSET = "citizens.commands.npc.targetable.unset";
|
||||
public static final String TELEPORT_NPC_LOCATION_NOT_FOUND = "citizens.commands.npc.tp.location-not-found";
|
||||
@ -442,9 +448,6 @@ public class Messages {
|
||||
public static final String TPTO_SUCCESS = "citizens.commands.npc.tpto.success";
|
||||
public static final String TRACKING_RANGE_SET = "citizens.commands.npc.trackingrange.set";
|
||||
public static final String TRAIT_LOAD_FAILED = "citizens.notifications.trait-load-failed";
|
||||
public static final String TRAIT_NOT_CONFIGURABLE = "citizens.commands.traitc.not-configurable";
|
||||
public static final String TRAIT_NOT_FOUND = "citizens.commands.traitc.missing";
|
||||
public static final String TRAIT_NOT_FOUND_ON_NPC = "citizens.commands.traitc.not-on-npc";
|
||||
public static final String TRAIT_ONSPAWN_FAILED = "citizens.notifications.trait-onspawn-failed";
|
||||
public static final String TRAITS_ADDED = "citizens.commands.trait.added";
|
||||
public static final String TRAITS_FAILED_TO_ADD = "citizens.commands.trait.failed-to-add";
|
||||
|
@ -13,6 +13,7 @@
|
||||
"citizens.commands.help.header" : "Help",
|
||||
"citizens.commands.id-not-found" : "Couldn''t find any NPC with ID [[{0}]].",
|
||||
"citizens.commands.invalid-mobtype" : "[[{0}]] is not a valid mobtype.",
|
||||
"citizens.commands.npc.targetable.playerlist-warning" : "Adding NPC to the player list to allow targeting by other mobs. This may cause plugin conflicts. You can turn this off by using /npc playerlist at any time.",
|
||||
"citizens.commands.invalid-number" : "That is not a valid number.",
|
||||
"citizens.commands.invalid.class" : "Invalid external commands class.",
|
||||
"citizens.commands.npc.activationrange.description" : "Sets the activation range",
|
||||
@ -23,13 +24,21 @@
|
||||
"citizens.commands.npc.age.help" : "Can only be used on entities that can become babies. Use the [[-l]] flag to lock age over time (note: relogs may be required to see this).",
|
||||
"citizens.commands.npc.age.invalid-age" : "Invalid age. Valid ages are adult, baby, number between -24000 and 0",
|
||||
"citizens.commands.npc.age.locked" : "Age locked.",
|
||||
"citizens.commands.npc.forcefield.describe": "[[{0}] has a forcefield with height [[{1}]], width [[{2}]], strength [[{3}]].",
|
||||
"citizens.commands.npc.forcefield.description": "Creates a forcefield which pushes players close to the NPC away",
|
||||
"citizens.commands.npc.age.set" : "[[{0}]] is now [[{1}]].",
|
||||
"citizens.commands.npc.forcefield.width-set": "Forcefield width set to [[{0}]] blocks.",
|
||||
"citizens.commands.npc.forcefield.height-set": "Forcefield height set to [[{0}]] blocks.",
|
||||
"citizens.commands.npc.forcefield.strength-set": "Forcefield strength set to [[{0}]] blocks per tick.",
|
||||
"citizens.commands.npc.age.set-adult" : "[[{0}]] is now an adult.",
|
||||
"citizens.commands.npc.age.set-baby" : "[[{0}]] is now a baby.",
|
||||
"citizens.commands.npc.display.description" : "Set various display entity modifiers",
|
||||
"citizens.commands.npc.age.set-normal" : "[[{0}]] is now age [[{1}]].",
|
||||
"citizens.commands.npc.age.unlocked" : "Age unlocked.",
|
||||
"citizens.commands.npc.aggressive.description" : "Sets the aggressive status of the entity",
|
||||
"citizens.commands.npc.aggressive.help" : "",
|
||||
"citizens.commands.npc.entitypose.set" : "Set entity pose to [[{0}]]",
|
||||
"citizens.commands.npc.entitypose.description" : "Control entity pose",
|
||||
"citizens.commands.npc.ai.description" : "Sets whether the NPC should use vanilla AI",
|
||||
"citizens.commands.npc.attribute.set" : "Attribute [[{0}]] set to base value [[{1}]].",
|
||||
"citizens.commands.npc.attribute.reset" : "Attribute [[{0}]] reset to default value.",
|
||||
@ -641,12 +650,7 @@
|
||||
"citizens.commands.trait.failed-to-remove" : "Couldn''t remove {0}.",
|
||||
"citizens.commands.trait.remove.description" : "Removes traits on the NPC",
|
||||
"citizens.commands.trait.remove.help" : "",
|
||||
"citizens.commands.trait.removed" : "Removed {0} successfully.",
|
||||
"citizens.commands.traitc.*.description" : "Configures a trait",
|
||||
"citizens.commands.traitc.*.help" : "",
|
||||
"citizens.commands.traitc.missing" : "Trait not found.",
|
||||
"citizens.commands.traitc.not-configurable" : "That trait is not configurable.",
|
||||
"citizens.commands.traitc.not-on-npc" : "The NPC doesn''t have that trait.",
|
||||
"citizens.commands.trait.removed" : "Removed {0} successfully.",
|
||||
"citizens.commands.unknown-command" : "Unknown command.",
|
||||
"citizens.commands.waypoints.add.description" : "Adds a waypoint at a point",
|
||||
"citizens.commands.waypoints.add.help" : "",
|
||||
|
@ -6,10 +6,6 @@ main: net.citizensnpcs.Citizens
|
||||
website: https://www.citizensnpcs.co
|
||||
api-version: "1.13"
|
||||
commands:
|
||||
traitc:
|
||||
aliases: [trc]
|
||||
description: Configures traits
|
||||
permission: citizens.trait.help
|
||||
trait:
|
||||
description: Trait commands
|
||||
permission: citizens.trait.help
|
||||
|
@ -223,6 +223,7 @@ import net.citizensnpcs.trait.versioned.BossBarTrait;
|
||||
import net.citizensnpcs.trait.versioned.CamelTrait;
|
||||
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
|
||||
import net.citizensnpcs.trait.versioned.CatTrait;
|
||||
import net.citizensnpcs.trait.versioned.DisplayTrait;
|
||||
import net.citizensnpcs.trait.versioned.EnderDragonTrait;
|
||||
import net.citizensnpcs.trait.versioned.FoxTrait;
|
||||
import net.citizensnpcs.trait.versioned.FrogTrait;
|
||||
@ -958,6 +959,7 @@ public class NMSImpl implements NMSBridge {
|
||||
registerTraitWithCommand(manager, BossBarTrait.class);
|
||||
registerTraitWithCommand(manager, CamelTrait.class);
|
||||
registerTraitWithCommand(manager, CatTrait.class);
|
||||
registerTraitWithCommand(manager, DisplayTrait.class);
|
||||
registerTraitWithCommand(manager, FoxTrait.class);
|
||||
registerTraitWithCommand(manager, FrogTrait.class);
|
||||
registerTraitWithCommand(manager, GoatTrait.class);
|
||||
|
@ -54,9 +54,7 @@ public class HorseController extends MobEntityController {
|
||||
|
||||
public static class EntityHorseNPC extends Horse implements NPCHolder {
|
||||
private double baseMovementSpeed;
|
||||
|
||||
private final CitizensNPC npc;
|
||||
|
||||
private boolean riding;
|
||||
|
||||
public EntityHorseNPC(EntityType<? extends Horse> types, Level level) {
|
||||
|
@ -221,6 +221,7 @@ import net.citizensnpcs.trait.versioned.BossBarTrait;
|
||||
import net.citizensnpcs.trait.versioned.CamelTrait;
|
||||
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
|
||||
import net.citizensnpcs.trait.versioned.CatTrait;
|
||||
import net.citizensnpcs.trait.versioned.DisplayTrait;
|
||||
import net.citizensnpcs.trait.versioned.EnderDragonTrait;
|
||||
import net.citizensnpcs.trait.versioned.FoxTrait;
|
||||
import net.citizensnpcs.trait.versioned.FrogTrait;
|
||||
@ -935,6 +936,7 @@ public class NMSImpl implements NMSBridge {
|
||||
registerTraitWithCommand(manager, BossBarTrait.class);
|
||||
registerTraitWithCommand(manager, CamelTrait.class);
|
||||
registerTraitWithCommand(manager, CatTrait.class);
|
||||
registerTraitWithCommand(manager, DisplayTrait.class);
|
||||
registerTraitWithCommand(manager, FoxTrait.class);
|
||||
registerTraitWithCommand(manager, FrogTrait.class);
|
||||
registerTraitWithCommand(manager, GoatTrait.class);
|
||||
|
Loading…
Reference in New Issue
Block a user