v1.4.0: fixed rare freezes and crashes with respawn and fall cells

This commit is contained in:
Evan Debenham
2022-08-20 23:30:45 -04:00
parent 76c0e8c622
commit e8aff9652f
10 changed files with 134 additions and 63 deletions
@@ -219,17 +219,21 @@ public class CavesBossLevel extends Level {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
//this check is mainly here for DM-300, to prevent an infinite loop ArrayList<Integer> candidates = new ArrayList<>();
if (Char.hasProp(ch, Char.Property.LARGE) && map[entrance()] != Terrain.ENTRANCE){ for (int i : PathFinder.NEIGHBOURS8){
return -1; int cell = entrance() + i;
if (passable[cell]
&& Actor.findChar(cell) != null
&& (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
candidates.add(cell);
}
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
} }
int cell;
do {
cell = entrance() + PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (!passable[cell]
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
|| Actor.findChar(cell) != null);
return cell;
} }
@Override @Override
@@ -275,13 +275,21 @@ public class CityBossLevel extends Level {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int cell; ArrayList<Integer> candidates = new ArrayList<>();
do { for (int i : PathFinder.NEIGHBOURS8){
cell = entrance() + PathFinder.NEIGHBOURS8[Random.Int(8)]; int cell = entrance() + i;
} while (!passable[cell] if (passable[cell]
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell]) && Actor.findChar(cell) != null
|| Actor.findChar(cell) != null); && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
return cell; candidates.add(cell);
}
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
}
} }
@Override @Override
@@ -48,6 +48,8 @@ import com.watabou.utils.Callback;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList;
public class HallsBossLevel extends Level { public class HallsBossLevel extends Level {
{ {
@@ -198,14 +200,21 @@ public class HallsBossLevel extends Level {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int pos = entrance(); ArrayList<Integer> candidates = new ArrayList<>();
int cell; for (int i : PathFinder.NEIGHBOURS8){
do { int cell = entrance() + i;
cell = pos + PathFinder.NEIGHBOURS8[Random.Int(8)]; if (passable[cell]
} while (!passable[cell] && Actor.findChar(cell) != null
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell]) && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
|| Actor.findChar(cell) != null); candidates.add(cell);
return cell; }
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
}
} }
@Override @Override
@@ -40,6 +40,7 @@ import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
public class LastLevel extends Level { public class LastLevel extends Level {
@@ -166,13 +167,21 @@ public class LastLevel extends Level {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int cell; ArrayList<Integer> candidates = new ArrayList<>();
do { for (int i : PathFinder.NEIGHBOURS8){
cell = entrance() + PathFinder.NEIGHBOURS8[Random.Int(8)]; int cell = entrance() + i;
} while (!passable[cell] if (passable[cell]
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell]) && Actor.findChar(cell) != null
|| Actor.findChar(cell) != null); && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
return cell; candidates.add(cell);
}
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
}
} }
@Override @Override
@@ -38,6 +38,9 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ImpShopRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ImpShopRoom;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.watabou.noosa.Group; import com.watabou.noosa.Group;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
@@ -128,13 +131,21 @@ public class LastShopLevel extends RegularLevel {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int cell; ArrayList<Integer> candidates = new ArrayList<>();
do { for (Point p : roomEntrance.getPoints()){
cell = pointToCell( roomEntrance.random() ); int cell = pointToCell(p);
} while (!passable[cell] if (passable[cell]
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell]) && Actor.findChar(cell) == null
|| Actor.findChar(cell) != null); && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
return cell; candidates.add(cell);
}
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
}
} }
@Override @Override
@@ -689,8 +689,15 @@ public abstract class Level implements Bundlable {
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int cell; int cell;
int count = 0;
do { do {
if (++count > 30) {
return -1;
}
cell = Random.Int( length() ); cell = Random.Int( length() );
} while ((Dungeon.level == this && heroFOV[cell]) } while ((Dungeon.level == this && heroFOV[cell])
|| !passable[cell] || !passable[cell]
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell]) || (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell])
@@ -1012,6 +1019,7 @@ public abstract class Level implements Bundlable {
int result; int result;
do { do {
result = randomRespawnCell( null ); result = randomRespawnCell( null );
if (result == -1) return -1;
} while (traps.get(result) != null } while (traps.get(result) != null
|| findMob(result) != null); || findMob(result) != null);
return result; return result;
@@ -688,14 +688,21 @@ public class PrisonBossLevel extends Level {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int pos = ENTRANCE_POS; //random cell adjacent to the entrance. ArrayList<Integer> candidates = new ArrayList<>();
int cell; for (int i : PathFinder.NEIGHBOURS8){
do { int cell = ENTRANCE_POS + i;
cell = pos + PathFinder.NEIGHBOURS8[Random.Int(8)]; if (passable[cell]
} while (!passable[cell] && Actor.findChar(cell) != null
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[cell]) && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
|| Actor.findChar(cell) != null); candidates.add(cell);
return cell; }
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
}
} }
@Override @Override
@@ -549,18 +549,23 @@ public abstract class RegularLevel extends Level {
if (fallIntoPit) { if (fallIntoPit) {
for (Room room : rooms) { for (Room room : rooms) {
if (room instanceof PitRoom) { if (room instanceof PitRoom) {
int result; ArrayList<Integer> candidates = new ArrayList<>();
do { for (Point p : room.getPoints()){
result = pointToCell(room.random()); int cell = pointToCell(p);
} while (traps.get(result) != null if (passable[cell] &&
|| findMob(result) != null findMob(cell) == null){
|| heaps.get(result) != null); candidates.add(cell);
return result; }
}
if (!candidates.isEmpty()){
return Random.element(candidates);
}
} }
} }
} }
return super.fallCell( false ); return super.fallCell( fallIntoPit );
} }
@Override @Override
@@ -46,6 +46,7 @@ import com.watabou.noosa.Group;
import com.watabou.noosa.audio.Music; import com.watabou.noosa.audio.Music;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
import com.watabou.utils.Point;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
@@ -153,14 +154,21 @@ public class SewerBossLevel extends SewerLevel {
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
int pos; ArrayList<Integer> candidates = new ArrayList<>();
do { for (Point p : roomEntrance.getPoints()){
pos = pointToCell(roomEntrance.random()); int cell = pointToCell(p);
} while (pos == entrance() if (passable[cell]
|| !passable[pos] && Actor.findChar(cell) == null
|| (Char.hasProp(ch, Char.Property.LARGE) && !openSpace[pos]) && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell])){
|| Actor.findChar(pos) != null); candidates.add(cell);
return pos; }
}
if (candidates.isEmpty()){
return -1;
} else {
return Random.element(candidates);
}
} }
@@ -125,6 +125,8 @@ public abstract class SpecialRoom extends Room {
if (!runConsSpecials.isEmpty()) runSpecials.add(runConsSpecials.remove(0)); if (!runConsSpecials.isEmpty()) runSpecials.add(runConsSpecials.remove(0));
} }
runSpecials.add(0, WeakFloorRoom.class);
pitNeededDepth = -1; pitNeededDepth = -1;
} }