v1.3.0: improved death tracking logic in a few cases

This commit is contained in:
Evan Debenham
2022-05-24 13:15:50 -04:00
parent 8d8783d172
commit 8ce4b87f13
12 changed files with 64 additions and 23 deletions
@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors; package com.shatteredpixel.shatteredpixeldungeon.actors;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
@@ -72,6 +73,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.DeathMark; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.DeathMark;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Endure; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Endure;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.MirrorImage;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.PrismaticImage;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Potential; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Potential;
@@ -85,6 +88,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFireblast; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFireblast;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFrost; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFrost;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLightning; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLightning;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLivingEarth;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blocking; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blocking;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim;
@@ -411,6 +415,10 @@ public abstract class Char extends Actor {
return true; return true;
} }
if (this instanceof WandOfLivingEarth.EarthGuardian
|| this instanceof MirrorImage || this instanceof PrismaticImage){
Badges.validateDeathFromFriendlyMagic();
}
Dungeon.fail( getClass() ); Dungeon.fail( getClass() );
GLog.n( Messages.capitalize(Messages.get(Char.class, "kill", name())) ); GLog.n( Messages.capitalize(Messages.get(Char.class, "kill", name())) );
@@ -36,12 +36,16 @@ public class CorrosiveGas extends Blob {
//FIXME should have strength per-cell //FIXME should have strength per-cell
private int strength = 0; private int strength = 0;
//used in specific cases where the source of the corrosion is important for death logic
private Class source;
@Override @Override
protected void evolve() { protected void evolve() {
super.evolve(); super.evolve();
if (volume == 0){ if (volume == 0){
strength = 0; strength = 0;
source = null;
} else { } else {
Char ch; Char ch;
int cell; int cell;
@@ -59,24 +63,32 @@ public class CorrosiveGas extends Blob {
} }
public CorrosiveGas setStrength(int str){ public CorrosiveGas setStrength(int str){
return setStrength(str, null);
}
public CorrosiveGas setStrength(int str, Class source){
if (str > strength) { if (str > strength) {
strength = str; strength = str;
this.source = source;
} }
return this; return this;
} }
private static final String STRENGTH = "strength"; private static final String STRENGTH = "strength";
private static final String SOURCE = "source";
@Override @Override
public void restoreFromBundle(Bundle bundle) { public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle); super.restoreFromBundle(bundle);
strength = bundle.getInt( STRENGTH ); strength = bundle.getInt( STRENGTH );
source = bundle.getClass( SOURCE );
} }
@Override @Override
public void storeInBundle(Bundle bundle) { public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle); super.storeInBundle(bundle);
bundle.put( STRENGTH, strength ); bundle.put( STRENGTH, strength );
bundle.put( SOURCE, source );
} }
@Override @Override
@@ -345,7 +345,7 @@ public class Combo extends Buff implements ActionIndicator.Action {
dist--; dist--;
} }
} }
WandOfBlastWave.throwChar(enemy, trajectory, dist, true, false); WandOfBlastWave.throwChar(enemy, trajectory, dist, true, false, hero.getClass());
break; break;
case PARRY: case PARRY:
hit(enemy); hit(enemy);
@@ -21,8 +21,10 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfCorrosion;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
@@ -34,8 +36,12 @@ public class Corrosion extends Buff implements Hero.Doom {
private float damage = 1; private float damage = 1;
protected float left; protected float left;
//used in specific cases where the source of the corrosion is important for death logic
private Class source;
private static final String DAMAGE = "damage"; private static final String DAMAGE = "damage";
private static final String LEFT = "left"; private static final String LEFT = "left";
private static final String SOURCE = "source";
{ {
type = buffType.NEGATIVE; type = buffType.NEGATIVE;
@@ -47,6 +53,7 @@ public class Corrosion extends Buff implements Hero.Doom {
super.storeInBundle( bundle ); super.storeInBundle( bundle );
bundle.put( DAMAGE, damage ); bundle.put( DAMAGE, damage );
bundle.put( LEFT, left ); bundle.put( LEFT, left );
bundle.put( SOURCE, source);
} }
@Override @Override
@@ -54,11 +61,17 @@ public class Corrosion extends Buff implements Hero.Doom {
super.restoreFromBundle( bundle ); super.restoreFromBundle( bundle );
damage = bundle.getFloat( DAMAGE ); damage = bundle.getFloat( DAMAGE );
left = bundle.getFloat( LEFT ); left = bundle.getFloat( LEFT );
source = bundle.getClass( SOURCE );
} }
public void set(float duration, int damage) { public void set(float duration, int damage){
set(duration, damage, null);
}
public void set(float duration, int damage, Class source) {
this.left = Math.max(duration, left); this.left = Math.max(duration, left);
if (this.damage < damage) this.damage = damage; if (this.damage < damage) this.damage = damage;
this.source = source;
} }
@Override @Override
@@ -114,6 +127,10 @@ public class Corrosion extends Buff implements Hero.Doom {
@Override @Override
public void onDeath() { public void onDeath() {
if (source == WandOfCorrosion.class){
Badges.validateDeathFromFriendlyMagic();
}
Dungeon.fail( getClass() ); Dungeon.fail( getClass() );
GLog.n(Messages.get(this, "ondeath")); GLog.n(Messages.get(this, "ondeath"));
} }
@@ -293,7 +293,9 @@ public class ElementalBlast extends ArmorAbility {
WandOfBlastWave.throwChar(mob, WandOfBlastWave.throwChar(mob,
new Ballistica(mob.pos, aim.collisionPos, Ballistica.MAGIC_BOLT), new Ballistica(mob.pos, aim.collisionPos, Ballistica.MAGIC_BOLT),
knockback, knockback,
true); true,
true,
ElementalBlast.this.getClass());
} }
//*** Wand of Frost *** //*** Wand of Frost ***
@@ -102,7 +102,7 @@ public class HeroicLeap extends ArmorAbility {
if (mob.pos == hero.pos + i && hero.hasTalent(Talent.IMPACT_WAVE)){ if (mob.pos == hero.pos + i && hero.hasTalent(Talent.IMPACT_WAVE)){
Ballistica trajectory = new Ballistica(mob.pos, mob.pos + i, Ballistica.MAGIC_BOLT); Ballistica trajectory = new Ballistica(mob.pos, mob.pos + i, Ballistica.MAGIC_BOLT);
int strength = 1+hero.pointsInTalent(Talent.IMPACT_WAVE); int strength = 1+hero.pointsInTalent(Talent.IMPACT_WAVE);
WandOfBlastWave.throwChar(mob, trajectory, strength, true); WandOfBlastWave.throwChar(mob, trajectory, strength, true, true, HeroicLeap.this.getClass());
if (Random.Int(4) < hero.pointsInTalent(Talent.IMPACT_WAVE)){ if (Random.Int(4) < hero.pointsInTalent(Talent.IMPACT_WAVE)){
Buff.prolong(mob, Vulnerable.class, 3f); Buff.prolong(mob, Vulnerable.class, 3f);
} }
@@ -406,7 +406,7 @@ public class DM300 extends Mob {
if (Dungeon.level.adjacent(pos, target.pos)){ if (Dungeon.level.adjacent(pos, target.pos)){
int oppositeAdjacent = target.pos + (target.pos - pos); int oppositeAdjacent = target.pos + (target.pos - pos);
Ballistica trajectory = new Ballistica(target.pos, oppositeAdjacent, Ballistica.MAGIC_BOLT); Ballistica trajectory = new Ballistica(target.pos, oppositeAdjacent, Ballistica.MAGIC_BOLT);
WandOfBlastWave.throwChar(target, trajectory, 2, false, false); WandOfBlastWave.throwChar(target, trajectory, 2, false, false, getClass());
if (target == Dungeon.hero){ if (target == Dungeon.hero){
Dungeon.hero.interrupt(); Dungeon.hero.interrupt();
} }
@@ -42,7 +42,7 @@ public class Repulsion extends Armor.Glyph {
if (Random.Int( level + 5 ) >= 4){ if (Random.Int( level + 5 ) >= 4){
int oppositeHero = attacker.pos + (attacker.pos - defender.pos); int oppositeHero = attacker.pos + (attacker.pos - defender.pos);
Ballistica trajectory = new Ballistica(attacker.pos, oppositeHero, Ballistica.MAGIC_BOLT); Ballistica trajectory = new Ballistica(attacker.pos, oppositeHero, Ballistica.MAGIC_BOLT);
WandOfBlastWave.throwChar(attacker, trajectory, 2, true); WandOfBlastWave.throwChar(attacker, trajectory, 2, true, true, getClass());
} }
return damage; return damage;
@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.items.wands; package com.shatteredpixel.shatteredpixeldungeon.items.wands;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -85,7 +86,7 @@ public class WandOfBlastWave extends DamageWand {
if (ch.pos == bolt.collisionPos + i) { if (ch.pos == bolt.collisionPos + i) {
Ballistica trajectory = new Ballistica(ch.pos, ch.pos + i, Ballistica.MAGIC_BOLT); Ballistica trajectory = new Ballistica(ch.pos, ch.pos + i, Ballistica.MAGIC_BOLT);
int strength = 1 + Math.round(buffedLvl() / 2f); int strength = 1 + Math.round(buffedLvl() / 2f);
throwChar(ch, trajectory, strength, false); throwChar(ch, trajectory, strength, false, true, getClass());
} }
} }
@@ -100,23 +101,14 @@ public class WandOfBlastWave extends DamageWand {
if (bolt.path.size() > bolt.dist+1 && ch.pos == bolt.collisionPos) { if (bolt.path.size() > bolt.dist+1 && ch.pos == bolt.collisionPos) {
Ballistica trajectory = new Ballistica(ch.pos, bolt.path.get(bolt.dist + 1), Ballistica.MAGIC_BOLT); Ballistica trajectory = new Ballistica(ch.pos, bolt.path.get(bolt.dist + 1), Ballistica.MAGIC_BOLT);
int strength = buffedLvl() + 3; int strength = buffedLvl() + 3;
throwChar(ch, trajectory, strength, false); throwChar(ch, trajectory, strength, false, true, getClass());
} }
} }
} }
public static void throwChar(final Char ch, final Ballistica trajectory, int power){
throwChar(ch, trajectory, power, true);
}
public static void throwChar(final Char ch, final Ballistica trajectory, int power, public static void throwChar(final Char ch, final Ballistica trajectory, int power,
boolean closeDoors) { boolean closeDoors, boolean collideDmg, Class cause){
throwChar(ch, trajectory, power, closeDoors, true);
}
public static void throwChar(final Char ch, final Ballistica trajectory, int power,
boolean closeDoors, boolean collideDmg){
if (ch.properties().contains(Char.Property.BOSS)) { if (ch.properties().contains(Char.Property.BOSS)) {
power /= 2; power /= 2;
} }
@@ -167,13 +159,18 @@ public class WandOfBlastWave extends DamageWand {
if (finalCollided && ch.isAlive()) { if (finalCollided && ch.isAlive()) {
ch.damage(Random.NormalIntRange(finalDist, 2*finalDist), this); ch.damage(Random.NormalIntRange(finalDist, 2*finalDist), this);
Paralysis.prolong(ch, Paralysis.class, 1 + finalDist/2f); Paralysis.prolong(ch, Paralysis.class, 1 + finalDist/2f);
if (ch == Dungeon.hero && !ch.isAlive()){
if ( cause == WandOfBlastWave.class){
Badges.validateDeathFromFriendlyMagic();
}
Dungeon.fail(cause);
}
} }
if (closeDoors && Dungeon.level.map[oldPos] == Terrain.OPEN_DOOR){ if (closeDoors && Dungeon.level.map[oldPos] == Terrain.OPEN_DOOR){
Door.leave(oldPos); Door.leave(oldPos);
} }
Dungeon.level.occupyCell(ch); Dungeon.level.occupyCell(ch);
if (ch == Dungeon.hero){ if (ch == Dungeon.hero){
//FIXME currently no logic here if the throw effect kills the hero
Dungeon.observe(); Dungeon.observe();
} }
} }
@@ -58,7 +58,7 @@ public class WandOfCorrosion extends Wand {
public void onZap(Ballistica bolt) { public void onZap(Ballistica bolt) {
CorrosiveGas gas = Blob.seed(bolt.collisionPos, 50 + 10 * buffedLvl(), CorrosiveGas.class); CorrosiveGas gas = Blob.seed(bolt.collisionPos, 50 + 10 * buffedLvl(), CorrosiveGas.class);
CellEmitter.get(bolt.collisionPos).burst(Speck.factory(Speck.CORROSION), 10 ); CellEmitter.get(bolt.collisionPos).burst(Speck.factory(Speck.CORROSION), 10 );
gas.setStrength(2 + buffedLvl()); gas.setStrength(2 + buffedLvl(), getClass());
GameScene.add(gas); GameScene.add(gas);
Sample.INSTANCE.play(Assets.Sounds.GAS); Sample.INSTANCE.play(Assets.Sounds.GAS);
@@ -48,7 +48,12 @@ public class Elastic extends Weapon.Enchantment {
//trim it to just be the part that goes past them //trim it to just be the part that goes past them
trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size()-1), Ballistica.PROJECTILE); trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size()-1), Ballistica.PROJECTILE);
//knock them back along that ballistica //knock them back along that ballistica
WandOfBlastWave.throwChar(defender, trajectory, 2, !(weapon instanceof MissileWeapon || weapon instanceof SpiritBow)); WandOfBlastWave.throwChar(defender,
trajectory,
2,
!(weapon instanceof MissileWeapon || weapon instanceof SpiritBow),
true,
getClass());
} }
return damage; return damage;
@@ -76,7 +76,7 @@ public class GeyserTrap extends Trap {
//trim it to just be the part that goes past them //trim it to just be the part that goes past them
trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size()-1), Ballistica.PROJECTILE); trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size()-1), Ballistica.PROJECTILE);
//knock them back along that ballistica //knock them back along that ballistica
WandOfBlastWave.throwChar(ch, trajectory, 2, true); WandOfBlastWave.throwChar(ch, trajectory, 2, true, true, getClass());
} }
} }
@@ -105,7 +105,7 @@ public class GeyserTrap extends Trap {
//trace a ballistica in the direction of our target //trace a ballistica in the direction of our target
Ballistica trajectory = new Ballistica(pos, targetpos, Ballistica.MAGIC_BOLT); Ballistica trajectory = new Ballistica(pos, targetpos, Ballistica.MAGIC_BOLT);
//knock them back along that ballistica //knock them back along that ballistica
WandOfBlastWave.throwChar(ch, trajectory, 2, true); WandOfBlastWave.throwChar(ch, trajectory, 2, true, true, getClass());
} }
} }
} }