v2.5.0: added checks for load into invalid cells in caves & city boss

This commit is contained in:
Evan Debenham
2024-08-08 14:19:36 -04:00
parent c8b4b87e0c
commit 5373b1388d
5 changed files with 38 additions and 6 deletions

View File

@@ -464,10 +464,9 @@ public class Dungeon {
if (t != null) pos = t.cell(); if (t != null) pos = t.cell();
} }
//Place hero at the entrance if they are out of the map (often used for pox = -1) //Place hero at the entrance if they are out of the map (often used for pos = -1)
// or if they are in solid terrain (except in the mining level, where that happens normally) // or if they are in invalid terrain terrain (except in the mining level, where that happens normally)
if (pos < 0 || pos >= level.length() if (pos < 0 || pos >= level.length() || level.invalidHeroPos(pos)){
|| (!(level instanceof MiningLevel) && !level.passable[pos] && !level.avoid[pos])){
pos = level.getTransition(null).cell(); pos = level.getTransition(null).cell();
} }

View File

@@ -256,6 +256,20 @@ public class CavesBossLevel extends Level {
return super.setCellToWater(includeTraps, cell); return super.setCellToWater(includeTraps, cell);
} }
@Override
public boolean invalidHeroPos(int tile) {
//hero cannot be above gate, or above arena, when gate is closed
if (map[gate.left + gate.top*width()] == Terrain.CUSTOM_DECO){
Point p = cellToPoint(tile);
if (p.y < diggableArea.top){
return true;
} else if (p.y < gate.bottom && p.x >= gate.left && p.x < gate.right){
return true;
}
}
return super.invalidHeroPos(tile);
}
@Override @Override
public void occupyCell(Char ch) { public void occupyCell(Char ch) {
//seal the level when the hero moves near to a pylon, the level isn't already sealed, and the gate hasn't been destroyed //seal the level when the hero moves near to a pylon, the level isn't already sealed, and the gate hasn't been destroyed
@@ -330,8 +344,8 @@ public class CavesBossLevel extends Level {
blobs.get(PylonEnergy.class).fullyClear(); blobs.get(PylonEnergy.class).fullyClear();
set( entrance(), Terrain.ENTRANCE ); set( entrance(), Terrain.ENTRANCE );
int i = 14 + 13*width(); int i = gate.top*width();
for (int j = 0; j < 5; j++){ for (int j = gate.left; j < gate.right; j++){
set( i+j, Terrain.EMPTY ); set( i+j, Terrain.EMPTY );
if (Dungeon.level.heroFOV[i+j]){ if (Dungeon.level.heroFOV[i+j]){
CellEmitter.get(i+j).burst(BlastParticle.FACTORY, 10); CellEmitter.get(i+j).burst(BlastParticle.FACTORY, 10);

View File

@@ -293,6 +293,15 @@ public class CityBossLevel extends Level {
} }
} }
@Override
public boolean invalidHeroPos(int tile) {
//hero cannot be above top door if it is locked
if (map[topDoor] == Terrain.LOCKED_DOOR && tile <= topDoor){
return true;
}
return super.invalidHeroPos(tile);
}
@Override @Override
public void occupyCell( Char ch ) { public void occupyCell( Char ch ) {
if (map[bottomDoor] != Terrain.LOCKED_DOOR && map[topDoor] == Terrain.LOCKED_DOOR if (map[bottomDoor] != Terrain.LOCKED_DOOR && map[topDoor] == Terrain.LOCKED_DOOR

View File

@@ -1467,6 +1467,11 @@ public abstract class Level implements Bundlable {
return (float)Math.sqrt(Math.pow(Math.abs( ax - bx ), 2) + Math.pow(Math.abs( ay - by ), 2)); return (float)Math.sqrt(Math.pow(Math.abs( ax - bx ), 2) + Math.pow(Math.abs( ay - by ), 2));
} }
//usually just if a cell is solid, but other cases exist too
public boolean invalidHeroPos( int tile ){
return !passable[tile] && !avoid[tile];
}
//returns true if the input is a valid tile within the level //returns true if the input is a valid tile within the level
public boolean insideMap( int tile ){ public boolean insideMap( int tile ){
//top and bottom row and beyond //top and bottom row and beyond

View File

@@ -333,6 +333,11 @@ public class MiningLevel extends CavesLevel {
return wallVisuals; return wallVisuals;
} }
@Override
public boolean invalidHeroPos(int tile) {
return false; //solid tiles are fine for hero to be in here
}
public static class BorderTopDarken extends CustomTilemap { public static class BorderTopDarken extends CustomTilemap {
{ {