From 098ab9d772267cd73b4f41d7cb29b30d8e067ffb Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 4 Oct 2023 14:18:31 -0400 Subject: [PATCH] v2.2.0: fixed a variety of small bugs: - guardians 'dodging' instead of 'blocking' - guardians having defenseSkill while recovering - spire not finishing attacks if hero leaves vision range - beacon of returning allowing return to mining level - 'cash out' being repeatedly selectable --- .../assets/messages/actors/actors.properties | 1 + .../actors/mobs/CrystalGuardian.java | 6 + .../actors/mobs/CrystalSpire.java | 144 +++++++++--------- .../items/spells/BeaconOfReturning.java | 6 + .../windows/WndBlacksmith.java | 2 +- 5 files changed, 86 insertions(+), 73 deletions(-) diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index e2c08d993..494cc71a5 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -1112,6 +1112,7 @@ actors.mobs.crab.name=sewer crab actors.mobs.crab.desc=These huge crabs are at the top of the food chain in the sewers. They are extremely fast and their thick carapace can withstand heavy blows. actors.mobs.crystalguardian.name=crystal guardian +actors.mobs.crystalguardian.def_verb=blocked actors.mobs.crystalguardian.desc=These large crystalline guardians almost look like statues, if it weren't for their bright glowing eyes. The hardened crystal they're made out of causes them to be sluggish but very tough, so _it's best to leave them to sleep in their crystal nest for as long as possible._\n\nDue to their size, crystal guardians will move much more slowly in enclosed spaces. They're also so durable that they're impossible to kill outright. They can be beaten down and temporarily disabled, but they'll just get back up again after a little while. actors.mobs.crystalmimic.name=crystal mimic diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java index a1e2b918f..045bf330b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java @@ -89,6 +89,12 @@ public class CrystalGuardian extends Mob{ return 20; } + @Override + public int defenseSkill(Char enemy) { + if (recovering) return 0; + return super.defenseSkill(enemy); + } + @Override public int drRoll() { return super.drRoll() + Random.NormalIntRange(0, 10); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java index eff4bba80..9aee7d032 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java @@ -103,83 +103,83 @@ public class CrystalSpire extends Mob { enemySeen = enemy.isAlive() && fieldOfView[enemy.pos]; //end of char/mob logic + if (!targetedCells.isEmpty()){ + + ArrayList cellsToAttack = targetedCells.remove(0); + + for (int i : cellsToAttack){ + + Char ch = Actor.findChar(i); + if (ch instanceof CrystalSpire){ + continue; //don't spawn crystals on itself + } + + Level.set(i, Terrain.MINE_CRYSTAL); + GameScene.updateMap(i); + + Splash.at(i, 0xFFFFFF, 5); + } + + for (int i : cellsToAttack){ + Char ch = Actor.findChar(i); + + if (ch != null && !(ch instanceof CrystalWisp || ch instanceof CrystalSpire)){ + int dmg = Random.NormalIntRange(6, 15); + + //guardians are hit harder by the attack + if (ch instanceof CrystalGuardian) { + dmg += 12; //18-27 damage + Buff.prolong(ch, Cripple.class, 30f); + } + ch.damage(dmg, CrystalSpire.this); + + int movePos = i; + //crystal guardians get knocked away from the hero, others get knocked away from the spire + if (ch instanceof CrystalGuardian){ + for (int j : PathFinder.NEIGHBOURS8){ + if (!Dungeon.level.solid[i+j] && Actor.findChar(i+j) == null && + Dungeon.level.trueDistance(i+j, Dungeon.hero.pos) > Dungeon.level.trueDistance(movePos, Dungeon.hero.pos)){ + movePos = i+j; + } + } + } else if (!Char.hasProp(ch, Property.IMMOVABLE)) { + for (int j : PathFinder.NEIGHBOURS8){ + if (!Dungeon.level.solid[i+j] && Actor.findChar(i+j) == null && + Dungeon.level.trueDistance(i+j, pos) > Dungeon.level.trueDistance(movePos, pos)){ + movePos = i+j; + } + } + } + + if (ch.isAlive()){ + if (movePos != i){ + Actor.add(new Pushing(ch, i, movePos)); + ch.pos = movePos; + Dungeon.level.occupyCell(ch); + } + } else if (ch == Dungeon.hero){ + GLog.n( Messages.capitalize(Messages.get(Char.class, "kill", name())) ); + Dungeon.fail(this); + } + } + } + + PixelScene.shake( 1, 0.7f ); + Sample.INSTANCE.play( Assets.Sounds.SHATTER ); + + if (!targetedCells.isEmpty()){ + for (int i : targetedCells.get(0)){ + sprite.parent.add(new TargetedCell(i, 0xFF0000)); + } + } + + } + if (hits < 3 || !enemySeen){ spend(TICK); return true; } else { - if (!targetedCells.isEmpty()){ - - ArrayList cellsToAttack = targetedCells.remove(0); - - for (int i : cellsToAttack){ - - Char ch = Actor.findChar(i); - if (ch instanceof CrystalSpire){ - continue; //don't spawn crystals on itself - } - - Level.set(i, Terrain.MINE_CRYSTAL); - GameScene.updateMap(i); - - Splash.at(i, 0xFFFFFF, 5); - } - - for (int i : cellsToAttack){ - Char ch = Actor.findChar(i); - - if (ch != null && !(ch instanceof CrystalWisp || ch instanceof CrystalSpire)){ - int dmg = Random.NormalIntRange(6, 15); - - //guardians are hit harder by the attack - if (ch instanceof CrystalGuardian) { - dmg += 12; //18-27 damage - Buff.prolong(ch, Cripple.class, 30f); - } - ch.damage(dmg, CrystalSpire.this); - - int movePos = i; - //crystal guardians get knocked away from the hero, others get knocked away from the spire - if (ch instanceof CrystalGuardian){ - for (int j : PathFinder.NEIGHBOURS8){ - if (!Dungeon.level.solid[i+j] && Actor.findChar(i+j) == null && - Dungeon.level.trueDistance(i+j, Dungeon.hero.pos) > Dungeon.level.trueDistance(movePos, Dungeon.hero.pos)){ - movePos = i+j; - } - } - } else if (!Char.hasProp(ch, Property.IMMOVABLE)) { - for (int j : PathFinder.NEIGHBOURS8){ - if (!Dungeon.level.solid[i+j] && Actor.findChar(i+j) == null && - Dungeon.level.trueDistance(i+j, pos) > Dungeon.level.trueDistance(movePos, pos)){ - movePos = i+j; - } - } - } - - if (ch.isAlive()){ - if (movePos != i){ - Actor.add(new Pushing(ch, i, movePos)); - ch.pos = movePos; - Dungeon.level.occupyCell(ch); - } - } else if (ch == Dungeon.hero){ - GLog.n( Messages.capitalize(Messages.get(Char.class, "kill", name())) ); - Dungeon.fail(this); - } - } - } - - PixelScene.shake( 1, 0.7f ); - Sample.INSTANCE.play( Assets.Sounds.SHATTER ); - - if (!targetedCells.isEmpty()){ - for (int i : targetedCells.get(0)){ - sprite.parent.add(new TargetedCell(i, 0xFF0000)); - } - } - - } - if (abilityCooldown <= 0){ if (Random.Int(2) == 0) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java index b868e6ef6..e1eb56b69 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/BeaconOfReturning.java @@ -155,6 +155,12 @@ public class BeaconOfReturning extends Spell { return; } + //cannot return to mining level + if (returnDepth >= 11 && returnDepth <= 14 && returnBranch == 1){ + GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") ); + return; + } + Level.beforeTransition(); Invisibility.dispel(); InterlevelScene.mode = InterlevelScene.Mode.RETURN; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBlacksmith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBlacksmith.java index 83e0c249f..0768d889d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBlacksmith.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndBlacksmith.java @@ -144,7 +144,7 @@ public class WndBlacksmith extends Window { WndBlacksmith.this.hide(); } }; - cashOut.enable(true); + cashOut.enable(Blacksmith.Quest.favor > 0); buttons.add(cashOut); float pos = message.bottom() + 3*GAP;