Fix to hologram, add /npc itemframe

This commit is contained in:
fullwall 2024-04-19 15:48:33 +08:00
parent 1b32596c37
commit 6368cb379e
9 changed files with 155 additions and 23 deletions

View File

@ -459,7 +459,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
getServer().getPluginManager().callEvent(new CitizensPreReloadEvent()); getServer().getPluginManager().callEvent(new CitizensPreReloadEvent());
templateRegistry = new TemplateRegistry(new File(this.getDataFolder(), "templates").toPath()); templateRegistry = new TemplateRegistry(new File(this.getDataFolder(), "templates").toPath());
saves.reloadFromSource(); saves.reloadFromSource();
saves.loadInto(npcRegistry); saves.loadInto(npcRegistry);

View File

@ -24,6 +24,7 @@ import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Rotation;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -128,6 +129,7 @@ import net.citizensnpcs.trait.Gravity;
import net.citizensnpcs.trait.HologramTrait; import net.citizensnpcs.trait.HologramTrait;
import net.citizensnpcs.trait.HomeTrait; import net.citizensnpcs.trait.HomeTrait;
import net.citizensnpcs.trait.HorseModifiers; import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.ItemFrameTrait;
import net.citizensnpcs.trait.LookClose; import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.MirrorTrait; import net.citizensnpcs.trait.MirrorTrait;
import net.citizensnpcs.trait.MountTrait; import net.citizensnpcs.trait.MountTrait;
@ -959,7 +961,7 @@ public class NPCCommands {
flags = "b", flags = "b",
permission = "citizens.npc.endercrystal") permission = "citizens.npc.endercrystal")
@Requirements(ownership = true, selected = true, types = EntityType.ENDER_CRYSTAL) @Requirements(ownership = true, selected = true, types = EntityType.ENDER_CRYSTAL)
public void endercrystal(CommandContext args, Player sender, NPC npc) throws CommandException { public void endercrystal(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
if (args.hasFlag('b')) { if (args.hasFlag('b')) {
EnderCrystalTrait trait = npc.getOrAddTrait(EnderCrystalTrait.class); EnderCrystalTrait trait = npc.getOrAddTrait(EnderCrystalTrait.class);
boolean showing = !trait.isShowBase(); boolean showing = !trait.isShowBase();
@ -972,6 +974,42 @@ public class NPCCommands {
throw new CommandException(); throw new CommandException();
} }
@Command(
aliases = { "npc" },
usage = "itemframe --visible [true|false] --fixed [true|false] --rotation [rotation] --item [item]",
desc = "",
modifiers = { "itemframe" },
min = 1,
max = 1,
flags = "",
permission = "citizens.npc.itemframe")
@Requirements(ownership = true, selected = true, types = EntityType.ITEM_FRAME)
public void endercrystal(CommandContext args, CommandSender sender, NPC npc, @Flag("visible") Boolean visible,
@Flag("fixed") Boolean fixed, @Flag("rotation") Rotation rotation, @Flag("item") ItemStack item)
throws CommandException {
ItemFrameTrait ift = npc.getOrAddTrait(ItemFrameTrait.class);
String msg = "";
if (visible != null) {
ift.setVisible(visible);
msg += " " + Messaging.tr(Messages.ITEMFRAME_VISIBLE_SET, visible);
}
if (fixed != null) {
ift.setFixed(fixed);
msg += " " + Messaging.tr(Messages.ITEMFRAME_FIXED_SET, fixed);
}
if (item != null) {
ift.setItem(item);
msg += " " + Messaging.tr(Messages.ITEMFRAME_ITEM_SET, item);
}
if (rotation != null) {
ift.setRotation(rotation);
msg += " " + Messaging.tr(Messages.ITEMFRAME_ROTATION_SET, rotation);
}
if (msg.isEmpty())
throw new CommandUsageException();
Messaging.send(sender, msg.trim());
}
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "enderman -a(ngry)", usage = "enderman -a(ngry)",
@ -981,7 +1019,7 @@ public class NPCCommands {
min = 1, min = 1,
max = 2, max = 2,
permission = "citizens.npc.enderman") permission = "citizens.npc.enderman")
public void enderman(CommandContext args, Player sender, NPC npc) throws CommandException { public void enderman(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
if (args.hasFlag('a')) { if (args.hasFlag('a')) {
boolean angry = npc.getOrAddTrait(EndermanTrait.class).toggleAngry(); boolean angry = npc.getOrAddTrait(EndermanTrait.class).toggleAngry();
Messaging.sendTr(sender, angry ? Messages.ENDERMAN_ANGRY_SET : Messages.ENDERMAN_ANGRY_UNSET, Messaging.sendTr(sender, angry ? Messages.ENDERMAN_ANGRY_SET : Messages.ENDERMAN_ANGRY_UNSET,
@ -3149,17 +3187,20 @@ public class NPCCommands {
min = 1, min = 1,
max = 2, max = 2,
permission = "citizens.npc.target") permission = "citizens.npc.target")
public void target(CommandContext args, Player sender, NPC npc) { public void target(CommandContext args, CommandSender sender, NPC npc) throws CommandUsageException {
if (args.hasFlag('c')) { if (args.hasFlag('c')) {
npc.getNavigator().cancelNavigation(); npc.getNavigator().cancelNavigation();
return; return;
} }
Entity toTarget = args.argsLength() < 2 ? sender : Bukkit.getPlayer(args.getString(1)); Entity toTarget = args.argsLength() < 2 && sender instanceof Player ? (Player) sender
if (toTarget == null) { : Bukkit.getPlayer(args.getString(1));
if (toTarget == null && args.argsLength() == 2) {
toTarget = Bukkit.getEntity(UUID.fromString(args.getString(1))); toTarget = Bukkit.getEntity(UUID.fromString(args.getString(1)));
} }
if (toTarget != null) { if (toTarget != null) {
npc.getNavigator().setTarget(toTarget, args.hasFlag('a')); npc.getNavigator().setTarget(toTarget, args.hasFlag('a'));
} else {
throw new CommandUsageException();
} }
} }

View File

@ -36,6 +36,7 @@ import net.citizensnpcs.trait.Gravity;
import net.citizensnpcs.trait.HologramTrait; import net.citizensnpcs.trait.HologramTrait;
import net.citizensnpcs.trait.HomeTrait; import net.citizensnpcs.trait.HomeTrait;
import net.citizensnpcs.trait.HorseModifiers; import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.trait.ItemFrameTrait;
import net.citizensnpcs.trait.LookClose; import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.MirrorTrait; import net.citizensnpcs.trait.MirrorTrait;
import net.citizensnpcs.trait.MountTrait; import net.citizensnpcs.trait.MountTrait;
@ -89,6 +90,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(HorseModifiers.class)); registerTrait(TraitInfo.create(HorseModifiers.class));
registerTrait(TraitInfo.create(HologramTrait.class)); registerTrait(TraitInfo.create(HologramTrait.class));
registerTrait(TraitInfo.create(Inventory.class)); registerTrait(TraitInfo.create(Inventory.class));
registerTrait(TraitInfo.create(ItemFrameTrait.class));
registerTrait(TraitInfo.create(LookClose.class)); registerTrait(TraitInfo.create(LookClose.class));
registerTrait(TraitInfo.create(PaintingTrait.class)); registerTrait(TraitInfo.create(PaintingTrait.class));
registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats()); registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats());

View File

@ -395,7 +395,7 @@ public class HologramTrait extends Trait {
@Override @Override
public void render0(NPC base, Vector3d offset) { public void render0(NPC base, Vector3d offset) {
if (hologram.getEntity().getVehicle() == null) { if (hologram.getEntity().getVehicle() == null) {
base.getEntity().addPassenger(hologram.getEntity()); NMS.mount(base.getEntity(), hologram.getEntity());
} }
} }
} }
@ -482,7 +482,7 @@ public class HologramTrait extends Trait {
public void render0(NPC npc, Vector3d offset) { public void render0(NPC npc, Vector3d offset) {
lastOffset = new Vector3d(offset); lastOffset = new Vector3d(offset);
if (hologram.getEntity().getVehicle() == null) { if (hologram.getEntity().getVehicle() == null) {
npc.getEntity().addPassenger(hologram.getEntity()); NMS.mount(npc.getEntity(), hologram.getEntity());
} }
} }
} }
@ -516,7 +516,7 @@ public class HologramTrait extends Trait {
tf.getTranslation().y = (float) offset.y + 0.1f; tf.getTranslation().y = (float) offset.y + 0.1f;
disp.setTransformation(tf); disp.setTransformation(tf);
if (hologram.getEntity().getVehicle() == null) { if (hologram.getEntity().getVehicle() == null) {
base.getEntity().addPassenger(hologram.getEntity()); NMS.mount(base.getEntity(), hologram.getEntity());
} }
} }
@ -658,15 +658,17 @@ public class HologramTrait extends Trait {
@Override @Override
protected NPC createNPC(Entity base, String name, Vector3d offset) { protected NPC createNPC(Entity base, String name, Vector3d offset) {
NPC npc = registry.createNPC(EntityType.TEXT_DISPLAY, ""); NPC hologram = registry.createNPC(EntityType.TEXT_DISPLAY, "");
npc.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, false); hologram.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, false);
npc.data().set(NPC.Metadata.TEXT_DISPLAY_COMPONENT, Messaging.minecraftComponentFromRawMessage(name)); hologram.data().set(NPC.Metadata.TEXT_DISPLAY_COMPONENT, Messaging.minecraftComponentFromRawMessage(name));
return npc; return hologram;
} }
@Override @Override
public void render0(NPC base, Vector3d offset) { public void render0(NPC base, Vector3d offset) {
TextDisplay disp = (TextDisplay) hologram.getEntity(); TextDisplay disp = (TextDisplay) hologram.getEntity();
disp.setInterpolationDelay(0);
disp.setInterpolationDuration(0);
disp.setBillboard(Billboard.CENTER); disp.setBillboard(Billboard.CENTER);
Transformation tf = disp.getTransformation(); Transformation tf = disp.getTransformation();
tf.getTranslation().y = (float) offset.y + 0.2f; tf.getTranslation().y = (float) offset.y + 0.2f;
@ -675,7 +677,7 @@ public class HologramTrait extends Trait {
disp.setBackgroundColor(color); disp.setBackgroundColor(color);
} }
if (hologram.getEntity().getVehicle() == null) { if (hologram.getEntity().getVehicle() == null) {
base.getEntity().addPassenger(hologram.getEntity()); NMS.mount(base.getEntity(), hologram.getEntity());
} }
} }
@ -688,7 +690,7 @@ public class HologramTrait extends Trait {
this.text = Placeholders.replace(raw, null, npc); this.text = Placeholders.replace(raw, null, npc);
if (hologram == null) if (hologram == null)
return; return;
npc.data().set(NPC.Metadata.TEXT_DISPLAY_COMPONENT, Messaging.minecraftComponentFromRawMessage(text)); hologram.data().set(NPC.Metadata.TEXT_DISPLAY_COMPONENT, Messaging.minecraftComponentFromRawMessage(text));
} }
} }

View File

@ -0,0 +1,83 @@
package net.citizensnpcs.trait;
import org.bukkit.Rotation;
import org.bukkit.entity.ItemFrame;
import org.bukkit.inventory.ItemStack;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
/**
* Persists {@link ItemFrame} metadata.
*/
@TraitName("itemframe")
public class ItemFrameTrait extends Trait {
@Persist
private Boolean fixed;
@Persist
private ItemStack item;
@Persist
private Rotation rotation = Rotation.NONE;
@Persist
private boolean visible = true;
public ItemFrameTrait() {
super("itemframe");
}
public Boolean getFixed() {
return fixed;
}
public ItemStack getItem() {
return item;
}
public Rotation getRotation() {
return rotation;
}
public boolean isVisible() {
return visible;
}
@Override
public void onSpawn() {
if (npc.getEntity() instanceof ItemFrame) {
ItemFrame frame = (ItemFrame) npc.getEntity();
if (rotation != null) {
frame.setRotation(rotation);
}
if (item != null) {
frame.setItem(item);
}
if (fixed != null) {
frame.setFixed(fixed);
} else {
frame.setFixed(npc.isProtected());
}
frame.setVisible(visible);
}
}
public void setFixed(boolean fixed) {
this.fixed = fixed;
onSpawn();
}
public void setItem(ItemStack item) {
this.item = item;
onSpawn();
}
public void setRotation(Rotation rot) {
rotation = rot;
onSpawn();
}
public void setVisible(boolean visible) {
this.visible = visible;
onSpawn();
}
}

View File

@ -204,6 +204,10 @@ public class Messages {
public static final String INVALID_TROPICALFISH_PATTERN = "citizens.commands.npc.tropicalfish.invalid-pattern"; public static final String INVALID_TROPICALFISH_PATTERN = "citizens.commands.npc.tropicalfish.invalid-pattern";
public static final String INVALID_VILLAGER_TYPE = "citizens.commands.npc.villager.invalid-type"; public static final String INVALID_VILLAGER_TYPE = "citizens.commands.npc.villager.invalid-type";
public static final String ITEM_SET = "citizens.commands.npc.item.item-set"; public static final String ITEM_SET = "citizens.commands.npc.item.item-set";
public static final String ITEMFRAME_FIXED_SET = "citizens.commands.npc.itemframe.fixed-set";
public static final String ITEMFRAME_ITEM_SET = "citizens.commands.npc.itemframe.item-set";
public static final String ITEMFRAME_ROTATION_SET = "citizens.commands.npc.itemframe.rotation-set";
public static final String ITEMFRAME_VISIBLE_SET = "citizens.commands.npc.itemframe.visible-set";
public static final String KNOCKBACK_SET = "citizens.commands.npc.knockback.set"; public static final String KNOCKBACK_SET = "citizens.commands.npc.knockback.set";
public static final String KNOCKBACK_UNSET = "citizens.commands.npc.knockback.unset"; public static final String KNOCKBACK_UNSET = "citizens.commands.npc.knockback.unset";
public static final String LEASHABLE_SET = "citizens.commands.npc.leashable.set"; public static final String LEASHABLE_SET = "citizens.commands.npc.leashable.set";

View File

@ -83,6 +83,11 @@
"citizens.commands.npc.chunkload.unset" : "[[{0}]] will no longer force chunks to be loaded.", "citizens.commands.npc.chunkload.unset" : "[[{0}]] will no longer force chunks to be loaded.",
"citizens.commands.npc.collidable.description" : "Toggles an NPC''s collidability", "citizens.commands.npc.collidable.description" : "Toggles an NPC''s collidability",
"citizens.commands.npc.collidable.help" : "", "citizens.commands.npc.collidable.help" : "",
"citizens.commands.npc.itemframe.description" : "Sets itemframe modifiers",
"citizens.commands.npc.itemframe.rotation-set" : "Rotation set to [[{0}]]",
"citizens.commands.npc.itemframe.item-set" : "Item set to [[{0}]]",
"citizens.commands.npc.itemframe.fixed-set" : "Fixed (whether the item can be rotated) set to [[{0}]]",
"citizens.commands.npc.itemframe.visible-set" : "Visible set to [[{0}]]",
"citizens.commands.npc.collidable.set" : "[[{0}]] will now collide with entities.", "citizens.commands.npc.collidable.set" : "[[{0}]] will now collide with entities.",
"citizens.commands.npc.collidable.unset" : "[[{0}]] will no longer collide with entities.", "citizens.commands.npc.collidable.unset" : "[[{0}]] will no longer collide with entities.",
"citizens.commands.npc.command.all-players-forgotten" : "[[{0}]] forgot all player command history.", "citizens.commands.npc.command.all-players-forgotten" : "[[{0}]] forgot all player command history.",

View File

@ -16,7 +16,6 @@ import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl; import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Display.TextDisplay; import net.minecraft.world.entity.Display.TextDisplay;
@ -114,9 +113,8 @@ public class TextDisplayController extends MobEntityController {
super.tick(); super.tick();
if (npc != null) { if (npc != null) {
npc.update(); npc.update();
Component component = npc.data().get(NPC.Metadata.TEXT_DISPLAY_COMPONENT); if (npc.data().has(NPC.Metadata.TEXT_DISPLAY_COMPONENT)) {
if (component != null) { setText(npc.data().get(NPC.Metadata.TEXT_DISPLAY_COMPONENT));
setText(component);
npc.data().remove(NPC.Metadata.TEXT_DISPLAY_COMPONENT); npc.data().remove(NPC.Metadata.TEXT_DISPLAY_COMPONENT);
} }
} }

View File

@ -14,7 +14,6 @@ import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Display.TextDisplay; import net.minecraft.world.entity.Display.TextDisplay;
@ -104,9 +103,8 @@ public class TextDisplayController extends MobEntityController {
super.tick(); super.tick();
if (npc != null) { if (npc != null) {
npc.update(); npc.update();
Component component = npc.data().get(NPC.Metadata.TEXT_DISPLAY_COMPONENT); if (npc.data().has(NPC.Metadata.TEXT_DISPLAY_COMPONENT)) {
if (component != null) { setText(npc.data().get(NPC.Metadata.TEXT_DISPLAY_COMPONENT));
setText(component);
npc.data().remove(NPC.Metadata.TEXT_DISPLAY_COMPONENT); npc.data().remove(NPC.Metadata.TEXT_DISPLAY_COMPONENT);
} }
} }