From 252bcad4d39d96c97630ad6c26131bb7cfb91668 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 2 Apr 2021 16:46:52 -0400 Subject: [PATCH] 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 --- .../main/assets/messages/misc/misc.properties | 2 +- .../actors/mobs/Goo.java | 39 +++++++++++++++---- .../sprites/GooSprite.java | 11 +++--- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/core/src/main/assets/messages/misc/misc.properties b/core/src/main/assets/messages/misc/misc.properties index 375f7ccd1..3945cdfe0 100644 --- a/core/src/main/assets/messages/misc/misc.properties +++ b/core/src/main/assets/messages/misc/misc.properties @@ -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_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_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 diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java index 5e0e38f04..dd40ccdb1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Goo.java @@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; import com.shatteredpixel.shatteredpixeldungeon.Badges; +import com.shatteredpixel.shatteredpixeldungeon.Challenges; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; 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.keys.SkeletonKey; import com.shatteredpixel.shatteredpixeldungeon.items.quest.GooBlob; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; @@ -46,7 +48,7 @@ import com.watabou.utils.Random; public class Goo extends Mob { { - HP = HT = 100; + HP = HT = Dungeon.isChallenged(Challenges.STRONGER_BOSSES) ? 120 : 100; EXP = 10; defenseSkill = 8; spriteClass = GooSprite.class; @@ -57,6 +59,7 @@ public class Goo extends Mob { } private int pumpedUp = 0; + private int healInc = 1; @Override public int damageRoll() { @@ -92,14 +95,20 @@ public class Goo extends Mob { public boolean act() { if (Dungeon.level.water[pos] && HP < HT) { + HP += healInc; 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); ((GooSprite)sprite).spray(false); + HP = Math.min(HP, HT); } - HP++; + } else { + healInc = 1; } if (state != SLEEPING){ @@ -111,7 +120,15 @@ public class Goo extends Mob { @Override 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 @@ -141,8 +158,8 @@ public class Goo extends Mob { @Override protected boolean doAttack( Char enemy ) { if (pumpedUp == 1) { - ((GooSprite)sprite).pumpUp( 2 ); pumpedUp++; + ((GooSprite)sprite).pumpUp( pumpedUp ); spend( attackDelay() ); @@ -171,8 +188,11 @@ public class Goo extends Mob { } else { pumpedUp++; + if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){ + pumpedUp++; + } - ((GooSprite)sprite).pumpUp( 1 ); + ((GooSprite)sprite).pumpUp( pumpedUp ); if (Dungeon.level.heroFOV[pos]) { sprite.showStatus( CharSprite.NEGATIVE, Messages.get(this, "!!!") ); @@ -258,6 +278,7 @@ public class Goo extends Mob { } private final String PUMPEDUP = "pumpedup"; + private final String HEALINC = "healinc"; @Override public void storeInBundle( Bundle bundle ) { @@ -265,6 +286,7 @@ public class Goo extends Mob { super.storeInBundle( bundle ); bundle.put( PUMPEDUP , pumpedUp ); + bundle.put( HEALINC, healInc ); } @Override @@ -276,6 +298,9 @@ public class Goo extends Mob { if (state != SLEEPING) BossHealthBar.assignBoss(this); if ((HP*2 <= HT)) BossHealthBar.bleed(true); + //if check is for pre-0.9.3 saves + healInc = bundle.getInt(HEALINC); + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GooSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GooSprite.java index 6e5bc4947..0f2363d26 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GooSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/GooSprite.java @@ -26,13 +26,12 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; 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.audio.Sample; import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.particles.Emitter.Factory; import com.watabou.noosa.particles.PixelParticle; -import com.watabou.utils.PathFinder; import com.watabou.utils.PointF; import com.watabou.utils.Random; @@ -92,9 +91,11 @@ public class GooSprite extends MobSprite { } else { play(pump); 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 < PathFinder.distance.length; i++) { - if (PathFinder.distance[i] <= warnDist) { + for (int i = 0; i < Dungeon.level.length(); i++){ + if (ch.fieldOfView[i] + && 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); e.pour(GooParticle.FACTORY, 0.04f); pumpUpEmitters.add(e);