Packet NPCs now properly spawn, fix NPE in new pathfinder, fix 1.8.8 compatibility with /npc shop

This commit is contained in:
fullwall 2023-01-04 23:02:33 +08:00
parent e21681fa26
commit ffef42efb7
15 changed files with 107 additions and 54 deletions

View File

@ -234,6 +234,10 @@ public class CitizensNPC extends AbstractNPC {
prev = getEntity().getLocation(CACHE_LOCATION);
despawn(DespawnReason.PENDING_RESPAWN);
}
PacketNPC packet = getTraitNullable(PacketNPC.class);
if (packet != null) {
newController = packet.wrap(newController);
}
entityController = newController;
if (wasSpawned) {
spawn(prev, SpawnReason.RESPAWN);
@ -333,7 +337,7 @@ public class CitizensNPC extends AbstractNPC {
@Override
public void accept(Runnable cancel) {
if (getEntity() == null || !getEntity().isValid()) {
if (getEntity() == null || (!hasTrait(PacketNPC.class) && !getEntity().isValid())) {
if (timer++ > Setting.ENTITY_SPAWN_WAIT_TICKS.asInt()) {
Messaging.debug("Couldn't spawn ", CitizensNPC.this, "waited", timer,
"ticks but entity not added to world");

View File

@ -89,6 +89,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
}
plan = planner.plan;
if (plan != null) {
vector = plan.getCurrentVector();
planner = null;
}
}
@ -97,7 +98,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
}
Location loc = npc.getEntity().getLocation(NPC_LOCATION);
/* Proper door movement - gets stuck on corners at times
Block block = currLoc.getWorld().getBlockAt(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
if (MinecraftBlockExaminer.isDoor(block.getType())) {
Door door = (Door) block.getState().getData();

View File

@ -1,15 +1,16 @@
package net.citizensnpcs.trait;
import java.util.function.Consumer;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.LocationLookup.PerPlayerMetadata;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.EntityController;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.PlayerUpdateTask;
@ -17,6 +18,7 @@ import net.citizensnpcs.util.PlayerUpdateTask;
@TraitName("packet")
public class PacketNPC extends Trait {
private EntityPacketTracker playerTracker;
private boolean spawned = false;
public PacketNPC() {
super("packet");
@ -25,26 +27,36 @@ public class PacketNPC extends Trait {
@Override
public void onSpawn() {
playerTracker = NMS.getPlayerTracker(npc.getEntity());
spawned = true;
}
@Override
public void run() {
wrap((CitizensNPC) npc);
if (!npc.isSpawned())
if (!spawned)
return;
PerPlayerMetadata<Boolean> ppm = CitizensAPI.getLocationLookup().registerMetadata("packetnpc", null);
for (Player nearby : CitizensAPI.getLocationLookup().getNearbyPlayers(npc.getStoredLocation(), 64)) {
if (!nearby.hasMetadata(npc.getUniqueId().toString())) {
if (!ppm.has(nearby.getUniqueId(), npc.getUniqueId().toString())) {
playerTracker.link(nearby);
nearby.setMetadata(npc.getUniqueId().toString(), new FixedMetadataValue(CitizensAPI.getPlugin(), true));
ppm.set(nearby.getUniqueId(), npc.getUniqueId().toString(), true);
}
}
playerTracker.run();
}
private void wrap(CitizensNPC npc) {
if (!(npc.getEntityController() instanceof PacketController)) {
npc.setEntityController(new PacketController(npc.getEntityController()));
public EntityController wrap(EntityController controller) {
if (!(controller instanceof PacketController)) {
return new PacketController(controller);
}
return controller;
}
public static interface EntityPacketTracker extends Runnable {
public void link(Player player);
public void unlinkAll(Consumer<Player> callback);
public void unlink(Player player);
}
private class PacketController implements EntityController {
@ -61,6 +73,13 @@ public class PacketNPC extends Trait {
@Override
public void die() {
base.die();
if (!spawned)
return;
PlayerUpdateTask.deregisterPlayer(getBukkitEntity());
PerPlayerMetadata<Boolean> ppm = CitizensAPI.getLocationLookup().registerMetadata("packetnpc", null);
playerTracker.unlinkAll(player -> ppm.remove(player.getUniqueId(), npc.getUniqueId().toString()));
spawned = false;
}
@Override
@ -70,9 +89,13 @@ public class PacketNPC extends Trait {
@Override
public void remove() {
if (!spawned)
return;
PlayerUpdateTask.deregisterPlayer(getBukkitEntity());
playerTracker.remove();
PerPlayerMetadata<Boolean> ppm = CitizensAPI.getLocationLookup().registerMetadata("packetnpc", null);
playerTracker.unlinkAll(player -> ppm.remove(player.getUniqueId(), npc.getUniqueId().toString()));
base.remove();
spawned = false;
}
@Override
@ -82,12 +105,4 @@ public class PacketNPC extends Trait {
return true;
}
}
public static interface EntityPacketTracker extends Runnable {
public void link(Player player);
public void remove();
public void unlink(Player player);
}
}

View File

@ -617,7 +617,7 @@ public class ShopTrait extends Trait {
shop.type == ShopType.COMMAND)));
}
@MenuSlot(slot = { 0, 8 }, material = Material.COMMAND_BLOCK, amount = 1)
@MenuSlot(slot = { 0, 8 }, compatMaterial = { "COMMAND_BLOCK", "COMMAND" }, amount = 1)
public void onToggleRightClick(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
event.setCancelled(true);
if (trait == null)

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -336,9 +337,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : tracker.trackedPlayers) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -357,9 +358,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : tracker.trackedPlayers) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -362,9 +363,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : tracker.trackedPlayers) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -383,9 +384,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : tracker.trackedPlayers) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -424,9 +425,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : linked) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(linked)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -439,9 +440,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : linked) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(linked)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -448,9 +449,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : linked) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(linked)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -464,9 +465,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (ServerPlayerConnection link : linked) {
unlink(link.getPlayer().getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (ServerPlayerConnection link : Lists.newArrayList(linked)) {
Player entity = link.getPlayer().getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -14,6 +14,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -468,9 +469,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (ServerPlayerConnection link : linked) {
unlink(link.getPlayer().getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (ServerPlayerConnection link : Lists.newArrayList(linked)) {
Player entity = link.getPlayer().getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -14,6 +14,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
@ -488,9 +489,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (ServerPlayerConnection link : linked) {
unlink(link.getPlayer().getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (ServerPlayerConnection link : Lists.newArrayList(linked)) {
Player entity = link.getPlayer().getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -319,9 +320,11 @@ public class NMSImpl implements NMSBridge {
}
@Override
public void remove() {
for (EntityPlayer link : tracker.trackedPlayers) {
unlink(link.getBukkitEntity());
public void unlinkAll(Consumer<Player> callback) {
for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) {
Player entity = link.getBukkitEntity();
unlink(entity);
callback.accept(entity);
}
}