From ed89011dbc4fbf7f84315c1d303a69ff44a6a62c Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Mon, 18 May 2020 21:57:40 +0200
Subject: [PATCH 1/7] Add NPC respawn on Player respawn
---
src/main/java/com/github/juliarn/npc/NPCPool.java | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/main/java/com/github/juliarn/npc/NPCPool.java b/src/main/java/com/github/juliarn/npc/NPCPool.java
index 3ecffc7..eb03f56 100644
--- a/src/main/java/com/github/juliarn/npc/NPCPool.java
+++ b/src/main/java/com/github/juliarn/npc/NPCPool.java
@@ -19,6 +19,7 @@
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
@@ -139,6 +140,18 @@ public void removeNPC(int entityId) {
}
}
+ @EventHandler
+ public void handleRespawn(PlayerRespawnEvent event) {
+ Player player = event.getPlayer();
+
+ this.npcMap.values().stream()
+ .filter(npc -> npc.isShownFor(player))
+ .forEach(npc -> {
+ npc.hide(player);
+ npc.show(player, this.javaPlugin, this.tabListRemoveTicks);
+ });
+ }
+
@EventHandler
public void handleQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
From 6e36f73e9c43e75f6845d816c276b04720cc8c52 Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Mon, 18 May 2020 22:52:08 +0200
Subject: [PATCH 2/7] Add world checks to imitate events :life:
---
src/main/java/com/github/juliarn/npc/NPCPool.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/github/juliarn/npc/NPCPool.java b/src/main/java/com/github/juliarn/npc/NPCPool.java
index eb03f56..2f3102c 100644
--- a/src/main/java/com/github/juliarn/npc/NPCPool.java
+++ b/src/main/java/com/github/juliarn/npc/NPCPool.java
@@ -166,7 +166,8 @@ public void handleSneak(PlayerToggleSneakEvent event) {
Player player = event.getPlayer();
this.npcMap.values().stream()
- .filter(npc -> npc.isImitatePlayer() && npc.isShownFor(player) && npc.getLocation().distanceSquared(player.getLocation()) <= this.actionDistance)
+ .filter(npc -> npc.isImitatePlayer() && npc.isShownFor(player))
+ .filter(npc -> npc.getLocation().getWorld().equals(player.getWorld()) && npc.getLocation().distanceSquared(player.getLocation()) <= this.actionDistance)
.forEach(npc -> npc.metadata().queue(MetadataModifier.EntityMetadata.SNEAKING, event.isSneaking()).send(player));
}
@@ -176,7 +177,8 @@ public void handleClick(PlayerInteractEvent event) {
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
this.npcMap.values().stream()
- .filter(npc -> npc.isImitatePlayer() && npc.isShownFor(player) && npc.getLocation().distanceSquared(player.getLocation()) <= this.actionDistance)
+ .filter(npc -> npc.isImitatePlayer() && npc.isShownFor(player))
+ .filter(npc -> npc.getLocation().getWorld().equals(player.getWorld()) && npc.getLocation().distanceSquared(player.getLocation()) <= this.actionDistance)
.forEach(npc -> npc.animation().queue(AnimationModifier.EntityAnimation.SWING_MAIN_ARM).send(player));
}
}
From fbe9b64801af934b45d3728f326959982b761c30 Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Tue, 13 Oct 2020 15:04:22 +0200
Subject: [PATCH 3/7] Fix entity equipment packet for 1.16
---
pom.xml | 4 ++--
.../npc/modifier/EquipmentModifier.java | 24 +++++++++++++++----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/pom.xml b/pom.xml
index 74a98d4..26fdbfe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.github.juliarn
npc-lib
- 2.3-RELEASE
+ 2.4-RELEASE
jar
@@ -46,7 +46,7 @@
com.comphenix.protocol
ProtocolLib
- 4.5.0
+ 4.6.0-SNAPSHOT
provided
diff --git a/src/main/java/com/github/juliarn/npc/modifier/EquipmentModifier.java b/src/main/java/com/github/juliarn/npc/modifier/EquipmentModifier.java
index b28fb8d..36f9c5c 100644
--- a/src/main/java/com/github/juliarn/npc/modifier/EquipmentModifier.java
+++ b/src/main/java/com/github/juliarn/npc/modifier/EquipmentModifier.java
@@ -4,10 +4,13 @@
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
+import com.comphenix.protocol.wrappers.Pair;
import com.github.juliarn.npc.NPC;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
+import java.util.Collections;
+
public class EquipmentModifier extends NPCModifier {
public EquipmentModifier(@NotNull NPC npc) {
@@ -17,8 +20,12 @@ public EquipmentModifier(@NotNull NPC npc) {
public EquipmentModifier queue(@NotNull EnumWrappers.ItemSlot itemSlot, @NotNull ItemStack equipment) {
PacketContainer packetContainer = super.newContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
- packetContainer.getItemSlots().write(MINECRAFT_VERSION < 9 ? 1 : 0, itemSlot);
- packetContainer.getItemModifier().write(0, equipment);
+ if (MINECRAFT_VERSION < 16) {
+ packetContainer.getItemSlots().write(MINECRAFT_VERSION < 9 ? 1 : 0, itemSlot);
+ packetContainer.getItemModifier().write(0, equipment);
+ } else {
+ packetContainer.getSlotStackPairLists().write(0, Collections.singletonList(new Pair<>(itemSlot, equipment)));
+ }
return this;
}
@@ -26,8 +33,17 @@ public EquipmentModifier queue(@NotNull EnumWrappers.ItemSlot itemSlot, @NotNull
public EquipmentModifier queue(int itemSlot, @NotNull ItemStack equipment) {
PacketContainer packetContainer = super.newContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
- packetContainer.getIntegers().write(MINECRAFT_VERSION < 9 ? 1 : 0, itemSlot);
- packetContainer.getItemModifier().write(0, equipment);
+ if (MINECRAFT_VERSION < 16) {
+ packetContainer.getIntegers().write(MINECRAFT_VERSION < 9 ? 1 : 0, itemSlot);
+ packetContainer.getItemModifier().write(0, equipment);
+ } else {
+ for (EnumWrappers.ItemSlot slot : EnumWrappers.ItemSlot.values()) {
+ if (slot.ordinal() == itemSlot) {
+ packetContainer.getSlotStackPairLists().write(0, Collections.singletonList(new Pair<>(slot, equipment)));
+ break;
+ }
+ }
+ }
return this;
}
From dac967db3e57d982439b06639aef98376ad6e77c Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Tue, 13 Oct 2020 15:25:06 +0200
Subject: [PATCH 4/7] Add possibility to exclude players from seeing the NPC.
fixes #21
---
src/main/java/com/github/juliarn/npc/NPC.java | 31 +++++++++++++++++++
.../java/com/github/juliarn/npc/NPCPool.java | 13 +++++---
2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/github/juliarn/npc/NPC.java b/src/main/java/com/github/juliarn/npc/NPC.java
index dd13844..ec3f110 100644
--- a/src/main/java/com/github/juliarn/npc/NPC.java
+++ b/src/main/java/com/github/juliarn/npc/NPC.java
@@ -21,6 +21,8 @@ public class NPC {
private final Collection seeingPlayers = new CopyOnWriteArraySet<>();
+ private final Collection excludedPlayers = new CopyOnWriteArraySet<>();
+
private final int entityId = RANDOM.nextInt(Short.MAX_VALUE);
private final WrappedGameProfile gameProfile;
@@ -81,6 +83,35 @@ public boolean isShownFor(Player player) {
return this.seeingPlayers.contains(player);
}
+ /**
+ * Adds a player which should be explicitly excluded from seeing this NPC
+ *
+ * @param player the player to be excluded
+ */
+ public void addExcludedPlayer(Player player) {
+ this.excludedPlayers.add(player);
+ }
+
+ /**
+ * Removes a player from being explicitly excluded from seeing this NPC
+ *
+ * @param player the player to be included again
+ */
+ public void removeExcludedPlayer(Player player) {
+ this.excludedPlayers.remove(player);
+ }
+
+ /**
+ * @return a modifiable collection of all players which are explicitly excluded from seeing this NPC
+ */
+ public Collection getExcludedPlayers() {
+ return this.excludedPlayers;
+ }
+
+ public boolean isExcluded(Player player) {
+ return this.excludedPlayers.contains(player);
+ }
+
/**
* Creates a new animation modifier which serves methods to play animations on an NPC
*
diff --git a/src/main/java/com/github/juliarn/npc/NPCPool.java b/src/main/java/com/github/juliarn/npc/NPCPool.java
index 2f3102c..0723bac 100644
--- a/src/main/java/com/github/juliarn/npc/NPCPool.java
+++ b/src/main/java/com/github/juliarn/npc/NPCPool.java
@@ -108,13 +108,13 @@ private void npcTick() {
double distance = npc.getLocation().distanceSquared(player.getLocation());
- if (distance >= this.spawnDistance && npc.isShownFor(player)) {
+ if ((npc.isExcluded(player) || distance >= this.spawnDistance) && npc.isShownFor(player)) {
npc.hide(player);
- } else if (distance <= this.spawnDistance && !npc.isShownFor(player)) {
+ } else if ((!npc.isExcluded(player) && distance <= this.spawnDistance) && !npc.isShownFor(player)) {
npc.show(player, this.javaPlugin, this.tabListRemoveTicks);
}
- if (npc.isLookAtPlayer() && distance <= this.actionDistance) {
+ if (npc.isShownFor(player) && npc.isLookAtPlayer() && distance <= this.actionDistance) {
npc.rotation().queueLookAt(player.getLocation()).send(player);
}
}
@@ -157,8 +157,11 @@ public void handleQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
this.npcMap.values().stream()
- .filter(npc -> npc.isShownFor(player))
- .forEach(npc -> npc.removeSeeingPlayer(player));
+ .filter(npc -> npc.isShownFor(player) || npc.isExcluded(player))
+ .forEach(npc -> {
+ npc.removeSeeingPlayer(player);
+ npc.removeExcludedPlayer(player);
+ });
}
@EventHandler
From 7116207773d705b88762ca6f0038ec2d097d4044 Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Tue, 13 Oct 2020 15:26:22 +0200
Subject: [PATCH 5/7] Update README
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 6c8ee7c..f8b38cb 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# NPC-Lib
-Minecraft NPC library for 1.8-1.15 servers.
+Minecraft NPC library for 1.8-1.16 servers.
This Library does only support the latest patch release of a supported version (for example 1.13.2).
Issues with older patch versions (for example 1.13.1) won't be fixed.
@@ -20,7 +20,7 @@ Maven
com.github.juliarn
npc-lib
- 2.3-RELEASE
+ 2.4-RELEASE
```
@@ -31,7 +31,7 @@ maven {
url 'https://jitpack.io'
}
-compile group: 'com.github.juliarn', name: 'npc-lib', version: '2.3-RELEASE'
+compile group: 'com.github.juliarn', name: 'npc-lib', version: '2.4-RELEASE'
```
Add ProtocolLib as dependency to your plugin.yml. It could look like this:
From d48524cb7ada1895b0d9a852d9159a2bd2e6f3b5 Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Tue, 13 Oct 2020 16:27:33 +0200
Subject: [PATCH 6/7] Fix invisible NPCs after death or world switch
---
src/main/java/com/github/juliarn/npc/NPCPool.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/github/juliarn/npc/NPCPool.java b/src/main/java/com/github/juliarn/npc/NPCPool.java
index 0723bac..5449a07 100644
--- a/src/main/java/com/github/juliarn/npc/NPCPool.java
+++ b/src/main/java/com/github/juliarn/npc/NPCPool.java
@@ -103,6 +103,9 @@ private void npcTick() {
for (Player player : ImmutableList.copyOf(Bukkit.getOnlinePlayers())) {
for (NPC npc : this.npcMap.values()) {
if (!npc.getLocation().getWorld().equals(player.getLocation().getWorld())) {
+ if (npc.isShownFor(player)) {
+ npc.hide(player);
+ }
continue;
}
@@ -146,10 +149,7 @@ public void handleRespawn(PlayerRespawnEvent event) {
this.npcMap.values().stream()
.filter(npc -> npc.isShownFor(player))
- .forEach(npc -> {
- npc.hide(player);
- npc.show(player, this.javaPlugin, this.tabListRemoveTicks);
- });
+ .forEach(npc -> npc.hide(player));
}
@EventHandler
From 2095627dba97d7011a218ac2714fc23fb6f1a722 Mon Sep 17 00:00:00 2001
From: Julian <42209193+juliarn@users.noreply.github.com>
Date: Tue, 13 Oct 2020 17:09:14 +0200
Subject: [PATCH 7/7] Update README.md
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f8b38cb..4733814 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# NPC-Lib
-Minecraft NPC library for 1.8-1.16 servers.
+Asynchronous, high-performance Minecraft NPC library for 1.8-1.16 servers.
+
This Library does only support the latest patch release of a supported version (for example 1.13.2).
Issues with older patch versions (for example 1.13.1) won't be fixed.