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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -103,83 +103,83 @@ public class CrystalSpire extends Mob {
|
||||
enemySeen = enemy.isAlive() && fieldOfView[enemy.pos];
|
||||
//end of char/mob logic
|
||||
|
||||
if (!targetedCells.isEmpty()){
|
||||
|
||||
ArrayList<Integer> 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<Integer> 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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user