From d3ebcd0f4b81d31649f1c5690df0828849ab3b58 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 14 May 2021 18:53:02 -0400 Subject: [PATCH] v0.9.3: adjusted Yog for bosses challenge: Baseline changes: - Yog fists now seek the hero when wandering Challenge changes: - laser damage up to 30-50 from 20-30 - Two fists are now spawned each time! - minion deck is now stronger --- .../assets/messages/actors/actors.properties | 2 + .../main/assets/messages/misc/misc.properties | 2 +- .../actors/mobs/YogDzewa.java | 114 ++++++++++++++---- .../actors/mobs/YogFist.java | 7 ++ 4 files changed, 102 insertions(+), 23 deletions(-) diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 10049eecc..e76c257c4 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -1088,6 +1088,8 @@ actors.mobs.yogdzewa$larva.name=god's larva actors.mobs.yogdzewa$larva.rankings_desc=Devoured by Yog-Dzewa actors.mobs.yogdzewa$larva.desc=These tiny spawn of Yog-Dzewa are simple minions that are easy to produce. While individually weak, they are summoned quickly and can become overwhelming in large numbers. actors.mobs.yogdzewa$yogripper.rankings_desc=Devoured by Yog-Dzewa +actors.mobs.yogdzewa$yogeye.rankings_desc=Devoured by Yog-Dzewa +actors.mobs.yogdzewa$yogscorpio.rankings_desc=Devoured by Yog-Dzewa actors.mobs.yogfist.invuln_warn=The fist is invulnerable while near to the eye! actors.mobs.yogfist.rankings_desc=Devoured by Yog-Dzewa diff --git a/core/src/main/assets/messages/misc/misc.properties b/core/src/main/assets/messages/misc/misc.properties index a49ad7367..7f58299ad 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\n\n_Goo:_ +20% health\n_-_ Healing in water ramps up, to 3/turn\n_-_ Pumps up in 1 turn instead of 2\n\n_Tengu:_ +25% health\n_-_ Phase 1: traps are much deadlier\n_-_ Phase 2: abilities are more frequent\n\n_DM-300:_ +33% health\n_-_ Pylons are tougher and 3 activate\n_-_ Abilities are more powerful and frequent\n_-_ DM-300 is faster when supercharged\n_-_ Exposed wires are twice as common\n\n_Dwarf King:_ +50% health\n_-_ Minions are stronger in all phases\n_-_ Phase 1: faster abilities and summons\n_-_ Phase 2: 2 more minions per round\n_-_ Phase 3: 2x health, faster summons +challenges.stronger_bosses_desc=Bosses are much tougher with this challenge!\n\n_Goo:_ +20% health\n_-_ Healing in water ramps up, to 3/turn\n_-_ Pumps up in 1 turn instead of 2\n_Tengu:_ +25% health\n_-_ Phase 1: traps are much deadlier\n_-_ Phase 2: abilities are more frequent\n_DM-300:_ +33% health\n_-_ Pylons are tougher and 3 activate\n_-_ Abilities are more powerful and frequent\n_-_ DM-300 is faster when supercharged\n_-_ Exposed wires are twice as common\n_Dwarf King:_ +50% health\n_-_ Minions are stronger in all phases\n_-_ Phase 1: faster abilities and summons\n_-_ Phase 2: 2 more minions per round\n_-_ Phase 3: 2x health, faster summons\n_Yog-Dzewa:_\n_-_ Two fists are summoned at a time!\n_-_ +60% laser damage\n_-_ Stronger minions rankings$record.something=Killed by Something diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java index e0e9f72bd..e6659beb2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogDzewa.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; +import com.shatteredpixel.shatteredpixeldungeon.Challenges; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; @@ -90,24 +91,57 @@ public class YogDzewa extends Mob { private static final int MIN_SUMMON_CD = 10; private static final int MAX_SUMMON_CD = 15; + private static Class getPairedFist(Class fist){ + if (fist == YogFist.BurningFist.class) return YogFist.SoiledFist.class; + if (fist == YogFist.SoiledFist.class) return YogFist.BurningFist.class; + if (fist == YogFist.RottingFist.class) return YogFist.RustedFist.class; + if (fist == YogFist.RustedFist.class) return YogFist.RottingFist.class; + if (fist == YogFist.BrightFist.class) return YogFist.DarkFist.class; + if (fist == YogFist.DarkFist.class) return YogFist.BrightFist.class; + return null; + } + private ArrayList fistSummons = new ArrayList<>(); + private ArrayList challengeSummons = new ArrayList<>(); { Random.pushGenerator(Dungeon.seedCurDepth()); fistSummons.add(Random.Int(2) == 0 ? YogFist.BurningFist.class : YogFist.SoiledFist.class); fistSummons.add(Random.Int(2) == 0 ? YogFist.RottingFist.class : YogFist.RustedFist.class); fistSummons.add(Random.Int(2) == 0 ? YogFist.BrightFist.class : YogFist.DarkFist.class); Random.shuffle(fistSummons); + //randomly place challenge summons so that two fists of a pair can never spawn together + if (Random.Int(2) == 0){ + challengeSummons.add(getPairedFist(fistSummons.get(1))); + challengeSummons.add(getPairedFist(fistSummons.get(2))); + challengeSummons.add(getPairedFist(fistSummons.get(0))); + } else { + challengeSummons.add(getPairedFist(fistSummons.get(2))); + challengeSummons.add(getPairedFist(fistSummons.get(0))); + challengeSummons.add(getPairedFist(fistSummons.get(1))); + } Random.popGenerator(); } - private static final int SUMMON_DECK_SIZE = 4; private ArrayList regularSummons = new ArrayList<>(); { - for (int i = 0; i < SUMMON_DECK_SIZE; i++){ - if (i >= Statistics.spawnersAlive){ - regularSummons.add(Larva.class); - } else { - regularSummons.add(YogRipper.class); + if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){ + for (int i = 0; i < 6; i++){ + if (i >= 4){ + regularSummons.add(YogRipper.class); + } + if (i >= Statistics.spawnersAlive){ + regularSummons.add(Larva.class); + } else { + regularSummons.add( i % 2 == 0 ? YogEye.class : YogScorpio.class); + } + } + } else { + for (int i = 0; i < 6; i++){ + if (i >= Statistics.spawnersAlive){ + regularSummons.add(Larva.class); + } else { + regularSummons.add(YogRipper.class); + } } } Random.shuffle(regularSummons); @@ -175,7 +209,11 @@ public class YogDzewa extends Mob { Dungeon.observe(); } for (Char ch : affected) { - ch.damage(Random.NormalIntRange(20, 30), new Eye.DeathGaze()); + if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){ + ch.damage(Random.NormalIntRange(30, 50), new Eye.DeathGaze()); + } else { + ch.damage(Random.NormalIntRange(20, 30), new Eye.DeathGaze()); + } if (Dungeon.level.heroFOV[pos]) { ch.sprite.flash(); @@ -322,8 +360,11 @@ public class YogDzewa extends Mob { GLog.n(Messages.get(this, "darkness")); sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable")); - YogFist fist = (YogFist) Reflection.newInstance(fistSummons.remove(0)); - fist.pos = Dungeon.level.exit; + addFist((YogFist)Reflection.newInstance(fistSummons.remove(0))); + + if (Dungeon.isChallenged(Challenges.STRONGER_BOSSES)){ + addFist((YogFist)Reflection.newInstance(challengeSummons.remove(0))); + } CellEmitter.get(Dungeon.level.exit-1).burst(ShadowParticle.UP, 25); CellEmitter.get(Dungeon.level.exit).burst(ShadowParticle.UP, 100); @@ -332,17 +373,6 @@ public class YogDzewa extends Mob { if (abilityCooldown < 5) abilityCooldown = 5; if (summonCooldown < 5) summonCooldown = 5; - int targetPos = Dungeon.level.exit + Dungeon.level.width(); - if (Actor.findChar(targetPos) == null){ - fist.pos = targetPos; - } else if (Actor.findChar(targetPos-1) == null){ - fist.pos = targetPos-1; - } else if (Actor.findChar(targetPos+1) == null){ - fist.pos = targetPos+1; - } - - GameScene.add(fist, 4); - Actor.addDelayed( new Pushing( fist, Dungeon.level.exit, fist.pos ), -1 ); } LockedFloor lock = Dungeon.hero.buff(LockedFloor.class); @@ -350,6 +380,33 @@ public class YogDzewa extends Mob { } + public void addFist(YogFist fist){ + fist.pos = Dungeon.level.exit; + + CellEmitter.get(Dungeon.level.exit-1).burst(ShadowParticle.UP, 25); + CellEmitter.get(Dungeon.level.exit).burst(ShadowParticle.UP, 100); + CellEmitter.get(Dungeon.level.exit+1).burst(ShadowParticle.UP, 25); + + if (abilityCooldown < 5) abilityCooldown = 5; + if (summonCooldown < 5) summonCooldown = 5; + + int targetPos = Dungeon.level.exit + Dungeon.level.width(); + + if (!Dungeon.isChallenged(Challenges.STRONGER_BOSSES) + && Actor.findChar(targetPos) == null){ + fist.pos = targetPos; + } else if (Actor.findChar(targetPos-1) == null){ + fist.pos = targetPos-1; + } else if (Actor.findChar(targetPos+1) == null){ + fist.pos = targetPos+1; + } else if (Actor.findChar(targetPos) == null){ + fist.pos = targetPos; + } + + GameScene.add(fist, 4); + Actor.addDelayed( new Pushing( fist, Dungeon.level.exit, fist.pos ), -1 ); + } + public void updateVisibility( Level level ){ if (phase > 1 && isAlive()){ level.viewDistance = 4 - (phase-1); @@ -453,6 +510,7 @@ public class YogDzewa extends Mob { private static final String FIST_SUMMONS = "fist_summons"; private static final String REGULAR_SUMMONS = "regular_summons"; + private static final String CHALLENGE_SUMMONS = "challenges_summons"; private static final String TARGETED_CELLS = "targeted_cells"; @@ -465,6 +523,7 @@ public class YogDzewa extends Mob { bundle.put(SUMMON_CD, summonCooldown); bundle.put(FIST_SUMMONS, fistSummons.toArray(new Class[0])); + bundle.put(CHALLENGE_SUMMONS, challengeSummons.toArray(new Class[0])); bundle.put(REGULAR_SUMMONS, regularSummons.toArray(new Class[0])); int[] bundleArr = new int[targetedCells.size()]; @@ -485,6 +544,8 @@ public class YogDzewa extends Mob { fistSummons.clear(); Collections.addAll(fistSummons, bundle.getClassArray(FIST_SUMMONS)); + challengeSummons.clear(); + Collections.addAll(challengeSummons, bundle.getClassArray(CHALLENGE_SUMMONS)); regularSummons.clear(); Collections.addAll(regularSummons, bundle.getClassArray(REGULAR_SUMMONS)); @@ -525,7 +586,16 @@ public class YogDzewa extends Mob { } - //used so death to yog's ripper demons have their own rankings description and are more aggro - public static class YogRipper extends RipperDemon { + //used so death to yog's ripper demons have their own rankings description + public static class YogRipper extends RipperDemon {} + public static class YogEye extends Eye { + { + maxLvl = -2; + } + } + public static class YogScorpio extends Scorpio { + { + maxLvl = -2; + } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogFist.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogFist.java index 854725f4b..f2e6aed20 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogFist.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/YogFist.java @@ -81,6 +81,13 @@ public abstract class YogFist extends Mob { @Override protected boolean act() { if (paralysed <= 0 && rangedCooldown > 0) rangedCooldown--; + + if (Dungeon.hero.invisible <= 0 && state == WANDERING){ + beckon(Dungeon.hero.pos); + state = HUNTING; + enemy = Dungeon.hero; + } + return super.act(); }