From f58edf216eca84d2f80c3c54a0862c21e1835784 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Sat, 12 Mar 2022 23:53:00 -0500 Subject: [PATCH] v1.2.0: improved logic for magical fire and toxic gas rooms --- .../levels/RegularLevel.java | 2 +- .../levels/rooms/Room.java | 18 +------ .../levels/rooms/special/MagicalFireRoom.java | 49 ++++++++++++++----- .../levels/rooms/special/ToxicGasRoom.java | 20 +++++--- 4 files changed, 54 insertions(+), 35 deletions(-) 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 44a4950ba..bac305c08 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -300,7 +300,7 @@ public abstract class RegularLevel extends Level { continue; } - ArrayList points = room.charWanderablePoints(this); + ArrayList points = room.charPlaceablePoints(this); if (!points.isEmpty()){ cell = pointToCell(Random.element(points)); if (passable[cell] && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java index 21386d6ed..804a21962 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java @@ -329,7 +329,7 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable { return points; } - //whether or not a character (usually spawned) can be placed here + //whether or not a character can be placed here (usually via spawn, tele, or wander) public boolean canPlaceCharacter(Point p, Level l){ return inside(p); } @@ -345,22 +345,6 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable { return points; } - //whether or not a character can wander here - public boolean canCharacterWander(Point p, Level l) { - return inside(p); - } - - public final ArrayList charWanderablePoints(Level l){ - ArrayList points = new ArrayList<>(); - for (int i = left; i <= right; i++) { - for (int j = top; j <= bottom; j++) { - Point p = new Point(i, j); - if (canCharacterWander(p, l)) points.add(p); - } - } - return points; - } - // **** Graph.Node interface **** diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java index 5f491664e..7384e6479 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blizzard; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire; @@ -56,8 +57,6 @@ public class MagicalFireRoom extends SpecialRoom { Door door = entrance(); door.set( Door.Type.REGULAR ); - int x = -1; - int y = -1; Point firePos = center(); Room behindFire = new EmptyRoom(); @@ -114,6 +113,25 @@ public class MagicalFireRoom extends SpecialRoom { return false; } + @Override + public boolean canPlaceCharacter(Point p, Level l) { + Blob fire = l.blobs.get(EternalFire.class); + + //disallow placing on special tiles or next to fire if fire is present. + //note that this is slightly brittle, assumes the fire is either all there or totally gone + if (fire != null && fire.volume > 0){ + int cell = l.pointToCell(p); + if (l.map[cell] == Terrain.EMPTY_SP) return false; + + if (fire.cur[cell] > 0) return false; + for (int i : PathFinder.NEIGHBOURS4){ + if (fire.cur[cell+i] > 0) return false; + } + } + + return super.canPlaceCharacter(p, l); + } + public static class EternalFire extends Fire { @Override protected void evolve() { @@ -123,6 +141,10 @@ public class MagicalFireRoom extends SpecialRoom { Freezing freeze = (Freezing)Dungeon.level.blobs.get( Freezing.class ); Blizzard bliz = (Blizzard)Dungeon.level.blobs.get( Blizzard.class ); + //if any part of the fire is cleared, cleanse the whole thing + //Note that this is a bit brittle atm, it assumes only one group of eternal fire per floor + boolean clearAll = false; + Level l = Dungeon.level; for (int i = area.left; i < area.right; i++){ for (int j = area.top; j < area.bottom; j++){ @@ -136,23 +158,25 @@ public class MagicalFireRoom extends SpecialRoom { //potion of purity can cleanse it though if (l.water[cell]){ cur[cell] = 0; + clearAll = true; } if (freeze != null && freeze.volume > 0 && freeze.cur[cell] > 0){ freeze.clear(cell); cur[cell] = 0; + clearAll = true; } if (bliz != null && bliz.volume > 0 && bliz.cur[cell] > 0){ bliz.clear(cell); cur[cell] = 0; + clearAll = true; } - //if the hero is adjacent, set them on fire briefly - //TODO all chars, but prevent random wandering into the fire? + //if a char is adjacent, set them on fire briefly if (cur[cell] > 0){ for (int k : PathFinder.NEIGHBOURS4){ - if (Actor.findChar(cell+k) == Dungeon.hero - && !Dungeon.hero.isImmune(getClass())){ - Buff.affect(Dungeon.hero, Burning.class).reignite(Dungeon.hero, 4f); + Char ch = Actor.findChar(cell+k); + if (ch != null && !ch.isImmune(getClass())){ + Buff.affect(ch, Burning.class).reignite(ch, 4f); } } } @@ -160,6 +184,12 @@ public class MagicalFireRoom extends SpecialRoom { l.passable[cell] = cur[cell] == 0 && (Terrain.flags[l.map[cell]] & Terrain.PASSABLE) != 0; } } + + if (clearAll){ + fullyClear(); + return; + } + super.evolve(); } @@ -171,10 +201,7 @@ public class MagicalFireRoom extends SpecialRoom { @Override public void clear(int cell) { - super.clear(cell); - if (cur == null) return; - Level l = Dungeon.level; - l.passable[cell] = cur[cell] == 0 && (Terrain.flags[l.map[cell]] & Terrain.PASSABLE) != 0; + fullyClear(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java index bc75caf40..4171e1db3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java @@ -47,7 +47,8 @@ public class ToxicGasRoom extends SpecialRoom { for (Point p : getPoints()){ int cell = level.pointToCell(p); if (level.map[cell] == Terrain.EMPTY) { - Blob.seed(cell, 3, ToxicGasSeed.class, level); + //as if gas has been spreading in the room for a while + Blob.seed(cell, 30, ToxicGas.class, level); } } @@ -56,9 +57,10 @@ public class ToxicGasRoom extends SpecialRoom { for (int i = 0; i < traps; i++){ int cell; do { - cell = level.pointToCell(random(1)); + cell = level.pointToCell(random(2)); } while (level.map[cell] == Terrain.INACTIVE_TRAP); level.setTrap(new ToxicVent().reveal(), cell); + Blob.seed(cell, 12, ToxicGasSeed.class, level); Painter.set(level, cell, Terrain.INACTIVE_TRAP); } @@ -72,8 +74,9 @@ public class ToxicGasRoom extends SpecialRoom { } @Override - public boolean canCharacterWander(Point p, Level l) { - return false; + public boolean canPlaceCharacter(Point p, Level l) { + Blob gas = l.blobs.get(ToxicGas.class); + return gas == null || gas.volume == 0 || gas.cur[l.pointToCell(p)] == 0; } public static class ToxicGasSeed extends Blob { @@ -86,13 +89,18 @@ public class ToxicGasRoom extends SpecialRoom { for (int j = area.left-1; j <= area.right; j++) { cell = j + i* Dungeon.level.width(); if (Dungeon.level.insideMap(cell)) { + if (Dungeon.level.map[cell] != Terrain.INACTIVE_TRAP){ + off[cell] = 0; + continue; + } + off[cell] = cur[cell]; volume += off[cell]; if (gas == null || gas.volume == 0){ GameScene.add(Blob.seed(cell, off[cell], ToxicGas.class)); - } else if (gas.cur[cell] < off[cell]){ - GameScene.add(Blob.seed(cell, off[cell] - gas.cur[cell], ToxicGas.class)); + } else if (gas.cur[cell] <= 9*off[cell]){ + GameScene.add(Blob.seed(cell, off[cell], ToxicGas.class)); } } }