Make idle behaviour work with NPC class

This commit is contained in:
Jordan Irwin 2024-06-22 02:41:28 -07:00
parent 6653634128
commit 757eb04038
No known key found for this signature in database
GPG key ID: E3E358C2F44C290A
9 changed files with 60 additions and 51 deletions

View file

@ -45,7 +45,6 @@ import games.stendhal.server.entity.creature.impl.attack.AttackStrategy;
import games.stendhal.server.entity.creature.impl.attack.AttackStrategyFactory;
import games.stendhal.server.entity.creature.impl.heal.HealerBehavior;
import games.stendhal.server.entity.creature.impl.heal.HealerBehaviourFactory;
import games.stendhal.server.entity.creature.impl.idle.IdleBehaviour;
import games.stendhal.server.entity.creature.impl.idle.IdleBehaviourFactory;
import games.stendhal.server.entity.item.Corpse;
import games.stendhal.server.entity.item.Item;
@ -129,7 +128,6 @@ public class Creature extends NPC {
private int respawnTime;
private Map<String, String> aiProfiles;
private IdleBehaviour idler;
private int targetX;
@ -137,8 +135,6 @@ public class Creature extends NPC {
private final int attackTurn = Rand.rand(5);
private boolean isIdle = true;
/** The type of the damage this creature does */
private Nature damageType = Nature.CUT;
/** The type of the damage this creature does in ranged attacks */
@ -1193,20 +1189,4 @@ public class Creature extends NPC {
}
return getZone() == player.getZone();
}
@Override
protected void handleSimpleCollision(final int nx, final int ny) {
if (isIdle && idler != null && idler.handleSimpleCollision(this, nx, ny)) {
return;
}
super.handleSimpleCollision(nx, ny);
}
@Override
protected void handleObjectCollision() {
if (isIdle && idler != null && idler.handleObjectCollision(this)) {
return;
}
super.handleObjectCollision();
}
}

View file

@ -11,16 +11,16 @@
***************************************************************************/
package games.stendhal.server.entity.creature.impl.idle;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.npc.NPC;
public abstract class AbstractIdleBehaviour implements IdleBehaviour {
@Override
public abstract void perform(Creature creature);
public abstract void perform(NPC npc);
@Override
public void onMoved(Creature creature) {
public void onMoved(NPC npc) {
// does nothing in this implementation
}
@ -30,12 +30,12 @@ public abstract class AbstractIdleBehaviour implements IdleBehaviour {
}
@Override
public boolean handleSimpleCollision(Creature creature, int nx, int ny) {
public boolean handleSimpleCollision(NPC npc, int nx, int ny) {
return false;
}
@Override
public boolean handleObjectCollision(Creature creature) {
public boolean handleObjectCollision(NPC npc) {
return false;
}
}

View file

@ -10,7 +10,8 @@
***************************************************************************/
package games.stendhal.server.entity.creature.impl.idle;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.npc.NPC;
/**
* An idle behaviour, where the idling creature stays invisible
@ -22,7 +23,7 @@ class CamouflagedIdleBehaviour extends AbstractIdleBehaviour {
private final IdleBehaviour base = new Patroller();
@Override
public void perform(Creature creature) {
public void perform(NPC creature) {
creature.setVisibility(50);
this.base.perform(creature);
}

View file

@ -1,6 +1,6 @@
/* $Id$ */
/***************************************************************************
* (C) Copyright 2003-2010 - Stendhal *
* (C) Copyright 2003-2024 - Stendhal *
***************************************************************************
***************************************************************************
* *
@ -12,20 +12,20 @@
***************************************************************************/
package games.stendhal.server.entity.creature.impl.idle;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.npc.NPC;
public interface IdleBehaviour {
void perform(Creature creature);
void perform(NPC npc);
/**
* Called when entity's position has changed.
*
* @param creature
* @param npc
* Moving entity.
*/
void onMoved(Creature creature);
void onMoved(NPC npc);
/**
* There may be need to reset certain attributes.
@ -35,7 +35,7 @@ public interface IdleBehaviour {
/**
* Can be called to execute tile collision behavior.
*
* @param creature
* @param npc
* Entity being acted on.
* @param nx
* Horizontal position where entity collides.
@ -44,15 +44,15 @@ public interface IdleBehaviour {
* @return
* {@code true} if collision handling should not propagate.
*/
boolean handleSimpleCollision(Creature creature, int nx, int ny);
boolean handleSimpleCollision(NPC npc, int nx, int ny);
/**
* Can be called to execute entity collision behavior.
*
* @param creature
* @param npc
* Entity being acted on.
* @return
* {@code true} if collision handling should not propagate.
*/
boolean handleObjectCollision(Creature creature);
boolean handleObjectCollision(NPC npc);
}

View file

@ -1,6 +1,6 @@
/* $Id$ */
/***************************************************************************
* (C) Copyright 2003-2012 - Stendhal *
* (C) Copyright 2003-2024 - Stendhal *
***************************************************************************
***************************************************************************
* *
@ -13,7 +13,7 @@
package games.stendhal.server.entity.creature.impl.idle;
import games.stendhal.common.Direction;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.npc.NPC;
class Patroller extends StandOnIdle {
private int minX;
@ -26,7 +26,7 @@ class Patroller extends StandOnIdle {
*
* @param creature
*/
private void initArea(final Creature creature) {
private void initArea(final NPC creature) {
minX = creature.getX() - 3;
maxX = creature.getX() + 2 + (int) (creature.getWidth());
minY = creature.getY() - 3;
@ -34,7 +34,7 @@ class Patroller extends StandOnIdle {
}
@Override
public void perform(final Creature creature) {
public void perform(final NPC creature) {
if (!creature.getZone().getPlayerAndFriends().isEmpty()) {
if (creature.hasPath()) {
creature.followPath();
@ -86,7 +86,7 @@ class Patroller extends StandOnIdle {
* @return <code>true</code> if the creature would leave the area,
* <code>false</code> otherwise
*/
private boolean weWouldLeaveArea(final Creature creature, final Direction d) {
private boolean weWouldLeaveArea(final NPC creature, final Direction d) {
return (creature.getY() + d.getdy() < minY)
|| (creature.getY() + d.getdy() > maxY)
|| (creature.getX() + d.getdx() < minX)

View file

@ -1,6 +1,6 @@
/* $Id$ */
/***************************************************************************
* (C) Copyright 2003-2010 - Stendhal *
* (C) Copyright 2003-2024 - Stendhal *
***************************************************************************
***************************************************************************
* *
@ -15,11 +15,12 @@ package games.stendhal.server.entity.creature.impl.idle;
import games.stendhal.common.Rand;
import games.stendhal.server.entity.Entity;
import games.stendhal.server.entity.RPEntity;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.npc.NPC;
public class StandOnIdle extends AbstractIdleBehaviour {
@Override
public void perform(final Creature creature) {
public void perform(final NPC creature) {
retreatUnderFire(creature);
}
@ -29,7 +30,7 @@ public class StandOnIdle extends AbstractIdleBehaviour {
* @param creature The creature that should try to retreat.
* @return <code>true</code> if trying to escape, <code>false</code> if retreatin is not needed
*/
protected boolean retreatUnderFire(final Creature creature) {
protected boolean retreatUnderFire(final NPC creature) {
for (RPEntity attacker : creature.getAttackingRPEntities()) {
if (attacker.canDoRangeAttack(creature, attacker.getMaxRangeForArcher())) {
retreat(creature, attacker);
@ -49,7 +50,7 @@ public class StandOnIdle extends AbstractIdleBehaviour {
* @param creature The creature that tries to retreat.
* @param enemy The enemy to run away from.
*/
private void retreat(final Creature creature, final Entity enemy) {
private void retreat(final NPC creature, final Entity enemy) {
creature.clearPath();
creature.faceToward(enemy);
creature.setDirection(creature.getDirection().oppositeDirection());

View file

@ -13,7 +13,6 @@ package games.stendhal.server.entity.creature.impl.idle;
import games.stendhal.common.Direction;
import games.stendhal.common.Rand;
import games.stendhal.server.entity.creature.Creature;
import games.stendhal.server.entity.npc.NPC;
@ -62,7 +61,7 @@ public class WanderIdleBehaviour extends StandOnIdle {
}
@Override
public void perform(final Creature npc) {
public void perform(final NPC npc) {
// FIXME: this check should be done in entity logic
if (!npc.getZone().getPlayerAndFriends().isEmpty()) {
if (npc.hasPath()) {
@ -186,7 +185,7 @@ public class WanderIdleBehaviour extends StandOnIdle {
}
@Override
public void onMoved(Creature npc) {
public void onMoved(NPC npc) {
if (stopQueued) {
npc.stop();
npc.applyMovement();
@ -199,12 +198,12 @@ public class WanderIdleBehaviour extends StandOnIdle {
}
@Override
public boolean handleSimpleCollision(final Creature npc, final int nx, final int ny) {
public boolean handleSimpleCollision(final NPC npc, final int nx, final int ny) {
return handleObjectCollision(npc);
}
@Override
public boolean handleObjectCollision(final Creature npc) {
public boolean handleObjectCollision(final NPC npc) {
changeDirection(npc);
return true;
}

View file

@ -29,6 +29,7 @@ import games.stendhal.server.core.pathfinder.Node;
import games.stendhal.server.core.pathfinder.Path;
import games.stendhal.server.entity.DressedEntity;
import games.stendhal.server.entity.Entity;
import games.stendhal.server.entity.creature.impl.idle.IdleBehaviour;
import games.stendhal.server.entity.item.Corpse;
import games.stendhal.server.events.SoundEvent;
import marauroa.common.game.Definition;
@ -81,6 +82,11 @@ public abstract class NPC extends DressedEntity {
/** The time stamp of previous sound event. */
private long lastSoundTime;
protected IdleBehaviour idler;
// considered idle by default
protected boolean isIdle = true;
public static void generateRPClass() {
try {
final RPClass npc = new RPClass("npc");
@ -409,4 +415,20 @@ public abstract class NPC extends DressedEntity {
}
setDirection(newDir);
}
@Override
protected void handleSimpleCollision(final int nx, final int ny) {
if (isIdle && idler != null && idler.handleSimpleCollision(this, nx, ny)) {
return;
}
super.handleSimpleCollision(nx, ny);
}
@Override
protected void handleObjectCollision() {
if (isIdle && idler != null && idler.handleObjectCollision(this)) {
return;
}
super.handleObjectCollision();
}
}

View file

@ -130,6 +130,9 @@ public abstract class PassiveNPC extends NPC {
@Override
protected void handleObjectCollision() {
if (isIdle && idler != null && idler.handleObjectCollision(this)) {
return;
}
if (pathIsBlocked()) {
stop();
return;
@ -150,6 +153,9 @@ public abstract class PassiveNPC extends NPC {
@Override
protected void handleSimpleCollision(final int nx, final int ny) {
if (isIdle && idler != null && idler.handleSimpleCollision(this, nx, ny)) {
return;
}
CollisionAction action = getCollisionAction();
if (!ignoresCollision()) {
if (usesRandomPath()) {