From 9326a3bdd4ac6625eb4b3bb3ba89e151a383f9cf Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 27 Nov 2019 20:28:33 -0500 Subject: [PATCH] v0.8.0: significant balance adjustments and design tweaks to traps --- .../actors/mobs/npcs/RatKing.java | 34 ++++- .../levels/CavesLevel.java | 15 +- .../levels/CityLevel.java | 16 +-- .../levels/HallsLevel.java | 13 +- .../shatteredpixeldungeon/levels/Level.java | 2 + .../levels/PrisonLevel.java | 10 +- .../levels/RegularLevel.java | 2 +- .../levels/SewerLevel.java | 10 +- .../levels/traps/CursingTrap.java | 29 +--- .../levels/traps/DisarmingTrap.java | 29 ++-- .../levels/traps/DisintegrationTrap.java | 20 --- .../levels/traps/DistortionTrap.java | 135 +++++++++++++++--- .../levels/traps/OozeTrap.java | 14 +- .../levels/traps/PitfallTrap.java | 64 +++++++-- .../levels/traps/PoisonDartTrap.java | 2 +- .../levels/traps/WornDartTrap.java | 2 +- .../messages/actors/actors.properties | 1 + .../messages/levels/levels.properties | 6 +- 18 files changed, 275 insertions(+), 129 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/RatKing.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/RatKing.java index bf841f930..e69be108d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/RatKing.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/RatKing.java @@ -62,7 +62,39 @@ public class RatKing extends NPC { public boolean reset() { return true; } - + + //***This functionality is for when rat king may be summoned by a distortion trap + + @Override + protected void onAdd() { + super.onAdd(); + if (Dungeon.depth != 5){ + yell(Messages.get(this, "confused")); + } + } + + @Override + protected boolean act() { + if (Dungeon.depth < 5){ + if (pos == Dungeon.level.exit){ + destroy(); + sprite.killAndErase(); + } else { + target = Dungeon.level.exit; + } + } else if (Dungeon.depth > 5){ + if (pos == Dungeon.level.entrance){ + destroy(); + sprite.killAndErase(); + } else { + target = Dungeon.level.entrance; + } + } + return super.act(); + } + + //*** + @Override public boolean interact() { sprite.turnTo( pos, Dungeon.hero.pos ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java index 8dfaa1c75..20f36cc5a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java @@ -30,7 +30,6 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BurningTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ConfusionTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CorrosionTrap; -import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrippingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GuardianTrap; @@ -96,18 +95,18 @@ public class CavesLevel extends RegularLevel { @Override protected Class[] trapClasses() { - return new Class[]{ BurningTrap.class, PoisonDartTrap.class, FrostTrap.class, StormTrap.class, CorrosionTrap.class, - GrippingTrap.class, ExplosiveTrap.class, RockfallTrap.class, GuardianTrap.class, - ConfusionTrap.class, SummoningTrap.class, WarpingTrap.class, - PitfallTrap.class }; + return new Class[]{ + BurningTrap.class, PoisonDartTrap.class, FrostTrap.class, StormTrap.class, CorrosionTrap.class, + GrippingTrap.class, RockfallTrap.class, GuardianTrap.class, + ConfusionTrap.class, SummoningTrap.class, WarpingTrap.class, PitfallTrap.class }; } @Override protected float[] trapChances() { - return new float[]{ 8, 8, 8, 8, 8, - 4, 4, 4, 4, + return new float[]{ + 4, 4, 4, 4, 4, 2, 2, 2, - 1 }; + 1, 1, 1, 1}; } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java index fcd685ae6..9e6135550 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java @@ -31,7 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CorrosionTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisarmingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap; -import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap; +import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DistortionTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FlashingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GuardianTrap; @@ -88,18 +88,18 @@ public class CityLevel extends RegularLevel { @Override protected Class[] trapClasses() { - return new Class[]{ FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class, - ExplosiveTrap.class, RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class, - SummoningTrap.class, WarpingTrap.class, CursingTrap.class, - PitfallTrap.class, DisarmingTrap.class }; + return new Class[]{ + FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class, + RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class, + DisarmingTrap.class, SummoningTrap.class, WarpingTrap.class, CursingTrap.class, PitfallTrap.class, DistortionTrap.class }; } @Override protected float[] trapChances() { - return new float[]{ 8, 8, 8, 8, 8, + return new float[]{ 4, 4, 4, 4, 4, - 2, 2, 2, - 1, 1 }; + 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1 }; } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java index 5b3aa84c8..bfc012ced 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java @@ -32,7 +32,6 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisarmingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DistortionTrap; -import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FlashingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrimTrap; @@ -100,18 +99,18 @@ public class HallsLevel extends RegularLevel { @Override protected Class[] trapClasses() { - return new Class[]{ FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class, - ExplosiveTrap.class, RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class, - SummoningTrap.class, WarpingTrap.class, CursingTrap.class, GrimTrap.class, - PitfallTrap.class, DisarmingTrap.class, DistortionTrap.class }; + return new Class[]{ + FrostTrap.class, StormTrap.class, CorrosionTrap.class, BlazingTrap.class, DisintegrationTrap.class, + RockfallTrap.class, FlashingTrap.class, GuardianTrap.class, WeakeningTrap.class, + DisarmingTrap.class, SummoningTrap.class, WarpingTrap.class, CursingTrap.class, GrimTrap.class, PitfallTrap.class, DistortionTrap.class }; } @Override protected float[] trapChances() { - return new float[]{ 8, 8, 8, 8, 8, + return new float[]{ 4, 4, 4, 4, 4, 2, 2, 2, 2, - 1, 1, 1 }; + 1, 1, 1, 1, 1, 1, 1 }; } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java index 75288e7b5..e964ff8cf 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java @@ -493,6 +493,8 @@ public abstract class Level implements Bundlable { @Override protected boolean act() { int count = 0; + + //TODO some mobs should count for less (ripper shouldn't count at all, ghouls should be 1/2, special enemies should be 0 for (Mob mob : mobs.toArray(new Mob[0])){ if (mob.alignment == Char.Alignment.ENEMY) count++; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java index f86fd22ae..e799238a3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java @@ -94,16 +94,18 @@ public class PrisonLevel extends RegularLevel { @Override protected Class[] trapClasses() { - return new Class[]{ ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, BurningTrap.class, PoisonDartTrap.class, + return new Class[]{ + ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, BurningTrap.class, PoisonDartTrap.class, AlarmTrap.class, OozeTrap.class, GrippingTrap.class, ConfusionTrap.class, FlockTrap.class, SummoningTrap.class, TeleportationTrap.class, }; } @Override protected float[] trapChances() { - return new float[]{ 8, 8, 8, 8, 8, - 4, 4, 4, - 2, 2, 2, 2 }; + return new float[]{ + 4, 4, 4, 4, 4, + 2, 2, 2, + 1, 1, 1, 1 }; } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java index 5f648f16c..57cb675d6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -141,7 +141,7 @@ public abstract class RegularLevel extends Level { protected abstract Painter painter(); protected int nTraps() { - return Random.NormalIntRange( 1, 3+(Dungeon.depth/3) ); + return Random.NormalIntRange( 2, 3 + (Dungeon.depth/5) ); } protected Class[] trapClasses(){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java index 3baf8b2fd..e67095d6c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java @@ -90,7 +90,8 @@ public class SewerLevel extends RegularLevel { protected Class[] trapClasses() { return Dungeon.depth == 1 ? new Class[]{ WornDartTrap.class } : - new Class[]{ ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, WornDartTrap.class, + new Class[]{ + ChillingTrap.class, ShockingTrap.class, ToxicTrap.class, WornDartTrap.class, AlarmTrap.class, OozeTrap.class, ConfusionTrap.class, FlockTrap.class, SummoningTrap.class, TeleportationTrap.class }; } @@ -99,9 +100,10 @@ public class SewerLevel extends RegularLevel { protected float[] trapChances() { return Dungeon.depth == 1 ? new float[]{1} : - new float[]{8, 8, 8, 8, - 4, 4, - 2, 2, 2, 2}; + new float[]{ + 4, 4, 4, 4, + 2, 2, + 1, 1, 1, 1}; } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/CursingTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/CursingTrap.java index 6a9578628..11c9548b1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/CursingTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/CursingTrap.java @@ -30,14 +30,13 @@ import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon; -import com.shatteredpixel.shatteredpixeldungeon.items.KindofMisc; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; -import com.watabou.utils.Random; import java.util.ArrayList; import java.util.Collections; @@ -76,7 +75,7 @@ public class CursingTrap extends Trap { ArrayList canCurse = new ArrayList<>(); KindOfWeapon weapon = hero.belongings.weapon; - if (weapon instanceof Weapon && !weapon.cursed){ + if (weapon instanceof Weapon && !(weapon instanceof MagesStaff)){ if (((Weapon) weapon).enchantment == null) priorityCurse.add(weapon); else @@ -84,34 +83,20 @@ public class CursingTrap extends Trap { } Armor armor = hero.belongings.armor; - if (armor != null && !armor.cursed){ + if (armor != null){ if (armor.glyph == null) priorityCurse.add(armor); else canCurse.add(armor); } - KindofMisc misc1 = hero.belongings.misc1; - if (misc1 != null){ - canCurse.add(misc1); - } - - KindofMisc misc2 = hero.belongings.misc2; - if (misc2 != null){ - canCurse.add(misc2); - } - Collections.shuffle(priorityCurse); Collections.shuffle(canCurse); - int numCurses = Random.Int(2) == 0 ? 1 : 2; - - for (int i = 0; i < numCurses; i++){ - if (!priorityCurse.isEmpty()){ - curse(priorityCurse.remove(0)); - } else if (!canCurse.isEmpty()){ - curse(canCurse.remove(0)); - } + if (!priorityCurse.isEmpty()){ + curse(priorityCurse.remove(0)); + } else if (!canCurse.isEmpty()){ + curse(canCurse.remove(0)); } EquipableItem.equipCursed(hero); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java index 94f61e4e3..159b8c7eb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisarmingTrap.java @@ -67,23 +67,26 @@ public class DisarmingTrap extends Trap{ if (weapon != null && !weapon.cursed) { - int cell = Dungeon.level.randomRespawnCell(); - if (cell != -1) { - hero.belongings.weapon = null; - Dungeon.quickslot.clearItem(weapon); - weapon.updateQuickslot(); + int cell; + do { + cell = Dungeon.level.randomRespawnCell(); - Dungeon.level.drop(weapon, cell).seen = true; - for (int i : PathFinder.NEIGHBOURS9) - Dungeon.level.visited[cell+i] = true; - GameScene.updateFog(); + PathFinder.buildDistanceMap(pos, Dungeon.level.passable); + } while (cell == -1 || PathFinder.distance[cell] < 10 || PathFinder.distance[cell] > 20); - GLog.w( Messages.get(this, "disarm") ); + hero.belongings.weapon = null; + Dungeon.quickslot.clearItem(weapon); + weapon.updateQuickslot(); - Sample.INSTANCE.play(Assets.SND_TELEPORT); - CellEmitter.get(pos).burst(Speck.factory(Speck.LIGHT), 4); + Dungeon.level.drop(weapon, cell).seen = true; + for (int i : PathFinder.NEIGHBOURS9) + Dungeon.level.mapped[cell+i] = true; + GameScene.updateFog(cell, 1); - } + GLog.w( Messages.get(this, "disarm") ); + + Sample.INSTANCE.play(Assets.SND_TELEPORT); + CellEmitter.get(pos).burst(Speck.factory(Speck.LIGHT), 4); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java index 0e66446ad..ae6704f6c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DisintegrationTrap.java @@ -29,8 +29,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; -import com.shatteredpixel.shatteredpixeldungeon.items.Item; -import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; @@ -76,24 +74,6 @@ public class DisintegrationTrap extends Trap { if (!hero.isAlive()){ Dungeon.fail( getClass() ); GLog.n( Messages.get(this, "ondeath") ); - } else { - Item item = hero.belongings.randomUnequipped(); - Bag bag = hero.belongings.backpack; - //bags do not protect against this trap - if (item instanceof Bag){ - bag = (Bag)item; - item = Random.element(bag.items); - } - if (item == null || item.level() > 0 || item.unique) return; - if (!item.stackable){ - item.detachAll(bag); - GLog.w( Messages.get(this, "one", item.name()) ); - } else { - int n = Random.NormalIntRange(1, (item.quantity()+1)/2); - for(int i = 1; i <= n; i++) - item.detach(bag); - GLog.w( Messages.get(this, "some", item.name()) ); - } } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DistortionTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DistortionTrap.java index 62d47a4c7..8e53ed129 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DistortionTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/DistortionTrap.java @@ -22,37 +22,136 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Belongings; -import com.shatteredpixel.shatteredpixeldungeon.items.Item; -import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.LloydsBeacon; -import com.shatteredpixel.shatteredpixeldungeon.journal.Notes; -import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene; -import com.watabou.noosa.Game; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Acidic; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Albino; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredBrute; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bandit; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Bestiary; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.CausticSlime; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Piranha; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Senior; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Statue; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Wraith; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.RatKing; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.watabou.utils.PathFinder; +import com.watabou.utils.Random; +import com.watabou.utils.Reflection; + +import java.util.ArrayList; +import java.util.Arrays; public class DistortionTrap extends Trap{ + private static final float DELAY = 2f; + { color = TEAL; shape = LARGE_DOT; } + private static final ArrayList> RARE = new ArrayList<>(Arrays.asList( + Albino.class, CausticSlime.class, + Bandit.class, + ArmoredBrute.class, + Elemental.Chaos.class, Senior.class, + Acidic.class)); + @Override public void activate() { - InterlevelScene.returnDepth = Dungeon.depth; - Belongings belongings = Dungeon.hero.belongings; - - for (Notes.Record rec : Notes.getRecords()){ - if (rec.depth() == Dungeon.depth){ - Notes.remove(rec); + + int nMobs = 3; + if (Random.Int( 2 ) == 0) { + nMobs++; + if (Random.Int( 2 ) == 0) { + nMobs++; } } - - for (Item i : belongings){ - if (i instanceof LloydsBeacon && ((LloydsBeacon) i).returnDepth == Dungeon.depth) - ((LloydsBeacon) i).returnDepth = -1; + + ArrayList candidates = new ArrayList<>(); + + for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) { + int p = pos + PathFinder.NEIGHBOURS8[i]; + if (Actor.findChar( p ) == null && (Dungeon.level.passable[p] || Dungeon.level.avoid[p])) { + candidates.add( p ); + } + } + + ArrayList respawnPoints = new ArrayList<>(); + + while (nMobs > 0 && candidates.size() > 0) { + int index = Random.index( candidates ); + + respawnPoints.add( candidates.remove( index ) ); + nMobs--; + } + + ArrayList mobs = new ArrayList<>(); + + int summoned = 0; + for (Integer point : respawnPoints) { + summoned++; + Mob mob; + switch (summoned){ + case 1: + if (Dungeon.depth != 5 && Random.Int(100) == 0){ + mob = new RatKing(); + break; + } + case 3: case 5 : default: + int floor; + do { + floor = Random.Int(25); + } while( Dungeon.bossLevel(floor)); + mob = Reflection.newInstance(Bestiary.getMobRotation(floor).get(0)); + break; + case 2: + switch (Random.Int(4)){ + case 0: default: + Wraith.spawnAt(point); + continue; //wraiths spawn themselves, no need to do more + case 1: + //yes it's intended that these are likely to die right away + mob = new Piranha(); + break; + case 2: + Mimic.spawnAt(point, new ArrayList<>()); + continue; //mimics spawn themselves, no need to do more + case 3: + mob = new Statue(); + break; + } + break; + case 4: + mob = Reflection.newInstance(Random.element(RARE)); + break; + } + + mob.maxLvl = Hero.MAX_LEVEL; + mob.state = mob.WANDERING; + mob.pos = point; + GameScene.add(mob, DELAY); + mobs.add(mob); + } + + //important to process the visuals and pressing of cells last, so spawned mobs have a chance to occupy cells first + Trap t; + for (Mob mob : mobs){ + //manually trigger traps first to avoid sfx spam + if ((t = Dungeon.level.traps.get(mob.pos)) != null && t.active){ + t.disarm(); + t.reveal(); + t.activate(); + } + ScrollOfTeleportation.appear(mob, mob.pos); + Dungeon.level.occupyCell(mob); } - InterlevelScene.mode = InterlevelScene.Mode.RESET; - Game.switchScene(InterlevelScene.class); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/OozeTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/OozeTrap.java index 31c220a80..e3f3158c1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/OozeTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/OozeTrap.java @@ -21,11 +21,13 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze; import com.shatteredpixel.shatteredpixeldungeon.effects.Splash; +import com.watabou.utils.PathFinder; public class OozeTrap extends Trap { @@ -36,11 +38,15 @@ public class OozeTrap extends Trap { @Override public void activate() { - Char ch = Actor.findChar( pos ); - if (ch != null && !ch.flying){ - Buff.affect(ch, Ooze.class).set( 20f ); - Splash.at( pos, 0x000000, 5); + for( int i : PathFinder.NEIGHBOURS9) { + if (!Dungeon.level.solid[pos + i]) { + Splash.at( pos + i, 0x000000, 5); + Char ch = Actor.findChar( pos + i ); + if (ch != null && !ch.flying){ + Buff.affect(ch, Ooze.class).set( 20f ); + } + } } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java index bcb364339..b53c05a3c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PitfallTrap.java @@ -24,6 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; @@ -31,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.utils.PathFinder; public class PitfallTrap extends Trap { @@ -46,26 +49,57 @@ public class PitfallTrap extends Trap { GLog.w(Messages.get(this, "no_pit")); return; } - - Heap heap = Dungeon.level.heaps.get( pos ); - if (heap != null){ - for (Item item : heap.items){ - Dungeon.dropToChasm(item); - } - heap.sprite.kill(); - GameScene.discard(heap); - Dungeon.level.heaps.remove( pos ); + //TODO visuals + DelayedPit p = Buff.affect(Dungeon.hero, DelayedPit.class, 1); + p.depth = Dungeon.depth; + p.pos = pos; + + if (pos == Dungeon.hero.pos){ + GLog.n(Messages.get(this, "triggered_hero")); + } else if (Dungeon.level.heroFOV[pos]){ + GLog.n(Messages.get(this, "triggered")); } - Char ch = Actor.findChar( pos ); + } - if (ch != null && !ch.flying) { - if (ch == Dungeon.hero) { - Chasm.heroFall(pos); - } else { - Chasm.mobFall((Mob) ch); + public static class DelayedPit extends FlavourBuff { + + int pos; + int depth; + + @Override + public boolean act() { + if (depth == Dungeon.depth) { + for (int i : PathFinder.NEIGHBOURS9) { + int cell = pos + i; + + Heap heap = Dungeon.level.heaps.get(cell); + + if (heap != null) { + for (Item item : heap.items) { + Dungeon.dropToChasm(item); + } + heap.sprite.kill(); + GameScene.discard(heap); + Dungeon.level.heaps.remove(cell); + } + + Char ch = Actor.findChar(cell); + + if (ch != null && !ch.flying) { + if (ch == Dungeon.hero) { + Chasm.heroFall(cell); + } else { + Chasm.mobFall((Mob) ch); + } + } + + } } + + detach(); + return true; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PoisonDartTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PoisonDartTrap.java index dcab6cfc5..24fd3560d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PoisonDartTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/PoisonDartTrap.java @@ -88,7 +88,7 @@ public class PoisonDartTrap extends Trap { reset(pos, finalTarget.sprite, new PoisonDart(), new Callback() { @Override public void call() { - int dmg = Random.NormalIntRange(1, 4) - finalTarget.drRoll(); + int dmg = Random.NormalIntRange(4, 8) - finalTarget.drRoll(); finalTarget.damage(dmg, trap); if (finalTarget == Dungeon.hero && !finalTarget.isAlive()){ Dungeon.fail( trap.getClass() ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/WornDartTrap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/WornDartTrap.java index a10dc0b3c..caf69a924 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/WornDartTrap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/traps/WornDartTrap.java @@ -74,7 +74,7 @@ public class WornDartTrap extends Trap { reset(pos, finalTarget.sprite, new Dart(), new Callback() { @Override public void call() { - int dmg = Random.NormalIntRange(1, 4) - finalTarget.drRoll(); + int dmg = Random.NormalIntRange(4, 8) - finalTarget.drRoll(); finalTarget.damage(dmg, trap); if (finalTarget == Dungeon.hero && !finalTarget.isAlive()){ Dungeon.fail( trap.getClass() ); 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 8440098aa..a1bee63e9 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 @@ -406,6 +406,7 @@ actors.mobs.npcs.prismaticimage.desc=This shimmering illusion bears a close rese actors.mobs.npcs.ratking.name=rat king actors.mobs.npcs.ratking.not_sleeping=I'm not sleeping! actors.mobs.npcs.ratking.what_is_it=What is it? I have no time for this nonsense. My kingdom won't rule itself! +actors.mobs.npcs.ratking.confused=Wha... Where am I? My kingdom needs me! actors.mobs.npcs.ratking.desc_festive=This rat is a little bigger than a regular marsupial rat. It's wearing a tiny festive hat instead of its usual crown. Happy Holidays! actors.mobs.npcs.ratking.desc=This rat is a little bigger than a regular marsupial rat and it's wearing a tiny crown on its head. diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/levels/levels.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/levels/levels.properties index 668b828c1..204fbf6ac 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/levels/levels.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/levels/levels.properties @@ -51,7 +51,7 @@ levels.traps.disintegrationtrap.ondeath=You were killed by the disintegration tr levels.traps.disintegrationtrap.desc=When triggered, this trap will lance the nearest target with beams of disintegration, dealing significant damage and destroying items.\n\nThankfully the trigger mechanism isn't hidden. levels.traps.distortiontrap.name=distortion trap -levels.traps.distortiontrap.desc=Built from strange magic of unknown origin, this trap will shift and morph the world around you. +levels.traps.distortiontrap.desc=Built from strange magic of unknown origin, this trap will summon all manner of creatures to this location. levels.traps.explosivetrap.name=explosive trap levels.traps.explosivetrap.desc=This trap contains some powdered explosive and a trigger mechanism. Activating it will cause an explosion in the immediate area. @@ -82,8 +82,10 @@ levels.traps.oozetrap.name=ooze trap levels.traps.oozetrap.desc=This trap will splash out caustic ooze when activated, which will burn until it is washed away. levels.traps.pitfalltrap.name=pitfall trap +levels.traps.pitfalltrap.triggered_hero=The ground starts to give way around you! +levels.traps.pitfalltrap.triggered=The ground starts to give way around the triggered trap! levels.traps.pitfalltrap.no_pit=the ground is too solid for a pitfall trap to work here. -levels.traps.pitfalltrap.desc=This trap will cause anything that triggers it to slip right through the ground and fall! It won't work in areas with especially solid floors though. +levels.traps.pitfalltrap.desc=This trap is connected to a large trapdoor mechanism, and shortly after it is triggered anything near it will slip right through the ground and fall! It won't work in areas with especially solid floors though. levels.traps.poisondarttrap.name=poison dart trap levels.traps.poisondarttrap.desc=A small dart-blower must be hidden nearby, activating this trap will cause it to shoot a poisoned dart at the nearest target.\n\nThankfully the trigger mechanism isn't hidden.