Add /npc horse -t and /npc hologram add --duration

This commit is contained in:
fullwall 2025-01-05 20:20:54 +08:00
parent 9475b283c2
commit 7e87f2ff27
6 changed files with 57 additions and 34 deletions

View File

@ -113,6 +113,7 @@ import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Paginator;
import net.citizensnpcs.api.util.Placeholders;
import net.citizensnpcs.api.util.SpigotUtil;
import net.citizensnpcs.commands.TemplateCommands.TemplateCompletions;
import net.citizensnpcs.commands.gui.NPCConfigurator;
import net.citizensnpcs.commands.history.CommandHistory;
import net.citizensnpcs.commands.history.CreateNPCHistoryItem;
@ -811,7 +812,8 @@ public class NPCCommands {
@Flag(value = "type", defValue = "PLAYER") EntityType type, @Flag("trait") String traits,
@Flag(value = "nameplate", completions = { "true", "false", "hover" }) String nameplate,
@Flag("temporaryduration") Duration temporaryDuration, @Flag("item") String item,
@Flag("template") String templateName, @Flag("registry") String registryName) throws CommandException {
@Flag(value = "template", completionsProvider = TemplateCompletions.class) String templateName,
@Flag("registry") String registryName) throws CommandException {
String name = args.getJoinedStrings(1).trim();
if (args.hasValueFlag("type")) {
if (type == null)
@ -1284,7 +1286,7 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "hologram add [text] | insert [line #] [text] | set [line #] [text] | remove [line #] | textshadow [line #] | bgcolor [line #] (red,green,blue(,alpha)) | clear | lineheight [height] | viewrange [range] | margintop [line #] [margin] | marginbottom [line #] [margin]",
usage = "hologram add [text] (--duration [duration]) | insert [line #] [text] | set [line #] [text] | remove [line #] | textshadow [line #] | bgcolor [line #] (red,green,blue(,alpha)) | clear | lineheight [height] | viewrange [range] | margintop [line #] [margin] | marginbottom [line #] [margin]",
desc = "",
modifiers = { "hologram" },
min = 1,
@ -1295,8 +1297,8 @@ public class NPCCommands {
value = 1,
completions = { "add", "insert", "set", "bgcolor", "textshadow", "remove", "clear", "lineheight",
"viewrange", "margintop", "marginbottom" }) String action,
@Arg(value = 2, completionsProvider = HologramTrait.TabCompletions.class) String secondCompletion)
throws CommandException {
@Arg(value = 2, completionsProvider = HologramTrait.TabCompletions.class) String secondCompletion,
@Flag("duration") Duration duration) throws CommandException {
HologramTrait trait = npc.getOrAddTrait(HologramTrait.class);
if (args.argsLength() == 1) {
String output = Messaging.tr(Messages.HOLOGRAM_DESCRIBE_HEADER, npc.getName());
@ -1360,7 +1362,11 @@ public class NPCCommands {
if (args.argsLength() == 2)
throw new CommandException(Messages.HOLOGRAM_TEXT_MISSING);
trait.addLine(args.getJoinedStrings(2));
if (duration != null) {
trait.addTemporaryLine(args.getJoinedStrings(2), Util.toTicks(duration));
} else {
trait.addLine(args.getJoinedStrings(2));
}
Messaging.sendTr(sender, Messages.HOLOGRAM_LINE_ADD, args.getJoinedStrings(2));
} else if (action.equalsIgnoreCase("insert")) {
if (args.argsLength() == 2)
@ -1475,12 +1481,12 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "horse|donkey|mule (--color color) (--type type) (--style style) (-cb)",
usage = "horse|donkey|mule (--color color) (--type type) (--style style) (-cbt)",
desc = "",
modifiers = { "horse", "donkey", "mule" },
min = 1,
max = 1,
flags = "cb",
flags = "cbt",
permission = "citizens.npc.horse")
@Requirements(selected = true, ownership = true)
public void horse(CommandContext args, CommandSender sender, NPC npc,
@ -1498,6 +1504,11 @@ public class NPCCommands {
horse.setCarryingChest(false);
output += Messaging.tr(Messages.HORSE_CHEST_UNSET) + " ";
}
if (args.hasFlag('t')) {
horse.setTamed(!horse.isTamed());
output += Messaging.tr(horse.isTamed() ? Messages.HORSE_TAMED_SET : Messages.HORSE_TAMED_UNSET,
npc.getName()) + " ";
}
if (type == EntityType.HORSE && (args.hasValueFlag("color") || args.hasValueFlag("colour"))) {
if (color == null) {
String valid = Util.listValuesPretty(Horse.Color.values());
@ -1570,6 +1581,16 @@ public class NPCCommands {
npc.getOrAddTrait(Inventory.class).openInventory((Player) sender);
}
private boolean isInDirectory(File file, File directory) {
try {
Path filePath = Paths.get(file.toURI()).toRealPath().normalize();
Path directoryPath = Paths.get(directory.toURI()).toRealPath().normalize();
return filePath.startsWith(directoryPath);
} catch (IOException e) {
return false;
}
}
@Command(
aliases = { "npc" },
usage = "item (item) (metadata) (-h(and))",
@ -3013,16 +3034,6 @@ public class NPCCommands {
Messaging.sendTr(sender, Messages.SITTING_SET, npc.getName(), Util.prettyPrintLocation(at));
}
private boolean isInDirectory(File file, File directory) {
try {
Path filePath = Paths.get(file.toURI()).toRealPath().normalize();
Path directoryPath = Paths.get(directory.toURI()).toRealPath().normalize();
return filePath.startsWith(directoryPath);
} catch (IOException e) {
return false;
}
}
@Command(
aliases = { "npc" },
usage = "skin (-e(xport) -c(lear) -l(atest) -s(kull) -b(edrock)) [name] (or --url [url] --file [file] (-s(lim)) or -t [uuid/name] [data] [signature])",
@ -3052,8 +3063,6 @@ public class NPCCommands {
if (!isInDirectory(skin, skinsFolder) || !skin.getName().endsWith(".png"))
throw new CommandException(Messages.INVALID_SKIN_FILE, file);
skin.getParentFile().mkdirs();
try {
JSONObject data = (JSONObject) new JSONParser()
.parse(new String(BaseEncoding.base64().decode(trait.getTexture())));
@ -3081,8 +3090,7 @@ public class NPCCommands {
if (file != null) {
File skinsFolder = new File(CitizensAPI.getDataFolder(), "skins");
File skin = new File(skinsFolder, Placeholders.replace(file, sender, npc));
if (!skin.exists() || !skin.isFile() || skin.isHidden()
|| !isInDirectory(skin, skinsFolder)) {
if (!skin.exists() || !skin.isFile() || skin.isHidden() || !isInDirectory(skin, skinsFolder)) {
Bukkit.getScheduler().runTask(CitizensAPI.getPlugin(),
() -> Messaging.sendErrorTr(sender, Messages.INVALID_SKIN_FILE, file));
return;

View File

@ -341,15 +341,18 @@ public class CitizensNavigator implements Navigator, Runnable {
stopNavigating(CancelReason.REPLACE);
}
localParams = defaultParams.clone();
int fallDistance = localParams.fallDistance();
if (fallDistance != -1) {
localParams.examiner(new FallingExaminer(fallDistance));
}
if (npc.data().get(NPC.Metadata.PATHFINDER_OPEN_DOORS, Setting.NEW_PATHFINDER_OPENS_DOORS.asBoolean())) {
localParams.examiner(new DoorExaminer());
}
if (Setting.NEW_PATHFINDER_CHECK_BOUNDING_BOXES.asBoolean()) {
localParams.examiner(new BoundingBoxExaminer(npc.getEntity()));
if (localParams.useNewPathfinder()) {
int fallDistance = localParams.fallDistance();
if (fallDistance != -1) {
localParams.examiner(new FallingExaminer(fallDistance));
}
if (npc.data().get(NPC.Metadata.PATHFINDER_OPEN_DOORS, Setting.NEW_PATHFINDER_OPENS_DOORS.asBoolean())) {
localParams.examiner(new DoorExaminer());
}
if (Setting.NEW_PATHFINDER_CHECK_BOUNDING_BOXES.asBoolean()) {
localParams.examiner(new BoundingBoxExaminer(npc.getEntity()));
}
}
updatePathfindingRange();
executing = strategy.apply(localParams);

View File

@ -28,6 +28,8 @@ public class HorseModifiers extends Trait {
private ItemStack saddle = null;
@Persist("style")
private Style style = Style.NONE;
@Persist("tamed")
private boolean tamed;
public HorseModifiers() {
super("horsemodifiers");
@ -55,6 +57,10 @@ public class HorseModifiers extends Trait {
return style;
}
public boolean isTamed() {
return tamed;
}
@Override
public void onSpawn() {
updateModifiers();
@ -101,6 +107,11 @@ public class HorseModifiers extends Trait {
updateModifiers();
}
public void setTamed(boolean tamed) {
this.tamed = tamed;
updateModifiers();
}
private void updateModifiers() {
if (npc.getEntity() instanceof Horse) {
Horse horse = (Horse) npc.getEntity();
@ -115,7 +126,6 @@ public class HorseModifiers extends Trait {
}
private static boolean SUPPORTS_CARRYING_CHEST;
static {
try {
if (NMS.getMethodHandle(Class.forName("org.bukkit.entity.ChestedHorse"), "setCarryingChest", false,

View File

@ -194,6 +194,8 @@ public class Messages {
public static final String HORSE_COLOR_SET = "citizens.commands.npc.horse.color-set";
public static final String HORSE_DESCRIBE = "citizens.commands.npc.horse.describe";
public static final String HORSE_STYLE_SET = "citizens.commands.npc.horse.style-set";
public static final String HORSE_TAMED_SET = "citizens.commands.npc.horse.tamed-set";
public static final String HORSE_TAMED_UNSET = "citizens.commands.npc.horse.tamed-unset";
public static final String INVALID_AGE = "citizens.commands.npc.age.invalid-age";
public static final String INVALID_ANCHOR_NAME = "citizens.commands.npc.anchor.invalid-name";
public static final String INVALID_ANIMATION = "citizens.editors.waypoints.triggers.animation.invalid-animation";

View File

@ -487,9 +487,7 @@ public class Util {
} finally {
if (op) {
if (!wasOp) {
// Disk I/O operation caused by Player#setOp(boolean)
// is not necessary here because changes on permission
// are not actually saved
// Avoid a disk I/O operation in Player#setOp(boolean)
NMS.setOpWithoutSaving(clicker, false);
}
}

View File

@ -27,6 +27,8 @@
"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.horse.tamed-set" : "[{{0}] is now tamed.",
"citizens.commands.npc.horse.tamed-unset" : "[{{0}] is no longer tamed.",
"citizens.commands.npc.bat.awake-set" : "[[{0}]] is now awake.",
"citizens.commands.npc.bat.awake-unset" : "[[{0}]] is no longer awake.",
"citizens.commands.npc.bat.description" : "Set bat modifiers",