From 099073dd8905a8d051db2790fd1837a5abd01453 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 19 Mar 2020 04:05:56 -0400 Subject: [PATCH] v0.8.0: various tweaks and adjustments, mainly for demon halls: - added missing properties to rippers and spawners - fixed rippers having long visibility range, increased their damage by 11% - reduced the bleed damage from new ripper leap - rippers now interrupt the hero when leaping - adjusted candle positions in Yog's boss level - added more text (including warnings) for demon spawners - adjusted the positioning of Yog's sprite - fixed cases where angled visuals would be incorrectly not visible - removed redundant declarations from Ring of Elements, it now copies from AntiMagic --- .../main/java/com/watabou/noosa/Visual.java | 3 ++ .../shatteredpixeldungeon/actors/Actor.java | 2 +- .../actors/mobs/DemonSpawner.java | 6 ++- .../actors/mobs/RipperDemon.java | 14 ++++-- .../items/rings/RingOfElements.java | 48 ++----------------- .../levels/LastLevel.java | 6 +-- .../levels/NewHallsBossLevel.java | 15 +++--- .../scenes/GameScene.java | 18 +++++++ .../sprites/YogSprite.java | 2 +- .../messages/actors/actors.properties | 3 +- .../messages/scenes/scenes.properties | 2 + 11 files changed, 54 insertions(+), 65 deletions(-) diff --git a/SPD-classes/src/main/java/com/watabou/noosa/Visual.java b/SPD-classes/src/main/java/com/watabou/noosa/Visual.java index c42112e47..1f026431d 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/Visual.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/Visual.java @@ -272,6 +272,9 @@ public class Visual extends Gizmo { if (c == null || !visible) return false; + //FIXME, the below calculations ignore angle, so assume visible if angle != 0 + if (angle != 0) return true; + //x coord if (x > c.scroll.x + c.width) return false; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java index 3fb2b4695..071ad2446 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Actor.java @@ -47,7 +47,7 @@ public abstract class Actor implements Bundlable { protected static final int VFX_PRIO = 100; //visual effects take priority protected static final int HERO_PRIO = 0; //positive is before hero, negative after protected static final int BLOB_PRIO = -10; //blobs act after hero, before mobs - protected static final int MOB_PRIO = -20; //mobs act between buffs and blobd + protected static final int MOB_PRIO = -20; //mobs act between buffs and blobs protected static final int BUFF_PRIO = -30; //buffs act last in a turn private static final int DEFAULT = -100; //if no priority is given, act after all else diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DemonSpawner.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DemonSpawner.java index 892daebd2..da65c53ef 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DemonSpawner.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DemonSpawner.java @@ -31,8 +31,10 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.SpawnerSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.utils.Bundle; import com.watabou.utils.PathFinder; import com.watabou.utils.Random; @@ -57,6 +59,7 @@ public class DemonSpawner extends Mob { properties.add(Property.IMMOVABLE); properties.add(Property.MINIBOSS); + properties.add(Property.DEMONIC); } @Override @@ -76,7 +79,7 @@ public class DemonSpawner extends Mob { private float spawnCooldown = 0; - private boolean spawnRecorded = false; + public boolean spawnRecorded = false; @Override protected boolean act() { @@ -133,6 +136,7 @@ public class DemonSpawner extends Mob { if (spawnRecorded){ Statistics.spawnersAlive--; } + GLog.h(Messages.get(this, "on_death")); super.die(cause); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RipperDemon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RipperDemon.java index 4724e6a0f..eca0b861c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RipperDemon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/RipperDemon.java @@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bleeding; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light; import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; import com.shatteredpixel.shatteredpixeldungeon.effects.TargetedCell; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; @@ -46,6 +47,7 @@ public class RipperDemon extends Mob { HP = HT = 60; defenseSkill = 22; + viewDistance = Light.DISTANCE; EXP = 9; //for corrupting maxLvl = -2; @@ -53,6 +55,9 @@ public class RipperDemon extends Mob { HUNTING = new Hunting(); baseSpeed = 1f; + + properties.add(Property.DEMONIC); + properties.add(Property.UNDEAD); } @Override @@ -62,7 +67,7 @@ public class RipperDemon extends Mob { @Override public int damageRoll() { - return Random.NormalIntRange( 12, 24 ); + return Random.NormalIntRange( 15, 25 ); } @Override @@ -136,7 +141,7 @@ public class RipperDemon extends Mob { Char ch = Actor.findChar(leapPos); if (ch != null){ if (alignment != ch.alignment){ - Buff.affect(ch, Bleeding.class).set(Math.max(damageRoll(), damageRoll())); + Buff.affect(ch, Bleeding.class).set(0.75f*Math.max(damageRoll(), damageRoll())); ch.sprite.flash(); Sample.INSTANCE.play(Assets.SND_HIT); } @@ -201,11 +206,10 @@ public class RipperDemon extends Mob { //get ready to leap leapPos = targetPos; spend(TICK); - if (Dungeon.level.heroFOV[leapPos]) { - sprite.parent.addToBack(new TargetedCell(leapPos, 0xFF0000)); - } if (Dungeon.level.heroFOV[pos]){ GLog.w(Messages.get(RipperDemon.this, "leap")); + sprite.parent.addToBack(new TargetedCell(leapPos, 0xFF0000)); + Dungeon.hero.interrupt(); } return true; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfElements.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfElements.java index 0e14d254d..f5946c58d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfElements.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfElements.java @@ -34,25 +34,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hex; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vulnerable; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Warlock; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfDisintegration; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFireblast; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFrost; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLightning; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLivingEarth; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfMagicMissile; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfPrismaticLight; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfTransfusion; -import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding; -import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap; -import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrimTrap; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import java.text.DecimalFormat; @@ -83,34 +65,10 @@ public class RingOfElements extends Ring { RESISTS.add( Poison.class ); RESISTS.add( Corrosion.class ); - RESISTS.add( Charm.class ); - RESISTS.add( Weakness.class ); - RESISTS.add( Vulnerable.class ); - RESISTS.add( Hex.class ); - RESISTS.add( Degrade.class ); - - RESISTS.add( DisintegrationTrap.class ); - RESISTS.add( GrimTrap.class ); - - RESISTS.add( WandOfBlastWave.class ); - RESISTS.add( WandOfDisintegration.class ); - RESISTS.add( WandOfFireblast.class ); - RESISTS.add( WandOfFrost.class ); - RESISTS.add( WandOfLightning.class ); - RESISTS.add( WandOfLivingEarth.class ); - RESISTS.add( WandOfMagicMissile.class ); - RESISTS.add( WandOfPrismaticLight.class ); - RESISTS.add( WandOfTransfusion.class ); - RESISTS.add( WandOfWarding.Ward.class ); - RESISTS.add( ToxicGas.class ); RESISTS.add( Electricity.class ); - - RESISTS.add( DM100.LightningBolt.class ); - RESISTS.add( Shaman.EarthenBolt.class ); - RESISTS.add( Warlock.DarkBolt.class ); - RESISTS.add( Eye.DeathGaze.class ); - RESISTS.add( Yog.BurningFist.DarkBolt.class ); + + RESISTS.addAll( AntiMagic.RESISTS ); } public static float resist( Char target, Class effect ){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java index c811abac1..397f0b022 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java @@ -307,10 +307,10 @@ public class LastLevel extends Level { private static final int[] map = new int[]{ -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 8, 9, 10, 11, 19, 11, 12, 13, 14, 0, 0, 0, - 0, 0, 0, 0, 16, 17, 18, 19, 19, 19, 20, 21, 22, 0, 0, 0, - 0, 0, 0, 0, 24, 25, 26, 31, 19, 31, 28, 29, 30, 0, 0, 0, + 0, 0, 0, 0, 16, 17, 18, 31, 19, 31, 20, 21, 22, 0, 0, 0, + 0, 0, 0, 0, 24, 25, 26, 19, 19, 19, 28, 29, 30, 0, 0, 0, + 0, 0, 0, 0, 24, 25, 26, 19, 19, 19, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 19, 19, 19, 28, 29, 30, 0, 0, 0, - 0, 0, 0, 0, 24, 25, 26, 31, 19, 31, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 24, 25, 34, 35, 35, 35, 34, 29, 30, 0, 0, 0, 0, 0, 0, 0, 40, 41, 36, 36, 36, 36, 36, 40, 41, 0, 0, 0, 0, 0, 0, 0, 48, 49, 36, 36, 36, 36, 36, 48, 49, 0, 0, 0, diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java index eca66c96e..181b9e397 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java @@ -127,10 +127,9 @@ public class NewHallsBossLevel extends Level { Painter.fill(this, ROOM_LEFT, ROOM_BOTTOM-1, 2, 2, Terrain.WALL_DECO ); Painter.fill(this, ROOM_RIGHT-1, ROOM_BOTTOM-1, 2, 2, Terrain.WALL_DECO ); - Painter.fill(this, ROOM_LEFT+3, ROOM_TOP+3, 3, 3, Terrain.EMPTY ); + Painter.fill(this, ROOM_LEFT+3, ROOM_TOP+2, 3, 4, Terrain.EMPTY ); exit = width/2 + ((ROOM_TOP+1) * width); - //map[exit] = Terrain.EXIT; CustomTilemap vis = new CenterPieceVisuals(); vis.pos(ROOM_LEFT, ROOM_TOP+1); @@ -186,14 +185,14 @@ public class NewHallsBossLevel extends Level { super.occupyCell( ch ); if (map[entrance] == Terrain.ENTRANCE && map[exit] != Terrain.EXIT - && ch == Dungeon.hero && ch.pos != entrance) { - + && ch == Dungeon.hero && Dungeon.level.distance(ch.pos, entrance) >= 2) { seal(); } } @Override public void seal() { + super.seal(); set( entrance, Terrain.EMPTY_SP ); GameScene.updateMap( entrance ); CellEmitter.get( entrance ).start( FlameParticle.FACTORY, 0.1f, 10 ); @@ -280,10 +279,10 @@ public class NewHallsBossLevel extends Level { private static final int[] map = new int[]{ 8, 9, 10, 11, 11, 11, 12, 13, 14, - 16, 17, 18, 19, 19, 19, 20, 21, 22, - 24, 25, 26, 27, 19, 27, 28, 29, 30, + 16, 17, 18, 27, 19, 27, 20, 21, 22, + 24, 25, 26, 19, 19, 19, 28, 29, 30, + 24, 25, 26, 19, 19, 19, 28, 29, 30, 24, 25, 26, 19, 19, 19, 28, 29, 30, - 24, 25, 26, 27, 19, 27, 28, 29, 30, 24, 25, 34, 35, 35, 35, -1, 29, 30, 40, 41, 36, 36, 36, 36, 36, 40, 41, 48, 49, 36, 36, 36, 36, 36, 48, 49 @@ -301,7 +300,7 @@ public class NewHallsBossLevel extends Level { int[] data = map.clone(); if (Dungeon.level.map[Dungeon.level.exit] == Terrain.EXIT) { data[4] = 19; - data[21] = data[23] = data[39] = data[41] = 31; + data[12] = data[14] = 31; } vis.map(data, tileW); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index 7fd57c035..9c493e717 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -30,6 +30,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DemonSpawner; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.effects.BannerSprites; import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter; @@ -441,6 +442,23 @@ public class GameScene extends PixelScene { ((DriedRose.GhostHero) ch).sayAppeared(); } } + + int spawnersAbove = Statistics.spawnersAlive; + if (spawnersAbove > 0) { + for (Mob m : Dungeon.level.mobs) { + if (m instanceof DemonSpawner && ((DemonSpawner) m).spawnRecorded) { + spawnersAbove--; + } + } + + if (spawnersAbove > 0) { + if (Dungeon.bossLevel()) { + GLog.n(Messages.get(this, "spawner_warn_final")); + } else { + GLog.n(Messages.get(this, "spawner_warn")); + } + } + } } else if (InterlevelScene.mode == InterlevelScene.Mode.RESET) { GLog.h(Messages.get(this, "warp")); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java index 18a701f3e..2e07fbc8e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/YogSprite.java @@ -31,7 +31,7 @@ public class YogSprite extends MobSprite { public YogSprite() { super(); - perspectiveRaise = 0.2f; + perspectiveRaise = 5 / 16f; texture( Assets.YOG ); diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties index 80ebcc2cc..074c823c1 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties @@ -482,7 +482,8 @@ actors.mobs.crystalmimic.escaped=The crystal mimic has escaped! actors.mobs.crystalmimic.desc=Mimics are magical creatures which can take any shape they wish. In dungeons they almost always choose a shape of a treasure chest, in order to lure in unsuspecting adventurers.\n\nCrystal mimics are trickier than their regular cousins, and prefer to avoid conflict while stealing loot. They will attempt to sprint away once discovered, and have the ability to reposition enemies when they attack. actors.mobs.demonspawner.name=demon spawner -actors.mobs.demonspawner.desc=This twisting amalgam of dwarven flesh is responsible for creating ripper demons from dwarven body parts. Clearly the demons see no issue with using every resource they can against their enemies.\n\nWhile visually terrifying, demon spawners have no means of moving or directly defending themselves. Their considerable mass makes them hard to kill quickly however, and they will spawn ripper demons more quickly when they are under threat. +actors.mobs.demonspawner.on_death=The demonic energy here seems to lessen as the spawner dies. +actors.mobs.demonspawner.desc=This twisting amalgam of dwarven flesh is responsible for creating ripper demons from the dwarves that have died in this region. Clearly the demons see no issue with using every resource they can against their enemies.\n\nWhile visually terrifying, demon spawners have no means of moving or directly defending themselves. Their considerable mass makes them hard to kill quickly however, and they will spawn ripper demons more quickly when they are under threat.\n\n_Demon spawners seem to be connected to some central source of demonic power. Killing them may weaken it._ actors.mobs.dm100.name=DM-100 actors.mobs.dm100.zap_kill=The lightning bolt killed you... diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/scenes/scenes.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/scenes/scenes.properties index 408bcc417..8bf0a59b0 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/scenes/scenes.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/scenes/scenes.properties @@ -22,6 +22,8 @@ scenes.changesscene.misc=Miscellaneous Changes scenes.changesscene.language=Language Improvements scenes.gamescene.descend=You descend to floor %d of the dungeon. +scenes.gamescene.spawner_warn=You feel that there's a source of demonic energy above you... +scenes.gamescene.spawner_warn_final=You can feel demonic energy radiating here from the previous floors! scenes.gamescene.warp=The walls warp and shift around you! scenes.gamescene.return=You return to floor %d of the dungeon. scenes.gamescene.chasm=Your steps echo across the dungeon.