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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<Point> points = room.charWanderablePoints(this);
|
ArrayList<Point> points = room.charPlaceablePoints(this);
|
||||||
if (!points.isEmpty()){
|
if (!points.isEmpty()){
|
||||||
cell = pointToCell(Random.element(points));
|
cell = pointToCell(Random.element(points));
|
||||||
if (passable[cell] && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])) {
|
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;
|
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){
|
public boolean canPlaceCharacter(Point p, Level l){
|
||||||
return inside(p);
|
return inside(p);
|
||||||
}
|
}
|
||||||
|
@ -345,22 +345,6 @@ public abstract class Room extends Rect implements Graph.Node, Bundlable {
|
||||||
return points;
|
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 ****
|
// **** Graph.Node interface ****
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
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.Blizzard;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
||||||
|
@ -56,8 +57,6 @@ public class MagicalFireRoom extends SpecialRoom {
|
||||||
Door door = entrance();
|
Door door = entrance();
|
||||||
door.set( Door.Type.REGULAR );
|
door.set( Door.Type.REGULAR );
|
||||||
|
|
||||||
int x = -1;
|
|
||||||
int y = -1;
|
|
||||||
Point firePos = center();
|
Point firePos = center();
|
||||||
Room behindFire = new EmptyRoom();
|
Room behindFire = new EmptyRoom();
|
||||||
|
|
||||||
|
@ -114,6 +113,25 @@ public class MagicalFireRoom extends SpecialRoom {
|
||||||
return false;
|
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 {
|
public static class EternalFire extends Fire {
|
||||||
@Override
|
@Override
|
||||||
protected void evolve() {
|
protected void evolve() {
|
||||||
|
@ -123,6 +141,10 @@ public class MagicalFireRoom extends SpecialRoom {
|
||||||
Freezing freeze = (Freezing)Dungeon.level.blobs.get( Freezing.class );
|
Freezing freeze = (Freezing)Dungeon.level.blobs.get( Freezing.class );
|
||||||
Blizzard bliz = (Blizzard)Dungeon.level.blobs.get( Blizzard.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;
|
Level l = Dungeon.level;
|
||||||
for (int i = area.left; i < area.right; i++){
|
for (int i = area.left; i < area.right; i++){
|
||||||
for (int j = area.top; j < area.bottom; j++){
|
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
|
//potion of purity can cleanse it though
|
||||||
if (l.water[cell]){
|
if (l.water[cell]){
|
||||||
cur[cell] = 0;
|
cur[cell] = 0;
|
||||||
|
clearAll = true;
|
||||||
}
|
}
|
||||||
if (freeze != null && freeze.volume > 0 && freeze.cur[cell] > 0){
|
if (freeze != null && freeze.volume > 0 && freeze.cur[cell] > 0){
|
||||||
freeze.clear(cell);
|
freeze.clear(cell);
|
||||||
cur[cell] = 0;
|
cur[cell] = 0;
|
||||||
|
clearAll = true;
|
||||||
}
|
}
|
||||||
if (bliz != null && bliz.volume > 0 && bliz.cur[cell] > 0){
|
if (bliz != null && bliz.volume > 0 && bliz.cur[cell] > 0){
|
||||||
bliz.clear(cell);
|
bliz.clear(cell);
|
||||||
cur[cell] = 0;
|
cur[cell] = 0;
|
||||||
|
clearAll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the hero is adjacent, set them on fire briefly
|
//if a char is adjacent, set them on fire briefly
|
||||||
//TODO all chars, but prevent random wandering into the fire?
|
|
||||||
if (cur[cell] > 0){
|
if (cur[cell] > 0){
|
||||||
for (int k : PathFinder.NEIGHBOURS4){
|
for (int k : PathFinder.NEIGHBOURS4){
|
||||||
if (Actor.findChar(cell+k) == Dungeon.hero
|
Char ch = Actor.findChar(cell+k);
|
||||||
&& !Dungeon.hero.isImmune(getClass())){
|
if (ch != null && !ch.isImmune(getClass())){
|
||||||
Buff.affect(Dungeon.hero, Burning.class).reignite(Dungeon.hero, 4f);
|
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;
|
l.passable[cell] = cur[cell] == 0 && (Terrain.flags[l.map[cell]] & Terrain.PASSABLE) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clearAll){
|
||||||
|
fullyClear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
super.evolve();
|
super.evolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,10 +201,7 @@ public class MagicalFireRoom extends SpecialRoom {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear(int cell) {
|
public void clear(int cell) {
|
||||||
super.clear(cell);
|
fullyClear();
|
||||||
if (cur == null) return;
|
|
||||||
Level l = Dungeon.level;
|
|
||||||
l.passable[cell] = cur[cell] == 0 && (Terrain.flags[l.map[cell]] & Terrain.PASSABLE) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -47,7 +47,8 @@ public class ToxicGasRoom extends SpecialRoom {
|
||||||
for (Point p : getPoints()){
|
for (Point p : getPoints()){
|
||||||
int cell = level.pointToCell(p);
|
int cell = level.pointToCell(p);
|
||||||
if (level.map[cell] == Terrain.EMPTY) {
|
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++){
|
for (int i = 0; i < traps; i++){
|
||||||
int cell;
|
int cell;
|
||||||
do {
|
do {
|
||||||
cell = level.pointToCell(random(1));
|
cell = level.pointToCell(random(2));
|
||||||
} while (level.map[cell] == Terrain.INACTIVE_TRAP);
|
} while (level.map[cell] == Terrain.INACTIVE_TRAP);
|
||||||
level.setTrap(new ToxicVent().reveal(), cell);
|
level.setTrap(new ToxicVent().reveal(), cell);
|
||||||
|
Blob.seed(cell, 12, ToxicGasSeed.class, level);
|
||||||
Painter.set(level, cell, Terrain.INACTIVE_TRAP);
|
Painter.set(level, cell, Terrain.INACTIVE_TRAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +74,9 @@ public class ToxicGasRoom extends SpecialRoom {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canCharacterWander(Point p, Level l) {
|
public boolean canPlaceCharacter(Point p, Level l) {
|
||||||
return false;
|
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 {
|
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++) {
|
for (int j = area.left-1; j <= area.right; j++) {
|
||||||
cell = j + i* Dungeon.level.width();
|
cell = j + i* Dungeon.level.width();
|
||||||
if (Dungeon.level.insideMap(cell)) {
|
if (Dungeon.level.insideMap(cell)) {
|
||||||
|
if (Dungeon.level.map[cell] != Terrain.INACTIVE_TRAP){
|
||||||
|
off[cell] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
off[cell] = cur[cell];
|
off[cell] = cur[cell];
|
||||||
volume += off[cell];
|
volume += off[cell];
|
||||||
|
|
||||||
if (gas == null || gas.volume == 0){
|
if (gas == null || gas.volume == 0){
|
||||||
GameScene.add(Blob.seed(cell, off[cell], ToxicGas.class));
|
GameScene.add(Blob.seed(cell, off[cell], ToxicGas.class));
|
||||||
} else if (gas.cur[cell] < off[cell]){
|
} else if (gas.cur[cell] <= 9*off[cell]){
|
||||||
GameScene.add(Blob.seed(cell, off[cell] - gas.cur[cell], ToxicGas.class));
|
GameScene.add(Blob.seed(cell, off[cell], ToxicGas.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user