Fixed a bug where an NPC could not attack an entity that was already set as their target

Fixed a regression that prevents some NPCs from walking back to their spawn point
Fixed a longstanding issue that didn't properly reset NPCs who wandered too far out of their natural movement radius (now disables combat + walks them back to their spawn point + fully heals them)
This commit is contained in:
Ceikry
2022-07-02 07:48:46 +00:00
committed by Ryan
parent c23c7d0617
commit 6dd30896f0
4 changed files with 61 additions and 32 deletions
@@ -412,7 +412,13 @@ public class NPC extends Entity {
*/ */
public void handleTickActions() { public void handleTickActions() {
if (!getLocks().isInteractionLocked()) { if (!getLocks().isInteractionLocked()) {
if (!pathBoundMovement && walkRadius > 0 && !getLocation().withinDistance(getProperties().getSpawnLocation(), walkRadius)) { if (!getLocks().isMovementLocked()) {
if (
!pathBoundMovement
&& walkRadius > 0
&& !getLocation().withinDistance(getProperties().getSpawnLocation(), (int)(walkRadius * 1.5))
)
{
if(!isNeverWalks()){ if(!isNeverWalks()){
if(walkRadius == 0) if(walkRadius == 0)
walkRadius = 3; walkRadius = 3;
@@ -420,6 +426,29 @@ public class NPC extends Entity {
if (aggressiveHandler != null) { if (aggressiveHandler != null) {
aggressiveHandler.setPauseTicks(walkRadius + 1); aggressiveHandler.setPauseTicks(walkRadius + 1);
} }
nextWalk = GameWorld.getTicks() + walkRadius + 1;
getLocks().lockMovement(100);
getImpactHandler().setDisabledTicks(100);
setAttribute("return-to-spawn", true);
GameWorld.getPulser().submit(new MovementPulse(this, getProperties().getSpawnLocation(), Pathfinder.SMART) {
@Override
public boolean pulse() {
getProperties().getCombatPulse().stop();
getLocks().unlockMovement();
fullRestore();
getImpactHandler().setDisabledTicks(0);
removeAttribute("return-to-spawn");
return true;
}
});
return;
}
if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) {
dialoguePlayer = null;
if (walks && !getPulseManager().hasPulseRunning() && !getProperties().getCombatPulse().isAttacking() && !getProperties().getCombatPulse().isInCombat() && nextWalk < GameWorld.getTicks()) {
if (walkToNextDest()) return;
}
}
} }
if (aggressive && aggressiveHandler != null && aggressiveHandler.selectTarget()) { if (aggressive && aggressiveHandler != null && aggressiveHandler.selectTarget()) {
return; return;
@@ -428,11 +457,14 @@ public class NPC extends Entity {
return; return;
} }
} }
if (!getLocks().isMovementLocked()) { if (forceTalk != null && getAttribute("lastForceTalk", 0) < GameWorld.getTicks()) {
if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) { sendChat(forceTalk);
dialoguePlayer = null; setAttribute("lastForceTalk", GameWorld.getTicks() + RandomFunction.random(15, 30));
if (walks && !getPulseManager().hasPulseRunning() && !getProperties().getCombatPulse().isAttacking() && !getProperties().getCombatPulse().isInCombat() && nextWalk < GameWorld.getTicks()) { }
if (RandomFunction.nextBool()) return; }
private boolean walkToNextDest() {
if (RandomFunction.nextBool()) return true;
setNextWalk(); setNextWalk();
Location l = getMovementDestination(); Location l = getMovementDestination();
if (canMove(l)) { if (canMove(l)) {
@@ -442,13 +474,7 @@ public class NPC extends Entity {
Pathfinder.find(this, l, true, Pathfinder.DUMB).walk(this); Pathfinder.find(this, l, true, Pathfinder.DUMB).walk(this);
} }
} }
} return false;
}
}
if (forceTalk != null && getAttribute("lastForceTalk", 0) < GameWorld.getTicks()) {
sendChat(forceTalk);
setAttribute("lastForceTalk", GameWorld.getTicks() + RandomFunction.random(15, 30));
}
} }
/** /**
@@ -90,7 +90,6 @@ public final class AggressiveHandler {
} }
if (target != null) { if (target != null) {
target.setAttribute("aggressor", entity); target.setAttribute("aggressor", entity);
if (target != entity.getProperties().getCombatPulse().getVictim()) {
if (entity.getProperties().getCombatPulse().isAttacking()) { if (entity.getProperties().getCombatPulse().isAttacking()) {
entity.getProperties().getCombatPulse().setVictim(target); entity.getProperties().getCombatPulse().setVictim(target);
entity.face(target); entity.face(target);
@@ -99,7 +98,6 @@ public final class AggressiveHandler {
} }
return true; return true;
} }
}
return entity.getProperties().getCombatPulse().isAttacking(); return entity.getProperties().getCombatPulse().isAttacking();
} }
@@ -286,6 +286,7 @@ class CombatPulse(
victim.skills.updateLevel(Skills.DEFENCE, -drain, victim.skills.getStaticLevel(Skills.DEFENCE) - drain) victim.skills.updateLevel(Skills.DEFENCE, -drain, victim.skills.getStaticLevel(Skills.DEFENCE) - drain)
} }
} }
if (!victim.locks.isMovementLocked)
victim.walkingQueue.reset() victim.walkingQueue.reset()
} }
setVictim(victim) setVictim(victim)
@@ -210,6 +210,10 @@ abstract class CombatSwingHandler(var type: CombatStyle?) {
* @return `True` if so. * @return `True` if so.
*/ */
open fun isAttackable(entity: Entity, victim: Entity): InteractionType? { open fun isAttackable(entity: Entity, victim: Entity): InteractionType? {
if (victim.getAttribute("return-to-spawn", false)) {
return InteractionType.NO_INTERACT
}
if (type == CombatStyle.MELEE) { if (type == CombatStyle.MELEE) {
val stepType = canStepTowards(entity, victim) val stepType = canStepTowards(entity, victim)
if (stepType != InteractionType.STILL_INTERACT) return stepType if (stepType != InteractionType.STILL_INTERACT) return stepType