mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-12-23 01:27:33 +01:00
Misc small changes
This commit is contained in:
parent
dd247a9ee0
commit
751e2a28ac
@ -28,7 +28,6 @@ import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Files;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import ch.ethz.globis.phtree.PhTreeHelper;
|
||||
@ -82,8 +81,6 @@ import net.citizensnpcs.npc.profile.ProfileFetcher;
|
||||
import net.citizensnpcs.npc.skin.Skin;
|
||||
import net.citizensnpcs.trait.ClickRedirectTrait;
|
||||
import net.citizensnpcs.trait.CommandTrait;
|
||||
import net.citizensnpcs.trait.HologramTrait;
|
||||
import net.citizensnpcs.trait.ScriptTrait;
|
||||
import net.citizensnpcs.trait.ShopTrait;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -98,6 +95,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
private final CommandManager commands = new CommandManager();
|
||||
private Settings config;
|
||||
private boolean enabled;
|
||||
private Locale locale;
|
||||
private LocationLookup locationLookup;
|
||||
private final NMSHelper nmsHelper = new NMSHelper() {
|
||||
private boolean SUPPORT_OWNER_PROFILE = true;
|
||||
@ -185,11 +183,14 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
if (type.equalsIgnoreCase("nbt")) {
|
||||
saves = new NBTStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");
|
||||
}
|
||||
|
||||
if (saves == null) {
|
||||
saves = new YamlStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");
|
||||
}
|
||||
|
||||
if (!saves.load())
|
||||
return null;
|
||||
|
||||
return SimpleNPCDataStore.create(saves);
|
||||
}
|
||||
|
||||
@ -282,11 +283,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
return getClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getScriptFolder() {
|
||||
return new File(getDataFolder(), "scripts");
|
||||
}
|
||||
|
||||
public StoredShops getShops() {
|
||||
return shops;
|
||||
}
|
||||
@ -552,6 +548,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
}
|
||||
}
|
||||
Translator.setInstance(new File(getDataFolder(), "lang"), locale);
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
private void startMetrics() {
|
||||
@ -562,16 +559,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
return 0;
|
||||
return Iterables.size(npcRegistry);
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.AdvancedPie("hologram_direction", () -> {
|
||||
Map<String, Integer> res = Maps.newHashMap();
|
||||
for (NPC npc : npcRegistry) {
|
||||
HologramTrait hg = npc.getTraitNullable(HologramTrait.class);
|
||||
if (hg != null) {
|
||||
res.put(hg.getDirection().name(), res.getOrDefault(hg.getDirection().name(), 0) + 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("locale", () -> locale.toString()));
|
||||
metrics.addCustomChart(new Metrics.AdvancedPie("traits", () -> {
|
||||
Map<String, Integer> res = Maps.newHashMap();
|
||||
for (NPC npc : npcRegistry) {
|
||||
@ -583,19 +571,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
}
|
||||
return res;
|
||||
}));
|
||||
metrics.addCustomChart(new Metrics.AdvancedPie("script_extensions", () -> {
|
||||
Map<String, Integer> res = Maps.newHashMap();
|
||||
for (NPC npc : npcRegistry) {
|
||||
ScriptTrait trait = npc.getTraitNullable(ScriptTrait.class);
|
||||
if (trait != null) {
|
||||
for (String file : trait.getScripts()) {
|
||||
String ext = Files.getFileExtension(file);
|
||||
res.put(ext, res.getOrDefault(ext, 0) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}));
|
||||
} catch (Exception e) {
|
||||
Messaging.logTr(Messages.METRICS_ERROR_NOTIFICATION, e.getMessage());
|
||||
}
|
||||
@ -630,7 +605,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
@Override
|
||||
public void run() {
|
||||
Plugin plib = Bukkit.getPluginManager().getPlugin("ProtocolLib");
|
||||
if (plib != null && plib.isEnabled() && ProtocolLibrary.getProtocolManager() != null) {
|
||||
if (Setting.HOOK_PROTOCOLLIB.asBoolean() && plib != null && plib.isEnabled()
|
||||
&& ProtocolLibrary.getProtocolManager() != null) {
|
||||
try {
|
||||
protocolListener = new ProtocolLibListener(Citizens.this);
|
||||
} catch (Throwable t) {
|
||||
|
@ -232,6 +232,7 @@ public class EventListen implements Listener {
|
||||
public void onChunkUnload(final ChunkUnloadEvent event) {
|
||||
if (chunkEventListener != null)
|
||||
return;
|
||||
|
||||
unloadNPCs(event, Arrays.asList(event.getChunk().getEntities()));
|
||||
}
|
||||
|
||||
@ -401,6 +402,7 @@ public class EventListen implements Listener {
|
||||
ChunkCoord coord = new ChunkCoord(event.getSpawnLocation());
|
||||
if (toRespawn.containsEntry(coord, event.getNPC()))
|
||||
return;
|
||||
|
||||
Messaging.debug("Stored", event.getNPC(), "for respawn from NPCNeedsRespawnEvent");
|
||||
toRespawn.put(coord, event.getNPC());
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public class ProtocolLibListener implements Listener {
|
||||
NPC npc = getNPCFromPacket(event);
|
||||
if (npc == null || !npc.data().has(NPC.Metadata.HOLOGRAM_LINE_SUPPLIER))
|
||||
return;
|
||||
|
||||
Function<Player, String> hvs = npc.data().get(NPC.Metadata.HOLOGRAM_LINE_SUPPLIER);
|
||||
int version = manager.getProtocolVersion(event.getPlayer());
|
||||
PacketContainer packet = event.getPacket();
|
||||
@ -81,6 +82,7 @@ public class ProtocolLibListener implements Listener {
|
||||
List<WrappedWatchableObject> wwo = packet.getWatchableCollectionModifier().readSafely(0);
|
||||
if (wwo == null)
|
||||
return;
|
||||
|
||||
boolean delta = false;
|
||||
String text = hvs.apply(event.getPlayer());
|
||||
for (WrappedWatchableObject wo : wwo) {
|
||||
@ -94,6 +96,7 @@ public class ProtocolLibListener implements Listener {
|
||||
delta = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (delta) {
|
||||
packet.getWatchableCollectionModifier().write(0, wwo);
|
||||
}
|
||||
@ -101,6 +104,7 @@ public class ProtocolLibListener implements Listener {
|
||||
List<WrappedDataValue> wdvs = packet.getDataValueCollectionModifier().readSafely(0);
|
||||
if (wdvs == null)
|
||||
return;
|
||||
|
||||
boolean delta = false;
|
||||
String text = hvs.apply(event.getPlayer());
|
||||
for (WrappedDataValue wdv : wdvs) {
|
||||
@ -109,6 +113,7 @@ public class ProtocolLibListener implements Listener {
|
||||
wdv.setValue(Optional.of(Messaging.minecraftComponentFromRawMessage(text)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (delta) {
|
||||
packet.getDataValueCollectionModifier().write(0, wdvs);
|
||||
}
|
||||
@ -138,6 +143,7 @@ public class ProtocolLibListener implements Listener {
|
||||
PlayerInfoData npcInfo = list.get(i);
|
||||
if (npcInfo == null)
|
||||
continue;
|
||||
|
||||
MirrorTrait trait = mirrorTraits.get(npcInfo.getProfile().getUUID());
|
||||
if (trait == null || !trait.isMirroring(event.getPlayer()))
|
||||
continue;
|
||||
@ -239,6 +245,7 @@ public class ProtocolLibListener implements Listener {
|
||||
Integer id = packet.getIntegers().readSafely(0);
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
entity = manager.getEntityFromID(event.getPlayer().getWorld(), id);
|
||||
} catch (FieldAccessException | IllegalArgumentException ex) {
|
||||
if (!LOGGED_ERROR) {
|
||||
@ -271,6 +278,7 @@ public class ProtocolLibListener implements Listener {
|
||||
rotationTraits.put(event.getNPC().getEntity().getEntityId(),
|
||||
event.getNPC().getTraitNullable(RotationTrait.class));
|
||||
}
|
||||
|
||||
if (event.getNPC().hasTrait(MirrorTrait.class)
|
||||
&& event.getNPC().getOrAddTrait(MobType.class).getType() == EntityType.PLAYER) {
|
||||
mirrorTraits.put(event.getNPC().getEntity().getUniqueId(),
|
||||
|
@ -180,6 +180,7 @@ public class Settings {
|
||||
"npc.hologram.always-update-position", false),
|
||||
HOLOGRAM_UPDATE_RATE("How often to update hologram names (including placeholders)",
|
||||
"npc.hologram.update-rate-ticks", "npc.hologram.update-rate", "1s"),
|
||||
HOOK_PROTOCOLLIB("Whether to hook into ProtocolLib", "general.interop.protocollib", true),
|
||||
INITIAL_PLAYER_JOIN_SKIN_PACKET_DELAY("How long to wait before sending skins to joined players",
|
||||
"npc.skins.player-join-update-delay-ticks", "npc.skins.player-join-update-delay", "1s"),
|
||||
KEEP_CHUNKS_LOADED("Whether to keep NPC chunks loaded", "npc.chunks.always-keep-loaded", false),
|
||||
|
@ -123,7 +123,6 @@ import net.citizensnpcs.trait.FollowTrait;
|
||||
import net.citizensnpcs.trait.GameModeTrait;
|
||||
import net.citizensnpcs.trait.Gravity;
|
||||
import net.citizensnpcs.trait.HologramTrait;
|
||||
import net.citizensnpcs.trait.HologramTrait.HologramDirection;
|
||||
import net.citizensnpcs.trait.HomeTrait;
|
||||
import net.citizensnpcs.trait.HorseModifiers;
|
||||
import net.citizensnpcs.trait.LookClose;
|
||||
@ -138,7 +137,6 @@ import net.citizensnpcs.trait.Powered;
|
||||
import net.citizensnpcs.trait.RabbitType;
|
||||
import net.citizensnpcs.trait.RotationTrait;
|
||||
import net.citizensnpcs.trait.ScoreboardTrait;
|
||||
import net.citizensnpcs.trait.ScriptTrait;
|
||||
import net.citizensnpcs.trait.SheepTrait;
|
||||
import net.citizensnpcs.trait.ShopTrait;
|
||||
import net.citizensnpcs.trait.ShopTrait.NPCShop;
|
||||
@ -995,15 +993,15 @@ public class NPCCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "follow (player name|NPC id) (-p[rotect]) (--margin [margin])",
|
||||
usage = "follow (player name|NPC id) (-p[rotect]) (--margin [margin]) (--enable [boolean])",
|
||||
desc = "Toggles NPC following you",
|
||||
flags = "p",
|
||||
modifiers = { "follow" },
|
||||
min = 1,
|
||||
max = 2,
|
||||
permission = "citizens.npc.follow")
|
||||
public void follow(CommandContext args, CommandSender sender, NPC npc, @Flag("margin") Double margin)
|
||||
throws CommandException {
|
||||
public void follow(CommandContext args, CommandSender sender, NPC npc, @Flag("margin") Double margin,
|
||||
@Flag("enable") Boolean explicit) throws CommandException {
|
||||
boolean protect = args.hasFlag('p');
|
||||
FollowTrait trait = npc.getOrAddTrait(FollowTrait.class);
|
||||
if (margin != null) {
|
||||
@ -1035,7 +1033,8 @@ public class NPCCommands {
|
||||
args.getString(1));
|
||||
return;
|
||||
}
|
||||
boolean following = !trait.isEnabled();
|
||||
|
||||
boolean following = explicit == null ? !trait.isEnabled() : explicit;
|
||||
trait.follow(following ? player.getPlayer() : null);
|
||||
Messaging.sendTr(sender, following ? Messages.FOLLOW_SET : Messages.FOLLOW_UNSET, npc.getName(),
|
||||
player.getName());
|
||||
@ -1129,17 +1128,15 @@ public class NPCCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "hologram add [text] | set [line #] [text] | remove [line #] | clear | lineheight [height] | direction [up|down] | margintop [line #] [margin] | marginbottom [line #] [margin]",
|
||||
usage = "hologram add [text] | set [line #] [text] | remove [line #] | clear | lineheight [height] | margintop [line #] [margin] | marginbottom [line #] [margin]",
|
||||
desc = "Controls NPC hologram text",
|
||||
modifiers = { "hologram" },
|
||||
min = 1,
|
||||
max = -1,
|
||||
permission = "citizens.npc.hologram")
|
||||
public void hologram(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Arg(
|
||||
value = 1,
|
||||
completions = { "add", "set", "remove", "clear", "lineheight", "direction", "margintop",
|
||||
"marginbottom" }) String action)
|
||||
public void hologram(CommandContext args, CommandSender sender, NPC npc, @Arg(
|
||||
value = 1,
|
||||
completions = { "add", "set", "remove", "clear", "lineheight", "margintop", "marginbottom" }) String action)
|
||||
throws CommandException {
|
||||
HologramTrait trait = npc.getOrAddTrait(HologramTrait.class);
|
||||
if (args.argsLength() == 1) {
|
||||
@ -1194,11 +1191,6 @@ public class NPCCommands {
|
||||
} else if (action.equalsIgnoreCase("lineheight")) {
|
||||
trait.setLineHeight(args.getDouble(2));
|
||||
Messaging.sendTr(sender, Messages.HOLOGRAM_LINE_HEIGHT_SET, args.getDouble(2));
|
||||
} else if (action.equalsIgnoreCase("direction")) {
|
||||
HologramDirection direction = args.getString(2).equalsIgnoreCase("up") ? HologramDirection.BOTTOM_UP
|
||||
: HologramDirection.TOP_DOWN;
|
||||
trait.setDirection(direction);
|
||||
Messaging.sendTr(sender, Messages.HOLOGRAM_DIRECTION_SET, Util.prettyEnum(direction));
|
||||
} else if (action.equalsIgnoreCase("margintop")) {
|
||||
if (args.argsLength() == 2) {
|
||||
throw new CommandException(Messages.HOLOGRAM_INVALID_LINE);
|
||||
@ -1385,20 +1377,24 @@ public class NPCCommands {
|
||||
throws CommandException {
|
||||
EntityType type = npc.getOrAddTrait(MobType.class).getType();
|
||||
if (!type.name().contains("ITEM_FRAME") && !type.name().contains("ITEM_DISPLAY")
|
||||
&& type != EntityType.DROPPED_ITEM && type != EntityType.FALLING_BLOCK)
|
||||
&& !type.name().contains("BLOCK_DISPLAY") && type != EntityType.DROPPED_ITEM
|
||||
&& type != EntityType.FALLING_BLOCK)
|
||||
throw new CommandException(CommandMessages.REQUIREMENTS_INVALID_MOB_TYPE, Util.prettyEnum(type));
|
||||
ItemStack stack = args.hasFlag('h') ? ((Player) sender).getItemInHand() : new ItemStack(mat, 1);
|
||||
if (modify != null) {
|
||||
stack = Util.parseItemStack(stack, modify);
|
||||
}
|
||||
|
||||
if (mat == null && !args.hasFlag('h'))
|
||||
throw new CommandException(Messages.UNKNOWN_MATERIAL);
|
||||
ItemStack fstack = stack.clone();
|
||||
npc.setItemProvider(() -> fstack);
|
||||
|
||||
if (npc.isSpawned()) {
|
||||
npc.despawn(DespawnReason.PENDING_RESPAWN);
|
||||
npc.spawn(npc.getStoredLocation(), SpawnReason.RESPAWN);
|
||||
}
|
||||
|
||||
Messaging.sendTr(sender, Messages.ITEM_SET, Util.prettyEnum(stack.getType()));
|
||||
}
|
||||
|
||||
@ -2596,34 +2592,6 @@ public class NPCCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "script --add [files] --remove [files]",
|
||||
desc = "Controls an NPC's scripts",
|
||||
modifiers = { "script" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "citizens.npc.script")
|
||||
public void script(CommandContext args, CommandSender sender, NPC npc, @Flag("add") String add,
|
||||
@Flag("remove") String remove) {
|
||||
ScriptTrait trait = npc.getOrAddTrait(ScriptTrait.class);
|
||||
if (add != null) {
|
||||
List<String> files = new ArrayList<String>();
|
||||
for (String file : add.split(",")) {
|
||||
if (!trait.validateFile(file)) {
|
||||
Messaging.sendErrorTr(sender, Messages.INVALID_SCRIPT_FILE, file);
|
||||
return;
|
||||
}
|
||||
files.add(file);
|
||||
}
|
||||
trait.addScripts(files);
|
||||
}
|
||||
if (remove != null) {
|
||||
trait.removeScripts(Arrays.asList(remove.split(",")));
|
||||
}
|
||||
Messaging.sendTr(sender, Messages.CURRENT_SCRIPTS, npc.getName(), Joiner.on("]],[[ ").join(trait.getScripts()));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "select|sel [id|name] (--range range) (--registry [name])",
|
||||
|
@ -343,6 +343,7 @@ public class CitizensNPC extends AbstractNPC {
|
||||
Messaging.debug("Retrying spawn of", this, "later, SpawnReason." + reason + ". Was loaded", loaded,
|
||||
"is loaded", Util.isLoaded(at));
|
||||
}
|
||||
|
||||
// we need to wait before trying to spawn
|
||||
entityController.remove();
|
||||
Bukkit.getPluginManager().callEvent(new NPCNeedsRespawnEvent(this, at));
|
||||
|
@ -87,7 +87,8 @@ public class CitizensNPCRegistry implements NPCRegistry {
|
||||
public NPC createNPCUsingItem(EntityType type, String name, ItemStack item) {
|
||||
NPC npc = createNPC(type, name);
|
||||
if (type == EntityType.DROPPED_ITEM || type == EntityType.FALLING_BLOCK || type == EntityType.ITEM_FRAME
|
||||
|| type.name().equals("GLOW_ITEM_FRAME") || type.name().equals("ITEM_DISPLAY")) {
|
||||
|| type.name().equals("GLOW_ITEM_FRAME") || type.name().equals("ITEM_DISPLAY")
|
||||
|| type.name().equals("BLOCK_DISPLAY")) {
|
||||
npc.data().set(NPC.Metadata.ITEM_AMOUNT, item.getAmount());
|
||||
npc.data().set(NPC.Metadata.ITEM_ID, item.getType().name());
|
||||
npc.data().set(NPC.Metadata.ITEM_DATA, item.getData().getData());
|
||||
|
@ -49,7 +49,6 @@ import net.citizensnpcs.trait.RabbitType;
|
||||
import net.citizensnpcs.trait.RotationTrait;
|
||||
import net.citizensnpcs.trait.Saddle;
|
||||
import net.citizensnpcs.trait.ScoreboardTrait;
|
||||
import net.citizensnpcs.trait.ScriptTrait;
|
||||
import net.citizensnpcs.trait.SheepTrait;
|
||||
import net.citizensnpcs.trait.SitTrait;
|
||||
import net.citizensnpcs.trait.SkinLayers;
|
||||
@ -117,7 +116,6 @@ public class CitizensTraitFactory implements TraitFactory {
|
||||
registerTrait(TraitInfo.create(RotationTrait.class));
|
||||
registerTrait(TraitInfo.create(Saddle.class));
|
||||
registerTrait(TraitInfo.create(ScoreboardTrait.class));
|
||||
registerTrait(TraitInfo.create(ScriptTrait.class).optInToStats());
|
||||
registerTrait(TraitInfo.create(SitTrait.class).optInToStats());
|
||||
registerTrait(TraitInfo.create(SleepTrait.class));
|
||||
registerTrait(TraitInfo.create(SheepTrait.class));
|
||||
|
@ -45,6 +45,7 @@ public class DropsTrait extends Trait {
|
||||
public void onNPCDeath(NPCDeathEvent event) {
|
||||
if (!event.getNPC().equals(npc))
|
||||
return;
|
||||
|
||||
Random random = Util.getFastRandom();
|
||||
for (ItemDrop drop : drops) {
|
||||
if (random.nextDouble() < drop.chance) {
|
||||
|
@ -43,8 +43,6 @@ import net.citizensnpcs.util.Util;
|
||||
public class HologramTrait extends Trait {
|
||||
private Location currentLoc;
|
||||
private BiFunction<String, Player, String> customHologramSupplier;
|
||||
@Persist
|
||||
private HologramDirection direction = HologramDirection.BOTTOM_UP;
|
||||
private double lastEntityHeight = 0;
|
||||
private boolean lastNameplateVisible;
|
||||
@Persist
|
||||
@ -110,10 +108,7 @@ public class HologramTrait extends Trait {
|
||||
hologramNPC.addTrait(PacketNPC.class);
|
||||
}
|
||||
|
||||
hologramNPC.spawn(currentLoc.clone().add(0,
|
||||
getEntityHeight()
|
||||
+ (direction == HologramDirection.BOTTOM_UP ? heightOffset : getMaxHeight() - heightOffset),
|
||||
0));
|
||||
hologramNPC.spawn(currentLoc.clone().add(0, getEntityHeight() + heightOffset, 0));
|
||||
|
||||
if (useDisplayEntities) {
|
||||
((Interaction) hologramNPC.getEntity()).setInteractionWidth(0);
|
||||
@ -150,13 +145,6 @@ public class HologramTrait extends Trait {
|
||||
return hologramNPC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The direction that hologram lines are displayed in
|
||||
*/
|
||||
public HologramDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
private double getEntityHeight() {
|
||||
return NMS.getHeight(npc.getEntity());
|
||||
}
|
||||
@ -195,10 +183,6 @@ public class HologramTrait extends Trait {
|
||||
return Lists.transform(lines, l -> l.text);
|
||||
}
|
||||
|
||||
private double getMaxHeight() {
|
||||
return (lastNameplateVisible ? getLineHeight() : 0) + getHeight(lines.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: this is implementation-specific and may be removed at a later date.
|
||||
*/
|
||||
@ -349,8 +333,7 @@ public class HologramTrait extends Trait {
|
||||
}
|
||||
|
||||
if (updatePosition && !useDisplayEntities) {
|
||||
Location tp = npcLoc.clone().add(0, lastEntityHeight
|
||||
+ (direction == HologramDirection.BOTTOM_UP ? getHeight(i) : getMaxHeight() - getHeight(i)), 0);
|
||||
Location tp = npcLoc.clone().add(0, lastEntityHeight + getHeight(i), 0);
|
||||
hologramNPC.teleport(tp, TeleportCause.PLUGIN);
|
||||
}
|
||||
|
||||
@ -385,17 +368,6 @@ public class HologramTrait extends Trait {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getDirection()
|
||||
* @param direction
|
||||
* The new direction
|
||||
*/
|
||||
public void setDirection(HologramDirection direction) {
|
||||
this.direction = direction;
|
||||
|
||||
reloadLineHolograms();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hologram line at a specific index
|
||||
*
|
||||
@ -461,11 +433,6 @@ public class HologramTrait extends Trait {
|
||||
reloadLineHolograms();
|
||||
}
|
||||
|
||||
public enum HologramDirection {
|
||||
BOTTOM_UP,
|
||||
TOP_DOWN;
|
||||
}
|
||||
|
||||
private class HologramLine implements Function<Player, String> {
|
||||
NPC hologram;
|
||||
double mb, mt;
|
||||
|
@ -109,6 +109,7 @@ public class RotationTrait extends Trait {
|
||||
PacketRotationSession session = itr.next();
|
||||
if (ran.contains(session))
|
||||
continue;
|
||||
|
||||
ran.add(session);
|
||||
session.run(npc.getEntity());
|
||||
if (!session.isActive()) {
|
||||
@ -192,6 +193,7 @@ public class RotationTrait extends Trait {
|
||||
if (triple == null) {
|
||||
triple = new PacketRotationTriple(entity);
|
||||
}
|
||||
|
||||
session.run(triple);
|
||||
if (!session.isActive()) {
|
||||
triple = null;
|
||||
|
@ -1,143 +0,0 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import net.citizensnpcs.Citizens;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.scripting.CompileCallback;
|
||||
import net.citizensnpcs.api.scripting.Script;
|
||||
import net.citizensnpcs.api.scripting.ScriptCompiler;
|
||||
import net.citizensnpcs.api.scripting.ScriptFactory;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
/**
|
||||
* Stores a list of scripts, which are pieces of arbitrary code that can be run every tick.
|
||||
*
|
||||
* @see ScriptCompiler
|
||||
*/
|
||||
@TraitName("scripttrait")
|
||||
public class ScriptTrait extends Trait {
|
||||
@Persist
|
||||
private final List<String> files = new ArrayList<String>();
|
||||
private final List<RunnableScript> runnableScripts = new ArrayList<RunnableScript>();
|
||||
|
||||
public ScriptTrait() {
|
||||
super("scripttrait");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and load all given script file names
|
||||
*
|
||||
* @see #loadScript(String)
|
||||
*/
|
||||
public void addScripts(List<String> scripts) {
|
||||
for (String f : scripts) {
|
||||
if (!files.contains(f) && validateFile(f)) {
|
||||
loadScript(f);
|
||||
files.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getScripts() {
|
||||
return files;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) {
|
||||
for (String file : files) {
|
||||
if (validateFile(file)) {
|
||||
loadScript(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile and load a script given by the file name.
|
||||
*
|
||||
* @param file
|
||||
* the script file name relative to the script folder
|
||||
* @see Citizens#getScriptFolder()
|
||||
*/
|
||||
public void loadScript(final String file) {
|
||||
File f = new File(JavaPlugin.getPlugin(Citizens.class).getScriptFolder(), file);
|
||||
CitizensAPI.getScriptCompiler().compile(f).cache(true).withCallback(new CompileCallback() {
|
||||
@Override
|
||||
public void onScriptCompiled(String sourceDescriptor, ScriptFactory compiled) {
|
||||
final Script newInstance = compiled.newInstance();
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
newInstance.invoke("onLoad", npc);
|
||||
} catch (RuntimeException e) {
|
||||
if (!(e.getCause() instanceof NoSuchMethodException)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
runnableScripts.add(new RunnableScript(newInstance, file));
|
||||
}
|
||||
});
|
||||
}
|
||||
}).beginWithFuture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given script file names.
|
||||
*/
|
||||
public void removeScripts(List<String> scripts) {
|
||||
files.removeAll(scripts);
|
||||
Iterator<RunnableScript> itr = runnableScripts.iterator();
|
||||
while (itr.hasNext()) {
|
||||
if (scripts.remove(itr.next().file)) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Iterator<RunnableScript> itr = runnableScripts.iterator();
|
||||
while (itr.hasNext()) {
|
||||
try {
|
||||
itr.next().script.invoke("run", npc);
|
||||
} catch (RuntimeException e) {
|
||||
if (e.getCause() instanceof NoSuchMethodException) {
|
||||
itr.remove();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the file exists and can be compiled by the system {@link ScriptCompiler}.
|
||||
*/
|
||||
public boolean validateFile(String file) {
|
||||
File f = new File(JavaPlugin.getPlugin(Citizens.class).getScriptFolder(), file);
|
||||
if (!f.exists() || !f.getParentFile().equals(JavaPlugin.getPlugin(Citizens.class).getScriptFolder())) {
|
||||
return false;
|
||||
}
|
||||
return CitizensAPI.getScriptCompiler().canCompile(f);
|
||||
}
|
||||
|
||||
private static class RunnableScript {
|
||||
String file;
|
||||
Script script;
|
||||
|
||||
public RunnableScript(Script script, String file) {
|
||||
this.script = script;
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Pose;
|
||||
import org.bukkit.entity.Warden;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
@ -21,6 +22,8 @@ import net.citizensnpcs.api.npc.NPC;
|
||||
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("wardentrait")
|
||||
public class WardenTrait extends Trait {
|
||||
@ -46,16 +49,16 @@ public class WardenTrait extends Trait {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "warden anger [entity uuid/player name] [anger]",
|
||||
usage = "warden dig|emerge|roar|anger [entity uuid/player name] [anger]",
|
||||
desc = "Sets warden modifiers",
|
||||
modifiers = { "warden" },
|
||||
min = 1,
|
||||
max = 4,
|
||||
permission = "citizens.npc.warden")
|
||||
@Requirements(selected = true, ownership = true, types = EntityType.WARDEN)
|
||||
public static void Warden(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Arg(value = 1, completions = { "anger" }) String command, @Arg(2) String player, @Arg(3) Integer anger)
|
||||
throws CommandException {
|
||||
public static void warden(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Arg(value = 1, completions = { "anger", "dig", "emerge", "roar" }) String command, @Arg(2) String player,
|
||||
@Arg(3) Integer anger) throws CommandException {
|
||||
WardenTrait trait = npc.getOrAddTrait(WardenTrait.class);
|
||||
String output = "";
|
||||
if (command.equalsIgnoreCase("anger")) {
|
||||
@ -68,9 +71,20 @@ public class WardenTrait extends Trait {
|
||||
} catch (IllegalArgumentException iae) {
|
||||
entity = Bukkit.getOfflinePlayer(player).getPlayer();
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
trait.addAnger(entity, anger);
|
||||
output = Messaging.tr(Messages.WARDEN_ANGER_ADDED, entity, anger);
|
||||
}
|
||||
} else if (command.equalsIgnoreCase("dig")) {
|
||||
NMS.setWardenPose(npc.getEntity(), Pose.DIGGING);
|
||||
output = Messaging.tr(Messages.WARDEN_POSE_SET, npc.getName(), "dig");
|
||||
} else if (command.equalsIgnoreCase("emerge")) {
|
||||
NMS.setWardenPose(npc.getEntity(), Pose.EMERGING);
|
||||
output = Messaging.tr(Messages.WARDEN_POSE_SET, npc.getName(), "emerge");
|
||||
} else if (command.equalsIgnoreCase("roar")) {
|
||||
NMS.setWardenPose(npc.getEntity(), Pose.ROARING);
|
||||
output = Messaging.tr(Messages.WARDEN_POSE_SET, npc.getName(), "roar");
|
||||
}
|
||||
|
||||
if (!output.isEmpty()) {
|
||||
|
@ -461,6 +461,8 @@ public class Messages {
|
||||
public static final String WANDER_WAYPOINTS_REMOVED_REGION = "citizens.editors.waypoints.wander.removed-region";
|
||||
public static final String WANDER_WAYPOINTS_WORLDGUARD_REGION_NOT_FOUND = "citizens.editors.waypoints.wander.worldguard-region-not-found";
|
||||
public static final String WANDER_WAYPOINTS_WORLDGUARD_REGION_SET = "citizens.editors.waypoints.wander.worldguard-region-set";
|
||||
public static final String WARDEN_ANGER_ADDED = "citizens.commands.npc.warden.anger-added";
|
||||
public static final String WARDEN_POSE_SET = "citizens.commands.npc.warden.pose-set";
|
||||
public static final String WAYPOINT_ADDED = "citizens.commands.waypoints.add.waypoint-added";
|
||||
public static final String WAYPOINT_PROVIDER_SET = "citizens.waypoints.set-provider";
|
||||
public static final String WAYPOINT_REMOVED = "citizens.commands.waypoints.waypoint-removed";
|
||||
|
@ -852,10 +852,14 @@ public class NMS {
|
||||
BRIDGE.setTeamNameTagVisible(team, visible);
|
||||
}
|
||||
|
||||
public static void setVerticalMovement(org.bukkit.entity.Entity bukkitEntity, double d) {
|
||||
public static void setVerticalMovement(Entity bukkitEntity, double d) {
|
||||
BRIDGE.setVerticalMovement(bukkitEntity, d);
|
||||
}
|
||||
|
||||
public static void setWardenPose(Entity entity, Object pose) {
|
||||
BRIDGE.setWardenPose(entity, pose);
|
||||
}
|
||||
|
||||
public static void setWitherInvulnerable(Wither wither, boolean charged) {
|
||||
BRIDGE.setWitherCharged(wither, charged);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator;
|
||||
|
||||
public interface NMSBridge {
|
||||
default void activate(Entity entity) {
|
||||
};
|
||||
}
|
||||
|
||||
public boolean addEntityToWorld(Entity entity, SpawnReason custom);
|
||||
|
||||
@ -60,9 +60,9 @@ public interface NMSBridge {
|
||||
|
||||
public default Iterable<Object> createBundlePacket(List<Object> packets) {
|
||||
return packets;
|
||||
}
|
||||
};
|
||||
|
||||
public EntityPacketTracker createPacketTracker(Entity entity, PacketAggregator agg);;
|
||||
public EntityPacketTracker createPacketTracker(Entity entity, PacketAggregator agg);
|
||||
|
||||
public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) throws Throwable;
|
||||
|
||||
@ -82,9 +82,9 @@ public interface NMSBridge {
|
||||
|
||||
public float getHeadYaw(Entity entity);
|
||||
|
||||
public double getHeight(Entity entity);
|
||||
public double getHeight(Entity entity);;
|
||||
|
||||
public float getHorizontalMovement(Entity entity);;
|
||||
public float getHorizontalMovement(Entity entity);
|
||||
|
||||
public CompoundTag getNBT(ItemStack item);
|
||||
|
||||
@ -147,9 +147,9 @@ public interface NMSBridge {
|
||||
|
||||
public Runnable playerTicker(Player entity);
|
||||
|
||||
public void registerEntityClass(Class<?> clazz);
|
||||
public void registerEntityClass(Class<?> clazz);;
|
||||
|
||||
public void remove(Entity entity);;
|
||||
public void remove(Entity entity);
|
||||
|
||||
public void removeFromServerPlayerList(Player player);
|
||||
|
||||
@ -165,7 +165,7 @@ public interface NMSBridge {
|
||||
|
||||
public void sendTabListRemove(Player recipient, Collection<? extends SkinnableEntity> skinnableNPCs);
|
||||
|
||||
public void sendTabListRemove(Player recipient, Player listPlayer);
|
||||
public void sendTabListRemove(Player recipient, Player listPlayer);;
|
||||
|
||||
public void sendTeamPacket(Player recipient, Team team, int mode);;
|
||||
|
||||
@ -174,11 +174,11 @@ public interface NMSBridge {
|
||||
|
||||
public default void setAllayDancing(Entity entity, boolean dancing) {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
public default void setCamelPose(Entity entity, CamelPose pose) {
|
||||
throw new UnsupportedOperationException();
|
||||
@ -245,6 +245,9 @@ public interface NMSBridge {
|
||||
|
||||
public void setVerticalMovement(Entity bukkitEntity, double d);
|
||||
|
||||
public default void setWardenPose(Entity entity, Object pose) {
|
||||
}
|
||||
|
||||
public void setWitherCharged(Wither wither, boolean charged);
|
||||
|
||||
public boolean shouldJump(Entity entity);
|
||||
@ -264,5 +267,5 @@ public interface NMSBridge {
|
||||
|
||||
public void updateNavigationWorld(Entity entity, World world);
|
||||
|
||||
public void updatePathfindingRange(NPC npc, float pathfindingRange);;
|
||||
public void updatePathfindingRange(NPC npc, float pathfindingRange);
|
||||
}
|
||||
|
@ -333,6 +333,8 @@ citizens.commands.npc.useitem.held-item-toggled=Using held item set to [[{0}]].
|
||||
citizens.commands.npc.useitem.offhand-item-toggled=Using offhand item set to [[{0}]].
|
||||
citizens.commands.npc.vulnerable.set=[[{0}]] is now vulnerable.
|
||||
citizens.commands.npc.vulnerable.stopped=[[{0}]] is no longer vulnerable.
|
||||
citizens.commands.npc.warden.anger-added=[[{1}]] anger added towards [[{0}]].
|
||||
citizens.commands.npc.warden.pose-set=[[{0}]]''s pose set to [[{1}]].
|
||||
citizens.commands.npc.wolf.unknown-collar-color=[[{0}]] is not an RGB-formatted collar color or the name of a DyeColor.
|
||||
citizens.commands.npc.wolf.collar-color-unsupported=[[{0}]] is not a RGB color code that can be used on a wolf''s collar.
|
||||
citizens.commands.npc.villager.level-set=Level set to [[{0}]].
|
||||
|
@ -116,5 +116,6 @@ public class PlayerControllerMove extends ControllerMove {
|
||||
|
||||
@Override
|
||||
public double f() {
|
||||
return thi
|
||||
return this.e;
|
||||
}
|
||||
}
|
@ -159,9 +159,9 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
|
||||
public void die(DamageSource damagesource) {
|
||||
// players that die are not normally removed from the world. when the
|
||||
// NPC dies, we are done with the instance and it should be removed.
|
||||
if (dead) {
|
||||
if (dead)
|
||||
return;
|
||||
}
|
||||
|
||||
super.die(damagesource);
|
||||
Bukkit.getScheduler().runTaskLater(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
@ -389,11 +389,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
|
||||
super.tick();
|
||||
if (npc == null)
|
||||
return;
|
||||
|
||||
noclip = isSpectator();
|
||||
Bukkit.getServer().getPluginManager().unsubscribeFromPermission("bukkit.broadcast.user", getBukkitEntity());
|
||||
boolean navigating = npc.getNavigator().isNavigating();
|
||||
updatePackets(navigating);
|
||||
npc.update();
|
||||
|
||||
if (npc.data().get(NPC.Metadata.PICKUP_ITEMS, false)) {
|
||||
AxisAlignedBB axisalignedbb;
|
||||
if (this.isPassenger() && !this.getVehicle().dead) {
|
||||
@ -401,6 +403,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
|
||||
} else {
|
||||
axisalignedbb = this.getBoundingBox().grow(1.0, 0.5, 1.0);
|
||||
}
|
||||
|
||||
for (Entity entity : this.world.getEntities(this, axisalignedbb)) {
|
||||
if (!entity.dead) {
|
||||
entity.pickup(this);
|
||||
|
@ -147,9 +147,9 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
|
||||
public void die(DamageSource damagesource) {
|
||||
// players that die are not normally removed from the world. when the
|
||||
// NPC dies, we are done with the instance and it should be removed.
|
||||
if (dead) {
|
||||
if (dead)
|
||||
return;
|
||||
}
|
||||
|
||||
super.die(damagesource);
|
||||
Bukkit.getScheduler().runTaskLater(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>net.citizensnpcs</groupId>
|
||||
<artifactId>citizens-parent</artifactId>
|
||||
<version>2.0.32-SNAPSHOT</version>
|
||||
<version>2.0.33-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>citizens-v1_17_R1</artifactId>
|
||||
<properties>
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.citizensnpcs.nms.v1_19_R3.entity.nonliving;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftBlockDisplay;
|
||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity;
|
||||
import org.bukkit.util.Vector;
|
||||
@ -32,6 +34,17 @@ public class BlockDisplayController extends MobEntityController {
|
||||
super(EntityBlockDisplayNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.bukkit.entity.Entity createEntity(Location at, NPC npc) {
|
||||
final EntityBlockDisplayNPC handle = new EntityBlockDisplayNPC(EntityType.BLOCK_DISPLAY,
|
||||
((CraftWorld) at.getWorld()).getHandle(), npc);
|
||||
if (npc != null) {
|
||||
((org.bukkit.entity.BlockDisplay) handle.getBukkitEntity())
|
||||
.setBlock(npc.getItemProvider().get().getType().createBlockData());
|
||||
}
|
||||
return handle.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.BlockDisplay getBukkitEntity() {
|
||||
return (org.bukkit.entity.BlockDisplay) super.getBukkitEntity();
|
||||
|
@ -297,6 +297,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.Container;
|
||||
@ -342,6 +343,7 @@ import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.entity.monster.EnderMan;
|
||||
import net.minecraft.world.entity.monster.Shulker;
|
||||
import net.minecraft.world.entity.monster.piglin.Piglin;
|
||||
import net.minecraft.world.entity.monster.warden.Warden;
|
||||
import net.minecraft.world.entity.projectile.FishingHook;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.inventory.AnvilMenu;
|
||||
@ -1665,6 +1667,44 @@ public class NMSImpl implements NMSBridge {
|
||||
handle.xxa = (float) d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWardenPose(org.bukkit.entity.Entity entity, Object pose) {
|
||||
Warden warden = (Warden) getHandle(entity);
|
||||
if (pose == org.bukkit.entity.Pose.DIGGING) {
|
||||
if (warden.hasPose(Pose.DIGGING))
|
||||
return;
|
||||
|
||||
warden.setPose(Pose.DIGGING);
|
||||
warden.playSound(SoundEvents.WARDEN_DIG, 5.0F, 1.0F);
|
||||
} else if (pose == org.bukkit.entity.Pose.EMERGING) {
|
||||
if (warden.hasPose(Pose.EMERGING))
|
||||
return;
|
||||
|
||||
warden.setPose(Pose.EMERGING);
|
||||
warden.playSound(SoundEvents.WARDEN_EMERGE, 5.0F, 1.0F);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
|
||||
if (warden.hasPose(Pose.EMERGING)) {
|
||||
warden.setPose(Pose.STANDING);
|
||||
}
|
||||
}, 134);
|
||||
} else if (pose == org.bukkit.entity.Pose.ROARING) {
|
||||
if (warden.hasPose(Pose.ROARING))
|
||||
return;
|
||||
|
||||
warden.setPose(Pose.ROARING);
|
||||
warden.playSound(SoundEvents.WARDEN_ROAR, 3.0F, 1.0F);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
|
||||
if (warden.hasPose(Pose.ROARING)) {
|
||||
warden.setPose(Pose.STANDING);
|
||||
}
|
||||
}, 84);
|
||||
} else {
|
||||
warden.setPose(Pose.STANDING);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWitherCharged(Wither wither, boolean charged) {
|
||||
WitherBoss handle = ((CraftWither) wither).getHandle();
|
||||
|
@ -15,7 +15,6 @@ import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
@ -94,6 +93,7 @@ public class WardenController extends MobEntityController {
|
||||
super.customServerAiStep();
|
||||
return;
|
||||
}
|
||||
|
||||
NMSImpl.updateMinecraftAIState(npc, this);
|
||||
npc.update();
|
||||
if (npc.useMinecraftAI()) {
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.citizensnpcs.nms.v1_20_R2.entity.nonliving;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftBlockDisplay;
|
||||
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity;
|
||||
import org.bukkit.util.Vector;
|
||||
@ -14,7 +16,6 @@ import net.citizensnpcs.nms.v1_20_R2.util.NMSImpl;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.TagKey;
|
||||
@ -32,6 +33,17 @@ public class BlockDisplayController extends MobEntityController {
|
||||
super(EntityBlockDisplayNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected org.bukkit.entity.Entity createEntity(Location at, NPC npc) {
|
||||
final EntityBlockDisplayNPC handle = new EntityBlockDisplayNPC(EntityType.BLOCK_DISPLAY,
|
||||
((CraftWorld) at.getWorld()).getHandle(), npc);
|
||||
if (npc != null) {
|
||||
((org.bukkit.entity.BlockDisplay) handle.getBukkitEntity())
|
||||
.setBlock(npc.getItemProvider().get().getType().createBlockData());
|
||||
}
|
||||
return handle.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.BlockDisplay getBukkitEntity() {
|
||||
return (org.bukkit.entity.BlockDisplay) super.getBukkitEntity();
|
||||
@ -111,6 +123,7 @@ public class BlockDisplayController extends MobEntityController {
|
||||
public Entity teleportTo(ServerLevel worldserver, Vec3 location) {
|
||||
if (npc == null)
|
||||
return super.teleportTo(worldserver, location);
|
||||
|
||||
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
|
||||
}
|
||||
|
||||
|
@ -287,6 +287,7 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.Container;
|
||||
@ -332,6 +333,7 @@ import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.entity.monster.EnderMan;
|
||||
import net.minecraft.world.entity.monster.Shulker;
|
||||
import net.minecraft.world.entity.monster.piglin.Piglin;
|
||||
import net.minecraft.world.entity.monster.warden.Warden;
|
||||
import net.minecraft.world.entity.projectile.FishingHook;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.inventory.AnvilMenu;
|
||||
@ -457,7 +459,7 @@ public class NMSImpl implements NMSBridge {
|
||||
}
|
||||
EnchantmentHelper.doPostHurtEffects(source, target);
|
||||
EnchantmentHelper.doPostDamageEffects(target, source);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelMoveDestination(org.bukkit.entity.Entity entity) {
|
||||
@ -473,7 +475,7 @@ public class NMSImpl implements NMSBridge {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
@ -1641,6 +1643,44 @@ public class NMSImpl implements NMSBridge {
|
||||
handle.xxa = (float) d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWardenPose(org.bukkit.entity.Entity entity, Object pose) {
|
||||
Warden warden = (Warden) getHandle(entity);
|
||||
if (pose == org.bukkit.entity.Pose.DIGGING) {
|
||||
if (warden.hasPose(Pose.DIGGING))
|
||||
return;
|
||||
|
||||
warden.setPose(Pose.DIGGING);
|
||||
warden.playSound(SoundEvents.WARDEN_DIG, 5.0F, 1.0F);
|
||||
} else if (pose == org.bukkit.entity.Pose.EMERGING) {
|
||||
if (warden.hasPose(Pose.EMERGING))
|
||||
return;
|
||||
|
||||
warden.setPose(Pose.EMERGING);
|
||||
warden.playSound(SoundEvents.WARDEN_EMERGE, 5.0F, 1.0F);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
|
||||
if (warden.hasPose(Pose.EMERGING)) {
|
||||
warden.setPose(Pose.STANDING);
|
||||
}
|
||||
}, 134);
|
||||
} else if (pose == org.bukkit.entity.Pose.ROARING) {
|
||||
if (warden.hasPose(Pose.ROARING))
|
||||
return;
|
||||
|
||||
warden.setPose(Pose.ROARING);
|
||||
warden.playSound(SoundEvents.WARDEN_ROAR, 3.0F, 1.0F);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
|
||||
if (warden.hasPose(Pose.ROARING)) {
|
||||
warden.setPose(Pose.STANDING);
|
||||
}
|
||||
}, 84);
|
||||
} else {
|
||||
warden.setPose(Pose.STANDING);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWitherCharged(Wither wither, boolean charged) {
|
||||
WitherBoss handle = ((CraftWither) wither).getHandle();
|
||||
@ -1672,7 +1712,7 @@ public class NMSImpl implements NMSBridge {
|
||||
@Override
|
||||
public void sleep(org.bukkit.entity.Player player, boolean sleeping) {
|
||||
getHandle(player).setPose(sleeping ? Pose.SLEEPING : Pose.STANDING);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void trySwim(org.bukkit.entity.Entity entity) {
|
||||
@ -2197,17 +2237,30 @@ public class NMSImpl implements NMSBridge {
|
||||
if (pitch == null) {
|
||||
pitch = handle.getXRot();
|
||||
}
|
||||
|
||||
List<Packet<?>> toSend = Lists.newArrayList();
|
||||
if (position) {
|
||||
TrackedEntity entry = ((ServerLevel) handle.level()).getChunkSource().chunkMap.entityMap
|
||||
.get(handle.getId());
|
||||
if (entry == null) {
|
||||
Messaging.debug("Null tracker entity for ", from);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
VecDeltaCodec vdc = null;
|
||||
try {
|
||||
vdc = (VecDeltaCodec) POSITION_CODEC_GETTER.invoke((ServerEntity) SERVER_ENTITY_GETTER.invoke(entry));
|
||||
ServerEntity serverEntity = (ServerEntity) SERVER_ENTITY_GETTER.invoke(entry);
|
||||
if (serverEntity == null) {
|
||||
Messaging.debug("Null server entity for ", from);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
vdc = (VecDeltaCodec) POSITION_CODEC_GETTER.invoke(serverEntity);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Vec3 pos = handle.trackingPosition();
|
||||
toSend.add(new ClientboundMoveEntityPacket.PosRot(handle.getId(), (short) vdc.encodeX(pos),
|
||||
(short) vdc.encodeY(pos), (short) vdc.encodeZ(pos), (byte) (bodyYaw * 256.0F / 360.0F),
|
||||
|
Loading…
Reference in New Issue
Block a user