v2.4.0: improve behavior for existing entrance/exit rooms

This commit is contained in:
Evan Debenham
2024-04-17 14:37:39 -04:00
parent 769c459aa7
commit cc80f8a391
10 changed files with 63 additions and 36 deletions

View File

@@ -260,7 +260,7 @@ public class Dungeon {
QuickSlotButton.reset();
Toolbar.swappedQuickslots = false;
depth = 15;
depth = 1;
branch = 0;
generatedLevels.clear();

View File

@@ -49,7 +49,7 @@ public class ShrapnelBomb extends Bomb {
boolean[] FOV = new boolean[Dungeon.level.length()];
Point c = Dungeon.level.cellToPoint(cell);
ShadowCaster.castShadow(c.x, c.y, FOV, Dungeon.level.losBlocking, 8);
ShadowCaster.castShadow(c.x, c.y, Dungeon.level.width(), FOV, Dungeon.level.losBlocking, 8);
ArrayList<Char> affected = new ArrayList<>();

View File

@@ -113,7 +113,7 @@ public class ScrollOfChallenge extends ExoticScroll {
boolean[] visibleCells = new boolean[Dungeon.level.length()];
Point c = Dungeon.level.cellToPoint(pos);
ShadowCaster.castShadow(c.x, c.y, visibleCells, Dungeon.level.losBlocking, 8);
ShadowCaster.castShadow(c.x, c.y, Dungeon.level.width(), visibleCells, Dungeon.level.losBlocking, 8);
int count=0;
for (boolean b : visibleCells){
if (b) count++;

View File

@@ -47,7 +47,7 @@ public class StoneOfDisarming extends Runestone {
protected void activate(final int cell) {
boolean[] FOV = new boolean[Dungeon.level.length()];
Point c = Dungeon.level.cellToPoint(cell);
ShadowCaster.castShadow(c.x, c.y, FOV, Dungeon.level.losBlocking, DIST);
ShadowCaster.castShadow(c.x, c.y, Dungeon.level.width(), FOV, Dungeon.level.losBlocking, DIST);
int sX = Math.max(0, c.x - DIST);
int eX = Math.min(Dungeon.level.width()-1, c.x + DIST);

View File

@@ -1290,7 +1290,7 @@ public abstract class Level implements Bundlable {
viewDist *= 1f + 0.25f*((Hero) c).pointsInTalent(Talent.FARSIGHT);
}
ShadowCaster.castShadow( cx, cy, fieldOfView, blocking, viewDist );
ShadowCaster.castShadow( cx, cy, width(), fieldOfView, blocking, viewDist );
} else {
BArray.setFalse(fieldOfView);
}

View File

@@ -61,9 +61,9 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.MagicalFire
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.PitRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.entrance.EntranceRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.exit.ExitRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BlazingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.BurningTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ChillingTrap;
@@ -73,6 +73,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.PitfallTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.WornDartTrap;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ShadowCaster;
import com.watabou.utils.Bundle;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
@@ -213,7 +214,7 @@ public abstract class RegularLevel extends Level {
ArrayList<Room> stdRooms = new ArrayList<>();
for (Room room : rooms) {
if (room instanceof StandardRoom && room != roomEntrance) {
if (room instanceof StandardRoom) {
for (int i = 0; i < ((StandardRoom) room).mobSpawnWeight(); i++) {
stdRooms.add(room);
}
@@ -222,6 +223,10 @@ public abstract class RegularLevel extends Level {
Random.shuffle(stdRooms);
Iterator<Room> stdRoomIter = stdRooms.iterator();
boolean[] entranceFOV = new boolean[length()];
Point c = cellToPoint(entrance());
ShadowCaster.castShadow(c.x, c.y, width(), entranceFOV, losBlocking, 8);
while (mobsToSpawn > 0) {
Mob mob = createMob();
Room roomToSpawn;
@@ -236,6 +241,7 @@ public abstract class RegularLevel extends Level {
mob.pos = pointToCell(roomToSpawn.random());
tries--;
} while (tries >= 0 && (findMob(mob.pos) != null
|| entranceFOV[mob.pos] || (roomToSpawn.isEntrance() && distance(entrance(), mob.pos) <= 5)
|| !passable[mob.pos]
|| solid[mob.pos]
|| !roomToSpawn.canPlaceCharacter(cellToPoint(mob.pos), this)
@@ -256,6 +262,7 @@ public abstract class RegularLevel extends Level {
mob.pos = pointToCell(roomToSpawn.random());
tries--;
} while (tries >= 0 && (findMob(mob.pos) != null
|| entranceFOV[mob.pos] || (roomToSpawn.isEntrance() && distance(entrance(), mob.pos) <= 5)
|| !passable[mob.pos]
|| solid[mob.pos]
|| !roomToSpawn.canPlaceCharacter(cellToPoint(mob.pos), this)

View File

@@ -30,18 +30,24 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret.SecretRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CaveRoom;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTilemap;
import com.watabou.noosa.Image;
import com.watabou.noosa.Tilemap;
import com.watabou.utils.GameMath;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class MineEntrance extends StandardRoom {
public class MineEntrance extends CaveRoom {
@Override
public float[] sizeCatProbs() {
return new float[]{1, 0, 0};
}
@Override
public int minWidth() {
@@ -60,19 +66,24 @@ public class MineEntrance extends StandardRoom {
@Override
public void paint(Level level) {
Painter.fill( level, this, Terrain.WALL );
Painter.fill( level, this, 1, Terrain.EMPTY );
for (Door door : connected.values()) {
door.set( Door.Type.REGULAR );
}
super.paint(level);
int entrance;
boolean valid = false;
do {
entrance = level.pointToCell(random(3));
} while (level.findMob(entrance) != null || level.map[entrance] == Terrain.WALL);
for (int i : PathFinder.NEIGHBOURS9){
if (level.map[entrance+i] != Terrain.WALL){
valid = true;
}
}
} while (level.findMob(entrance) != null || !valid);
Painter.set( level, entrance, Terrain.ENTRANCE );
for (int i : PathFinder.NEIGHBOURS8){
Painter.set( level, entrance+i, Terrain.EMPTY );
}
QuestExit vis = new QuestExit();
Point e = level.cellToPoint(entrance);
vis.pos(e.x - 1, e.y - 1);
@@ -88,7 +99,8 @@ public class MineEntrance extends StandardRoom {
if (Blacksmith.Quest.Type() == Blacksmith.Quest.CRYSTAL){
for (int i = 0; i < width()*height()/2; i ++){
Point r = random(1);
if (level.distance(level.pointToCell(r), entrance) > 1) {
if (level.distance(level.pointToCell(r), entrance) > 1
&& level.map[level.pointToCell(r)] != Terrain.WALL) {
Painter.set(level, r, Terrain.MINE_CRYSTAL);
}
}

View File

@@ -54,7 +54,11 @@ public class EntranceRoom extends StandardRoom {
@Override
public boolean canMerge(Level l, Point p, int mergeTerrain) {
return false;
if (Dungeon.depth <= 2) {
return false;
} else {
return super.canMerge(l, p, mergeTerrain);
}
}
@Override

View File

@@ -40,7 +40,12 @@ public class ExitRoom extends StandardRoom {
public int minHeight() {
return Math.max(super.minHeight(), 5);
}
@Override
public boolean isExit() {
return true;
}
public void paint(Level level) {
Painter.fill( level, this, Terrain.WALL );

View File

@@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.mechanics;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.watabou.utils.BArray;
@@ -46,7 +45,7 @@ public final class ShadowCaster {
}
}
public static void castShadow( int x, int y, boolean[] fieldOfView, boolean[] blocking, int distance ) {
public static void castShadow( int x, int y, int w, boolean[] fieldOfView, boolean[] blocking, int distance ) {
if (distance >= MAX_DISTANCE){
distance = MAX_DISTANCE;
@@ -55,18 +54,18 @@ public final class ShadowCaster {
BArray.setFalse(fieldOfView);
//set source cell to true
fieldOfView[y * Dungeon.level.width() + x] = true;
fieldOfView[y * w + x] = true;
//scans octants, clockwise
try {
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, +1, -1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, -1, +1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, +1, +1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, +1, +1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, -1, +1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, +1, -1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, -1, -1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, 0.0, 1.0, -1, -1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, +1, -1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, -1, +1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, +1, +1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, +1, +1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, -1, +1, false);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, +1, -1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, -1, -1, true);
scanOctant(distance, fieldOfView, blocking, 1, x, y, w, 0.0, 1.0, -1, -1, false);
} catch (Exception e){
ShatteredPixelDungeon.reportException(e);
BArray.setFalse(fieldOfView);
@@ -77,7 +76,7 @@ public final class ShadowCaster {
//scans a single 45 degree octant of the FOV.
//This can add up to a whole FOV by mirroring in X(mX), Y(mY), and X=Y(mXY)
private static void scanOctant(int distance, boolean[] fov, boolean[] blocking, int row,
int x, int y, double lSlope, double rSlope,
int x, int y, int w, double lSlope, double rSlope,
int mX, int mY, boolean mXY){
boolean inBlocking = false;
@@ -112,11 +111,11 @@ public final class ShadowCaster {
(int)Math.ceil((row + 0.5) * rSlope - 0.499));
//coordinates of source
int cell = x + y*Dungeon.level.width();
int cell = x + y*w;
//plus coordinates of current cell (including mirroring in x, y, and x=y)
if (mXY) cell += mX*start*Dungeon.level.width() + mY*row;
else cell += mX*start + mY*row*Dungeon.level.width();
if (mXY) cell += mX*start*w + mY*row;
else cell += mX*start + mY*row*w;
//for each column in this row, which
for (col = start; col <= end; col++){
@@ -136,7 +135,7 @@ public final class ShadowCaster {
//start a new scan, 1 row deeper, ending at the left side of current cell
if (col != start){
scanOctant(distance, fov, blocking, row+1, x, y, lSlope,
scanOctant(distance, fov, blocking, row+1, x, y, w, lSlope,
//change in x over change in y
(col - 0.5) / (row + 0.5),
mX, mY, mXY);
@@ -155,7 +154,7 @@ public final class ShadowCaster {
}
if (!mXY) cell += mX;
else cell += mX*Dungeon.level.width();
else cell += mX*w;
}