Skip to content

Commit

Permalink
Implement event, and use it to link hologram display entity. unify so…
Browse files Browse the repository at this point in the history
…me old tracker implementations. WIP implementation of unified player linking
  • Loading branch information
fullwall committed Oct 29, 2023
1 parent 751e2a2 commit d17ca61
Show file tree
Hide file tree
Showing 20 changed files with 316 additions and 107 deletions.
4 changes: 1 addition & 3 deletions main/src/main/java/net/citizensnpcs/Citizens.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ 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;
Expand Down Expand Up @@ -548,7 +547,6 @@ private void setupTranslator() {
}
}
Translator.setInstance(new File(getDataFolder(), "lang"), locale);
this.locale = locale;
}

private void startMetrics() {
Expand All @@ -559,7 +557,7 @@ private void startMetrics() {
return 0;
return Iterables.size(npcRegistry);
}));
metrics.addCustomChart(new Metrics.SimplePie("locale", () -> locale.toString()));
metrics.addCustomChart(new Metrics.SimplePie("locale", () -> Locale.getDefault().toString()));
metrics.addCustomChart(new Metrics.AdvancedPie("traits", () -> {
Map<String, Integer> res = Maps.newHashMap();
for (NPC npc : npcRegistry) {
Expand Down
61 changes: 57 additions & 4 deletions main/src/main/java/net/citizensnpcs/EventListen.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import net.citizensnpcs.api.event.NPCDespawnEvent;
import net.citizensnpcs.api.event.NPCKnockbackEvent;
import net.citizensnpcs.api.event.NPCLeftClickEvent;
import net.citizensnpcs.api.event.NPCLinkToPlayerEvent;
import net.citizensnpcs.api.event.NPCPushEvent;
import net.citizensnpcs.api.event.NPCRemoveEvent;
import net.citizensnpcs.api.event.NPCRightClickEvent;
Expand All @@ -109,6 +110,7 @@
import net.citizensnpcs.trait.CommandTrait;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.trait.HologramTrait;
import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.util.ChunkCoord;
import net.citizensnpcs.util.Messages;
Expand Down Expand Up @@ -428,6 +430,55 @@ public void onNPCKnockback(NPCKnockbackEvent event) {
}
}

@EventHandler(ignoreCancelled = true)
public void onNPCLinkToPlayer(NPCLinkToPlayerEvent event) {
NPC npc = event.getNPC();
ClickRedirectTrait crt = npc.getTraitNullable(ClickRedirectTrait.class);
if (crt != null) {
HologramTrait ht = crt.getRedirectNPC().getTraitNullable(HologramTrait.class);
if (ht != null) {
ht.onHologramSeenByPlayer(npc, event.getPlayer());
}
}

/* TODO
if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) {
onNPCPlayerLinkToPlayer(event);
}
*/
}

private void onNPCPlayerLinkToPlayer(NPCLinkToPlayerEvent event) {
Entity tracker = event.getNPC().getEntity();
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
if (!tracker.isValid() || !event.getPlayer().isValid())
return;

NMS.sendPositionUpdate(tracker, false, null, null, NMS.getHeadYaw(tracker));
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks() + 1);

boolean resetYaw = event.getNPC().data().get(NPC.Metadata.RESET_YAW_ON_SPAWN,
Setting.RESET_YAW_ON_SPAWN.asBoolean());
boolean sendTabRemove = NMS.sendTabListAdd(event.getPlayer(), (Player) tracker);
if (!sendTabRemove || !Setting.DISABLE_TABLIST.asBoolean()) {
if (resetYaw) {
// Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
// () -> PlayerAnimation.ARM_SWING.play((Player) tracker, event.getPlayer()), 1);
}
return;
}

Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
if (!tracker.isValid() || !event.getPlayer().isValid())
return;

NMS.sendTabListRemove(event.getPlayer(), (Player) tracker);
if (resetYaw) {
// PlayerAnimation.ARM_SWING.play((Player) tracker, event.getPlayer());
}
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onNPCRemove(NPCRemoveEvent event) {
toRespawn.values().remove(event.getNPC());
Expand All @@ -436,12 +487,14 @@ public void onNPCRemove(NPCRemoveEvent event) {
@EventHandler(ignoreCancelled = true)
public void onNPCSeenByPlayer(NPCSeenByPlayerEvent event) {
NPC npc = event.getNPC();
if (npc.hasTrait(ClickRedirectTrait.class)) {
npc = npc.getOrAddTrait(ClickRedirectTrait.class).getRedirectNPC();
ClickRedirectTrait crt = npc.getTraitNullable(ClickRedirectTrait.class);
if (crt != null) {
npc = crt.getRedirectNPC();
}

if (npc.hasTrait(PlayerFilter.class)) {
event.setCancelled(npc.getOrAddTrait(PlayerFilter.class).onSeenByPlayer(event.getPlayer()));
PlayerFilter pf = npc.getTraitNullable(PlayerFilter.class);
if (pf != null) {
event.setCancelled(pf.onSeenByPlayer(event.getPlayer()));
}
}

Expand Down
33 changes: 25 additions & 8 deletions main/src/main/java/net/citizensnpcs/trait/HologramTrait.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
Expand All @@ -36,9 +35,10 @@
import net.citizensnpcs.util.Util;

/**
* Persists a hologram attached to the NPC.
* Manages a set of <em>holograms</em> attached to the NPC. Holograms are lines of text or items that follow the NPC at
* some offset (typically vertically offset).
*/
// TODO: refactor this class and remove HologramDirection
// TODO: refactor this class
@TraitName("hologramtrait")
public class HologramTrait extends Trait {
private Location currentLoc;
Expand Down Expand Up @@ -99,6 +99,7 @@ private NPC createHologram(String line, double heightOffset) {
hologramNPC = registry.createNPC(EntityType.INTERACTION, line);
hologramNPC.addTrait(new ClickRedirectTrait(npc));
hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, true);
hologramNPC.getOrAddTrait(MountTrait.class).setMountedOn(npc.getUniqueId());
} else {
hologramNPC = registry.createNPC(EntityType.ARMOR_STAND, line);
hologramNPC.getOrAddTrait(ArmorStandTrait.class).setAsHelperEntityWithName(npc);
Expand All @@ -110,11 +111,6 @@ private NPC createHologram(String line, double heightOffset) {

hologramNPC.spawn(currentLoc.clone().add(0, getEntityHeight() + heightOffset, 0));

if (useDisplayEntities) {
((Interaction) hologramNPC.getEntity()).setInteractionWidth(0);
NMS.updateMountedInteractionHeight(hologramNPC.getEntity(), npc.getEntity(), heightOffset);
}

Matcher itemMatcher = ITEM_MATCHER.matcher(line);
if (itemMatcher.matches()) {
Material item = SpigotUtil.isUsing1_13API() ? Material.matchMaterial(itemMatcher.group(1), false)
Expand Down Expand Up @@ -214,6 +210,27 @@ public void onDespawn() {
}
}

public void onHologramSeenByPlayer(NPC hologram, Player player) {
if (useDisplayEntities && npc.isSpawned()) {
double height = -1;
if (nameLine != null && hologram.equals(nameLine.hologram)) {
height = 0;
} else {
for (int i = 0; i < lines.size(); i++) {
if (hologram.equals(lines.get(i).hologram)) {
height = getHeight(i);
break;
}
}
}

if (height == -1)
return;

NMS.linkTextInteraction(player, hologram.getEntity(), npc.getEntity(), height);
}
}

@Override
public void onRemove() {
onDespawn();
Expand Down
8 changes: 4 additions & 4 deletions main/src/main/java/net/citizensnpcs/util/NMS.java
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,10 @@ public static boolean isValid(Entity entity) {
return BRIDGE.isValid(entity);
}

public static void linkTextInteraction(Player player, Entity interaction, Entity mount, double height) {
BRIDGE.linkTextInteraction(player, interaction, mount, height);
}

public static void load(CommandManager commands) {
BRIDGE.load(commands);
}
Expand Down Expand Up @@ -891,10 +895,6 @@ public static void updateInventoryTitle(Player player, InventoryView view, Strin
BRIDGE.updateInventoryTitle(player, view, newTitle);
}

public static void updateMountedInteractionHeight(Entity entity, Entity mount, double height) {
BRIDGE.updateMountedInteractionHeight(entity, mount, height);
}

public static void updateNavigationWorld(org.bukkit.entity.Entity entity, org.bukkit.World world) {
BRIDGE.updateNavigationWorld(entity, world);
}
Expand Down
18 changes: 9 additions & 9 deletions main/src/main/java/net/citizensnpcs/util/NMSBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ public default Object getBossBar(Entity entity) {

public boolean isValid(Entity entity);

public default void linkTextInteraction(Player player, Entity interaction, Entity mount, double height) {
}

public void load(CommandManager commands);

public void look(Entity from, Entity to);
Expand All @@ -145,9 +148,9 @@ public default void onPlayerInfoAdd(Player player, Object source, Function<UUID,

public void playAnimation(PlayerAnimation animation, Player player, int radius);

public Runnable playerTicker(Player entity);
public Runnable playerTicker(Player entity);;

public void registerEntityClass(Class<?> clazz);;
public void registerEntityClass(Class<?> clazz);

public void remove(Entity entity);

Expand All @@ -163,20 +166,20 @@ public default void onPlayerInfoAdd(Player player, Object source, Function<UUID,

public boolean sendTabListAdd(Player recipient, Player listPlayer);

public void sendTabListRemove(Player recipient, Collection<? extends SkinnableEntity> skinnableNPCs);
public void sendTabListRemove(Player recipient, Collection<? extends SkinnableEntity> skinnableNPCs);;

public void sendTabListRemove(Player recipient, Player listPlayer);;

public void sendTeamPacket(Player recipient, Team team, int mode);;

default public void setAggressive(Entity entity, boolean aggro) {
};
}

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);

Expand Down Expand Up @@ -262,9 +265,6 @@ public default void setWardenPose(Entity entity, Object pose) {

public void updateInventoryTitle(Player player, InventoryView view, String newTitle);

public default void updateMountedInteractionHeight(Entity entity, Entity mount, double height) {
}

public void updateNavigationWorld(Entity entity, World world);

public void updatePathfindingRange(NPC npc, float pathfindingRange);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;

import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCLinkToPlayerEvent;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_10_R1.entity.EntityHumanNPC;
Expand All @@ -27,7 +29,6 @@ public PlayerlistTrackerEntry(EntityTrackerEntry entry) {

@Override
public void updatePlayer(final EntityPlayer entityplayer) {
// prevent updates to NPC "viewers"
if (entityplayer instanceof EntityHumanNPC)
return;
Entity tracker = getTracker(this);
Expand All @@ -38,8 +39,12 @@ public void updatePlayer(final EntityPlayer entityplayer) {
if (event.isCancelled())
return;
}
if (tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER)

super.updatePlayer(entityplayer);

if (tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;

if (entityplayer != tracker && c(entityplayer)) {
if (!this.trackedPlayers.contains(entityplayer)
&& ((entityplayer.x().getPlayerChunkMap().a(entityplayer, tracker.ac, tracker.ae))
Expand All @@ -51,9 +56,12 @@ public void updatePlayer(final EntityPlayer entityplayer) {
return;
skinnable.getSkinTracker().updateViewer(entityplayer.getBukkitEntity());
}

Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(
((NPCHolder) tracker).getNPC(), entityplayer.getBukkitEntity())));
}
}
super.updatePlayer(entityplayer);
}

private static int getE(EntityTrackerEntry entry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCLinkToPlayerEvent;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.npc.ai.NPCHolder;
Expand Down Expand Up @@ -86,35 +87,45 @@ private boolean isTracked(EntityPlayer player) {
}

public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
final EntityPlayer entityplayer = lastUpdatedPlayer;
if (lastUpdatedPlayer != null) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> Bukkit.getPluginManager().callEvent(
new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), entityplayer.getBukkitEntity())));
}

if (lastUpdatedPlayer == null || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;

NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
lastUpdatedPlayer = null;
NPC npc = ((NPCHolder) tracker).getNPC();
if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)),
1);
}

if (!Setting.DISABLE_TABLIST.asBoolean())
return;

Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()),
Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
}

@Override
public void updatePlayer(final EntityPlayer entityplayer) {
if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) {
if (entityplayer instanceof NPCHolder)
return;

if (!isTracked(entityplayer) && tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
}
if (entityplayer instanceof NPCHolder)
return;

super.updatePlayer(entityplayer);
}

Expand Down
Loading

0 comments on commit d17ca61

Please sign in to comment.