v2.5.0: further fixes to sleeping AI, and compensation balance tweaks:

- shadow clone now benefits from silent steps
- flying characters are now stealthy, do not wake distant sleepers
This commit is contained in:
Evan Debenham
2024-09-03 11:40:49 -04:00
parent 7d77431534
commit 49af7826ef
2 changed files with 23 additions and 10 deletions

View File

@@ -254,7 +254,7 @@ actors.buffs.invulnerability.name=invulnerable
actors.buffs.invulnerability.desc=You are suffuse with great protective power, granting you a brief period of invulnerability!\n\nTurns remaining: %s.
actors.buffs.levitation.name=levitating
actors.buffs.levitation.desc=A magical force is levitating you over the ground, making you feel weightless.\n\nLevitating characters ignore all ground-based effects. Traps won't trigger, water won't put out fire, plants won't be trampled, roots will miss, and pits will be hovered over. Be careful, as all these things can come into effect the second the levitation ends!\n\nTurns of levitation remaining: %s.
actors.buffs.levitation.desc=A magical force is levitating you over the ground, making you feel weightless.\n\nLevitating characters move silently and ignore all ground-based effects. Traps won't trigger, water won't put out fire, plants won't be trampled, roots will miss, and pits will be hovered over. Be careful, as all these things can come into effect the second the levitation ends!\n\nTurns of levitation remaining: %s.
actors.buffs.lifelink.name=life link
actors.buffs.lifelink.desc=This character's life force is linked to another character nearby. Any damage taken is shared between them.\n\nWhenever this character takes damage, half of it will be dealt to the life link target instead.\n\nTurns of life link remaining: %s, or until the linked character dies.

View File

@@ -51,6 +51,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.Feint;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.ShadowClone;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.DirectableAlly;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
@@ -293,9 +294,6 @@ public abstract class Mob extends Char {
//We are charmed and current enemy is what charmed us
} else if (buff(Charm.class) != null && buff(Charm.class).object == enemy.id()) {
newEnemy = true;
//We are sleeping (rather than preferring existing target, we want to see if anything is closer
} else if (state == SLEEPING){
newEnemy = true;
}
//additionally, if we are an ally, find a new enemy if...
@@ -1031,17 +1029,32 @@ public abstract class Mob extends Char {
}
}
if (enemyInFOV) {
//can be awoken by the least stealthy hostile present, not necessarily just our target
if (enemyInFOV || (enemy != null && enemy.invisible > 0)) {
float enemyStealth = enemy.stealth();
float closestHostileDist = Float.POSITIVE_INFINITY;
if (enemy instanceof Hero && ((Hero) enemy).hasTalent(Talent.SILENT_STEPS)){
if (Dungeon.level.distance(pos, enemy.pos) >= 4 - ((Hero) enemy).pointsInTalent(Talent.SILENT_STEPS)) {
enemyStealth = Float.POSITIVE_INFINITY;
for (Char ch : Actor.chars()){
if (fieldOfView[ch.pos] && ch.invisible == 0 && ch.alignment != alignment && ch.alignment != Alignment.NEUTRAL){
float chDist = ch.stealth() + distance(ch);
//silent steps rogue talent, which also applies to rogue's shadow clone
if ((ch instanceof Hero || ch instanceof ShadowClone.ShadowAlly)
&& Dungeon.hero.hasTalent(Talent.SILENT_STEPS)){
if (distance(ch) >= 4 - Dungeon.hero.pointsInTalent(Talent.SILENT_STEPS)) {
chDist = Float.POSITIVE_INFINITY;
}
}
//flying characters are naturally stealthy
if (ch.flying && distance(ch) >= 2){
chDist = Float.POSITIVE_INFINITY;
}
if (chDist < closestHostileDist){
closestHostileDist = chDist;
}
}
}
if (Random.Float( distance( enemy ) + enemyStealth ) < 1) {
if (Random.Float( closestHostileDist ) < 1) {
awaken(enemyInFOV);
if (state == SLEEPING){
spend(TICK); //wait if we can't wake up for some reason