v1.2.0: improved logic for magical fire and toxic gas rooms
This commit is contained in:
parent
542eae1bef
commit
f58edf216e
|
@ -300,7 +300,7 @@ public abstract class RegularLevel extends Level {
|
|||
continue;
|
||||
}
|
||||
|
||||
ArrayList<Point> points = room.charWanderablePoints(this);
|
||||
ArrayList<Point> points = room.charPlaceablePoints(this);
|
||||
if (!points.isEmpty()){
|
||||
cell = pointToCell(Random.element(points));
|
||||
if (passable[cell] && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])) {
|
||||
|
|
|
@ -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<Point> charWanderablePoints(Level l){
|
||||
ArrayList<Point> 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 ****
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user