v0.9.3: adjusted Goo for bosses challenge:

Baseline changes:
- Pump up is now more restrictive in what it can target
- Pump up VFX are accurate to what tiles are targetable by Goo
Challenge changes:
- HP up to 120 from 100
- Pump up charges over 1 turn instead of 2
- Healing in water ramps up to 3/turn
This commit is contained in:
Evan Debenham 2021-04-02 16:46:52 -04:00
parent 575d3475e9
commit 252bcad4d3
3 changed files with 39 additions and 13 deletions

View File

@ -86,6 +86,6 @@ challenges.no_scrolls_desc=A certain rune is harder to find. Unfortunately, it's
challenges.champion_enemies=Hostile champions challenges.champion_enemies=Hostile champions
challenges.champion_enemies_desc=You're not the only one who can level up!\n\n- Regular enemies have a 1/8 chance to spawn with a special champion buff.\n- Champions wake up if they spawn asleep\n- The hero knows when a champion spawns\n- Champions are immune to corruption\n\nThere are six types of champion enemy:\n_Blazing (orange):_ +25% melee damage, ignites on hit, immune to fire, spreads flames on death\n_Projecting (purple):_ +25% melee damage, can attack anything they see\n_Antimagic (green):_ -25% damage taken, immune to magical effects\n_Giant (blue):_ -75% damage taken, +1 melee range, cannot move into tunnels\n_Blessed (yellow):_ +200% accuracy, +200% evasion\n_Growing (red):_ +20% accuracy, evasion, damage, and effective HP. Increases by 1% every 3 turns. challenges.champion_enemies_desc=You're not the only one who can level up!\n\n- Regular enemies have a 1/8 chance to spawn with a special champion buff.\n- Champions wake up if they spawn asleep\n- The hero knows when a champion spawns\n- Champions are immune to corruption\n\nThere are six types of champion enemy:\n_Blazing (orange):_ +25% melee damage, ignites on hit, immune to fire, spreads flames on death\n_Projecting (purple):_ +25% melee damage, can attack anything they see\n_Antimagic (green):_ -25% damage taken, immune to magical effects\n_Giant (blue):_ -75% damage taken, +1 melee range, cannot move into tunnels\n_Blessed (yellow):_ +200% accuracy, +200% evasion\n_Growing (red):_ +20% accuracy, evasion, damage, and effective HP. Increases by 1% every 3 turns.
challenges.stronger_bosses=Badder bosses challenges.stronger_bosses=Badder bosses
challenges.stronger_bosses_desc=TODO challenges.stronger_bosses_desc=TODO\n\n_Goo:_ +20% health\n_-_ Healing in water ramps up, to a max of 3/turn\n_-_ Pumps up in 1 turn instead of 2
rankings$record.something=Killed by Something rankings$record.something=Killed by Something

View File

@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
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;
@ -32,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey; import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
import com.shatteredpixel.shatteredpixeldungeon.items.quest.GooBlob; import com.shatteredpixel.shatteredpixeldungeon.items.quest.GooBlob;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
@ -46,7 +48,7 @@ import com.watabou.utils.Random;
public class Goo extends Mob { public class Goo extends Mob {
{ {
HP = HT = 100; HP = HT = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 120 : 100;
EXP = 10; EXP = 10;
defenseSkill = 8; defenseSkill = 8;
spriteClass = GooSprite.class; spriteClass = GooSprite.class;
@ -57,6 +59,7 @@ public class Goo extends Mob {
} }
private int pumpedUp = 0; private int pumpedUp = 0;
private int healInc = 1;
@Override @Override
public int damageRoll() { public int damageRoll() {
@ -92,14 +95,20 @@ public class Goo extends Mob {
public boolean act() { public boolean act() {
if (Dungeon.level.water[pos] && HP < HT) { if (Dungeon.level.water[pos] && HP < HT) {
HP += healInc;
if (Dungeon.level.heroFOV[pos] ){ if (Dungeon.level.heroFOV[pos] ){
sprite.emitter().burst( Speck.factory( Speck.HEALING ), 1 ); sprite.emitter().burst( Speck.factory( Speck.HEALING ), healInc );
} }
if (HP*2 == HT) { if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES) && healInc < 3) {
healInc++;
}
if (HP*2 > HT) {
BossHealthBar.bleed(false); BossHealthBar.bleed(false);
((GooSprite)sprite).spray(false); ((GooSprite)sprite).spray(false);
HP = Math.min(HP, HT);
} }
HP++; } else {
healInc = 1;
} }
if (state != SLEEPING){ if (state != SLEEPING){
@ -111,7 +120,15 @@ public class Goo extends Mob {
@Override @Override
protected boolean canAttack( Char enemy ) { protected boolean canAttack( Char enemy ) {
return (pumpedUp > 0) ? distance( enemy ) <= 2 : super.canAttack(enemy); if (pumpedUp > 0){
//we check both from and to in this case as projectile logic isn't always symmetrical.
//this helps trim out BS edge-cases
return Dungeon.level.distance(enemy.pos, pos) <= 2
&& new Ballistica( pos, enemy.pos, Ballistica.PROJECTILE).collisionPos == enemy.pos
&& new Ballistica( enemy.pos, pos, Ballistica.PROJECTILE).collisionPos == pos;
} else {
return super.canAttack(enemy);
}
} }
@Override @Override
@ -141,8 +158,8 @@ public class Goo extends Mob {
@Override @Override
protected boolean doAttack( Char enemy ) { protected boolean doAttack( Char enemy ) {
if (pumpedUp == 1) { if (pumpedUp == 1) {
((GooSprite)sprite).pumpUp( 2 );
pumpedUp++; pumpedUp++;
((GooSprite)sprite).pumpUp( pumpedUp );
spend( attackDelay() ); spend( attackDelay() );
@ -171,8 +188,11 @@ public class Goo extends Mob {
} else { } else {
pumpedUp++; pumpedUp++;
if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){
pumpedUp++;
}
((GooSprite)sprite).pumpUp( 1 ); ((GooSprite)sprite).pumpUp( pumpedUp );
if (Dungeon.level.heroFOV[pos]) { if (Dungeon.level.heroFOV[pos]) {
sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "!!!") ); sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "!!!") );
@ -258,6 +278,7 @@ public class Goo extends Mob {
} }
private final String PUMPEDUP = "pumpedup"; private final String PUMPEDUP = "pumpedup";
private final String HEALINC = "healinc";
@Override @Override
public void storeInBundle( Bundle bundle ) { public void storeInBundle( Bundle bundle ) {
@ -265,6 +286,7 @@ public class Goo extends Mob {
super.storeInBundle( bundle ); super.storeInBundle( bundle );
bundle.put( PUMPEDUP , pumpedUp ); bundle.put( PUMPEDUP , pumpedUp );
bundle.put( HEALINC, healInc );
} }
@Override @Override
@ -276,6 +298,9 @@ public class Goo extends Mob {
if (state != SLEEPING) BossHealthBar.assignBoss(this); if (state != SLEEPING) BossHealthBar.assignBoss(this);
if ((HP*2 <= HT)) BossHealthBar.bleed(true); if ((HP*2 <= HT)) BossHealthBar.bleed(true);
//if check is for pre-0.9.3 saves
healInc = bundle.getInt(HEALINC);
} }
} }

View File

@ -26,13 +26,12 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.watabou.noosa.TextureFilm; import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.particles.Emitter;
import com.watabou.noosa.particles.Emitter.Factory; import com.watabou.noosa.particles.Emitter.Factory;
import com.watabou.noosa.particles.PixelParticle; import com.watabou.noosa.particles.PixelParticle;
import com.watabou.utils.PathFinder;
import com.watabou.utils.PointF; import com.watabou.utils.PointF;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@ -92,9 +91,11 @@ public class GooSprite extends MobSprite {
} else { } else {
play(pump); play(pump);
Sample.INSTANCE.play( Assets.Sounds.CHARGEUP, 1f, warnDist == 1 ? 0.8f : 1f ); Sample.INSTANCE.play( Assets.Sounds.CHARGEUP, 1f, warnDist == 1 ? 0.8f : 1f );
PathFinder.buildDistanceMap(ch.pos, BArray.not(Dungeon.level.solid, null), 2); for (int i = 0; i < Dungeon.level.length(); i++){
for (int i = 0; i < PathFinder.distance.length; i++) { if (ch.fieldOfView[i]
if (PathFinder.distance[i] <= warnDist) { && Dungeon.level.distance(i, ch.pos) <= warnDist
&& new Ballistica( ch.pos, i, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID | Ballistica.IGNORE_SOFT_SOLID).collisionPos == i
&& new Ballistica( i, ch.pos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID | Ballistica.IGNORE_SOFT_SOLID).collisionPos == ch.pos){
Emitter e = CellEmitter.get(i); Emitter e = CellEmitter.get(i);
e.pour(GooParticle.FACTORY, 0.04f); e.pour(GooParticle.FACTORY, 0.04f);
pumpUpEmitters.add(e); pumpUpEmitters.add(e);