v0.4.2: implemented path storage for better pathfinder performance

This commit is contained in:
Evan Debenham 2016-08-30 18:33:16 -04:00
parent e067901f0d
commit 01aad4196c
3 changed files with 104 additions and 15 deletions

View File

@ -67,6 +67,7 @@ public abstract class Char extends Actor {
public int SHLD;
protected float baseSpeed = 1;
protected PathFinder.Path path;
public int paralysed = 0;
public boolean rooted = false;

View File

@ -1013,6 +1013,9 @@ public class Hero extends Char {
private boolean getCloser( final int target ) {
if (target == pos)
return false;
if (rooted) {
Camera.main.shake( 1, 1f );
return false;
@ -1022,6 +1025,8 @@ public class Hero extends Char {
if (Dungeon.level.adjacent( pos, target )) {
path = null;
if (Actor.findChar( target ) == null) {
if (Level.pit[target] && !flying && !Level.solid[target]) {
if (!Chasm.jumpConfirmed){
@ -1039,16 +1044,40 @@ public class Hero extends Char {
} else {
int len = Dungeon.level.length();
boolean[] p = Level.passable;
boolean[] v = Dungeon.level.visited;
boolean[] m = Dungeon.level.mapped;
boolean[] passable = new boolean[len];
for (int i=0; i < len; i++) {
passable[i] = p[i] && (v[i] || m[i]);
boolean newPath = false;
if (path == null || path.isEmpty())
newPath = true;
else if (path.getLast() != target)
newPath = true;
else {
//checks 2 cells ahead for validity.
//Note that this is shorter than for mobs, so that mobs usually yield to the hero
for (int i = 0; i < Math.min(path.size(), 2); i++){
int cell = path.get(i);
if (!Level.passable[cell] || ((i != path.size()-1) && Dungeon.visible[cell] && Actor.findChar(cell) != null)) {
newPath = true;
break;
}
}
}
step = Dungeon.findStep( this, pos, target, passable, Level.fieldOfView );
if (newPath) {
int len = Dungeon.level.length();
boolean[] p = Level.passable;
boolean[] v = Dungeon.level.visited;
boolean[] m = Dungeon.level.mapped;
boolean[] passable = new boolean[len];
for (int i = 0; i < len; i++) {
passable[i] = p[i] && (v[i] || m[i]);
}
path = Dungeon.findPath(this, pos, target, passable, Level.fieldOfView);
}
if (path == null) return false;
step = path.removeFirst();
}
if (step != -1) {

View File

@ -290,13 +290,72 @@ public abstract class Mob extends Char {
protected boolean getCloser( int target ) {
if (rooted) {
if (rooted || target == pos) {
return false;
}
int step = Dungeon.findStep( this, pos, target,
Level.passable,
Level.fieldOfView );
boolean newPath = false;
if (path == null || path.isEmpty())
newPath = true;
else if (path.getLast() != target) {
//if the new target is adjacent to the end of the path, adjust for that
//rather than scrapping the whole path
if (Dungeon.level.adjacent(target, path.getLast())){
int last = path.removeLast();
if (path.isEmpty()) {
//shorten for a closer one
if (Dungeon.level.adjacent(target, pos)) {
path.add(target);
//extend the path for a further target
} else {
path.add(last);
path.add(target);
}
} else if (!path.isEmpty()){
//if the new target is simply 1 earlier in the path shorten the path
if (path.getLast() == target) {
//if the new target is closer/same, need to modify end of path
} else if (Dungeon.level.adjacent(target, path.getLast())){
path.add(target);
//if the new target is further away, need to extend the path
} else {
path.add(last);
path.add(target);
}
}
} else {
newPath = true;
}
}
if (!newPath){
//checks the next 4 cells in the path for validity
for (int i = 0; i < Math.min(path.size(), 4); i++){
int cell = path.get(i);
if (!Level.passable[cell] || ((i != path.size()-1) && Dungeon.visible[cell] && Actor.findChar(cell) != null)) {
newPath = true;
break;
}
}
}
if (newPath) {
path = Dungeon.findPath(this, pos, target,
Level.passable,
Level.fieldOfView);
}
if (path == null)
return false;
int step = path.removeFirst();
if (step != -1) {
move( step );
return true;
@ -467,7 +526,7 @@ public abstract class Mob extends Char {
float lootChance = this.lootChance;
int bonus = RingOfWealth.getBonus(Dungeon.hero, RingOfWealth.Wealth.class);
lootChance *= Math.pow(1.1, bonus);
lootChance *= Math.pow(1.15, bonus);
if (Random.Float() < lootChance && Dungeon.hero.lvl <= maxLvl + 2) {
Item loot = createLoot();