Fixed an issue causing a build up of pulses when regions are unloaded and npcs are still navigating back to their spawns

This commit is contained in:
Ceikry 2023-08-03 13:26:40 +00:00 committed by Ryan
parent 255fc9eca6
commit 4098f2bf0b
2 changed files with 51 additions and 2 deletions

View file

@ -462,7 +462,8 @@ public class NPC extends Entity {
getLocks().lockMovement(100); getLocks().lockMovement(100);
getImpactHandler().setDisabledTicks(100); getImpactHandler().setDisabledTicks(100);
setAttribute("return-to-spawn", true); setAttribute("return-to-spawn", true);
GameWorld.getPulser().submit(new MovementPulse(this, getProperties().getSpawnLocation(), Pathfinder.SMART) {
MovementPulse returnPulse = new MovementPulse(this, getProperties().getSpawnLocation(), Pathfinder.SMART) {
@Override @Override
public boolean pulse() { public boolean pulse() {
getProperties().getCombatPulse().stop(); getProperties().getCombatPulse().stop();
@ -470,9 +471,13 @@ public class NPC extends Entity {
fullRestore(); fullRestore();
getImpactHandler().setDisabledTicks(0); getImpactHandler().setDisabledTicks(0);
removeAttribute("return-to-spawn"); removeAttribute("return-to-spawn");
removeAttribute("return-to-spawn-pulse");
return true; return true;
} }
}); };
setAttribute("return-to-spawn-pulse", returnPulse);
GameWorld.getPulser().submit(returnPulse);
return; return;
} }
if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) { if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) {
@ -528,6 +533,14 @@ public class NPC extends Entity {
getWalkingQueue().reset(); getWalkingQueue().reset();
getPulseManager().clear(); getPulseManager().clear();
getUpdateMasks().reset(); getUpdateMasks().reset();
if (getAttribute("return-to-spawn", false)) {
this.location = getProperties().getSpawnLocation();
MovementPulse returnPulse = getAttribute("return-to-spawn-pulse");
if (returnPulse != null) {
returnPulse.pulse();
returnPulse.stop();
}
}
Repository.removeRenderableNPC(this); Repository.removeRenderableNPC(this);
if (getViewport().getRegion() instanceof DynamicRegion) { if (getViewport().getRegion() instanceof DynamicRegion) {
clear(); clear();

View file

@ -16,6 +16,7 @@ import core.game.node.entity.impl.PulseType
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.world.GameWorld import core.game.world.GameWorld
import core.game.world.map.Region
import core.net.packet.PacketProcessor import core.net.packet.PacketProcessor
import core.plugin.ClassScanner import core.plugin.ClassScanner
import core.plugin.Plugin import core.plugin.Plugin
@ -221,4 +222,39 @@ class PathfinderTests {
Assertions.assertEquals(1.0, p.location.getDistance(npc.location)) Assertions.assertEquals(1.0, p.location.getDistance(npc.location))
} }
} }
@Test fun npcShouldReliablyReturnToSpawnLocationIfTooFar() {
//spawn a player into the area just to make sure it ticks...
TestUtils.getMockPlayer("areatest").use { p ->
val npc = NPC(1, Location.create(3240, 3226, 0))
npc.isWalks = true
npc.isNeverWalks = false
npc.walkRadius = 5
npc.init()
npc.properties.spawnLocation = ServerConstants.HOME_LOCATION
TestUtils.advanceTicks(5, false)
Assertions.assertEquals(true, npc.getAttribute("return-to-spawn", false))
TestUtils.advanceTicks(50, false)
Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION) <= 9)
}
}
@Test fun npcShouldReliablyReturnToSpawnEvenIfRegionUnloaded() {
//spawn a player into the area just to make sure it ticks...
TestUtils.getMockPlayer("areaunloadtest").use { p ->
val npc = NPC(1, Location.create(3240, 3226, 0))
npc.isWalks = true
npc.isNeverWalks = false
npc.walkRadius = 5
npc.init()
npc.properties.spawnLocation = ServerConstants.HOME_LOCATION
TestUtils.advanceTicks(3, false)
Assertions.assertEquals(true, npc.getAttribute("return-to-spawn", false))
p.clear()
RegionManager.forId(npc.location.regionId).flagInactive(true)
TestUtils.advanceTicks(50, false)
Assertions.assertEquals(false, npc.getAttribute("return-to-spawn", false))
Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION) <= 5)
}
}
} }