fixed a bug in leader movement by using pathdist; also made pathdist more robust

This commit is contained in:
Zeno Rogue 2018-06-28 11:42:25 +02:00
parent ad74267080
commit c6412511f5
3 changed files with 77 additions and 51 deletions

109
game.cpp
View File

@ -2747,12 +2747,32 @@ bool nogoSlow(cell *to, cell *from) {
cell *pd_from; cell *pd_from;
int pd_range; int pd_range;
void onpath(cell *c, int d) {
c->pathdist = d;
pathq.push_back(c);
}
void onpath(cell *c, int d, int sp) {
c->pathdist = d;
pathq.push_back(c);
reachedfrom.push_back(sp);
}
void clear_pathdata() {
for(auto c: pathq) c->pathdist = PINFD;
pathq.clear();
pathqm.clear();
reachedfrom.clear();
}
int pathlock = 0;
void compute_graphical_distance() { void compute_graphical_distance() {
if(pathlock) { printf("path error: compute_graphical_distance\n"); }
cell *c1 = centerover.c ? centerover.c : pd_from ? pd_from : cwt.c; cell *c1 = centerover.c ? centerover.c : pd_from ? pd_from : cwt.c;
int sr = get_sightrange_ambush(); int sr = get_sightrange_ambush();
if(pd_from == c1 && pd_range == sr) return; if(pd_from == c1 && pd_range == sr) return;
for(auto c: pathq) c->pathdist = PINFD; clear_pathdata();
pathq.clear();
pd_from = c1; pd_from = c1;
pd_range = sr; pd_range = sr;
@ -2765,23 +2785,14 @@ void compute_graphical_distance() {
if(qb == 0) forCellCM(c1, c) ; if(qb == 0) forCellCM(c1, c) ;
forCellEx(c1, c) forCellEx(c1, c)
if(c1->pathdist == PINFD) if(c1->pathdist == PINFD)
c1->pathdist = c->pathdist + 1, onpath(c1, c->pathdist + 1);
pathq.push_back(c1);
} }
} }
void computePathdist(eMonster param) { void computePathdist(eMonster param) {
pd_from = NULL;
for(auto c: pathq) c->pathdist = PINFD;
pathq.clear();
pathqm.clear();
reachedfrom.clear();
for(int i=0; i<isize(targets); i++) { for(cell *c: targets)
pathq.push_back(targets[i]); onpath(c, isPlayerOn(c) ? 0 : 1, hrand(c->type));
targets[i]->pathdist = isPlayerOn(targets[i]) ? 0 : 1;
reachedfrom.push_back(hrand(targets[i]->type));
}
int qtarg = isize(targets); int qtarg = isize(targets);
@ -2818,14 +2829,33 @@ void computePathdist(eMonster param) {
continue; continue;
} }
c2->pathdist = d+1; onpath(c2, d+1, c->spn(i));
pathq.push_back(c2); reachedfrom.push_back(c->spn(i));
} }
} }
} }
} }
// pathdist end // pathdist end
struct pathdata {
void checklock() {
if(pd_from) pd_from = NULL, clear_pathdata();
if(pathlock) printf("path error\n");
pathlock++;
}
~pathdata() {
pathlock--;
clear_pathdata();
}
pathdata(eMonster m) {
checklock();
computePathdist(m);
}
pathdata(int i) {
checklock();
}
};
vector<pair<cell*, int> > butterflies; vector<pair<cell*, int> > butterflies;
void addButterfly(cell *c) { void addButterfly(cell *c) {
@ -3770,6 +3800,8 @@ int moveval(cell *c1, cell *c2, int d, flagtype mf) {
// actually they just run away // actually they just run away
if(m == moHunterChanging && c2->pathdist > c1->pathdist) return 1600; if(m == moHunterChanging && c2->pathdist > c1->pathdist) return 1600;
if((mf & MF_PATHDIST) && !pathlock) printf("using MF_PATHDIST without path\n");
if(hunt && (mf & MF_PATHDIST) && c2->pathdist < c1->pathdist && !peace::on) return 1500; // good move if(hunt && (mf & MF_PATHDIST) && c2->pathdist < c1->pathdist && !peace::on) return 1500; // good move
// prefer straight direction when wandering // prefer straight direction when wandering
@ -4379,7 +4411,7 @@ void removeIvy(cell *c) {
void moveivy() { void moveivy() {
if(isize(ivies) == 0) return; if(isize(ivies) == 0) return;
computePathdist(moIvyRoot); pathdata pd(moIvyRoot);
for(int i=0; i<isize(ivies); i++) { for(int i=0; i<isize(ivies); i++) {
cell *c = ivies[i]; cell *c = ivies[i];
cell *co = c; cell *co = c;
@ -4461,7 +4493,7 @@ bool isTargetOrAdjacent(cell *c) {
void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) { void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
if(!c) return; if(!c) return;
if(eq(c->aitmp, sval)) return; if(c->pathdist == 0) return;
if(movtype == moKrakenH && isTargetOrAdjacent(from)) ; if(movtype == moKrakenH && isTargetOrAdjacent(from)) ;
/* else if(passable_for(movtype, from, c, P_ONPLAYER | P_CHAIN | P_MONSTER)) ; /* else if(passable_for(movtype, from, c, P_ONPLAYER | P_CHAIN | P_MONSTER)) ;
@ -4518,7 +4550,8 @@ void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
return; return;
// in the gravity lands, eagles cannot ascend in their second move // in the gravity lands, eagles cannot ascend in their second move
if((mf & MF_ONLYEAGLE) && gravityLevel(c) < gravityLevel(from)) { if((mf & MF_ONLYEAGLE) && gravityLevel(c) < gravityLevel(from)) {
c->aitmp = sval; return; onpath(c, 0);
return;
} }
if((mf & MF_NOFRIEND) && isFriendly(c)) return; if((mf & MF_NOFRIEND) && isFriendly(c)) return;
if((mf & MF_MOUNT) && !isMounted(c)) return; if((mf & MF_MOUNT) && !isMounted(c)) return;
@ -4532,12 +4565,12 @@ void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
if(c->mov[j] && canAttack(c, c->monst, c->mov[j], c->mov[j]->monst, af)) { if(c->mov[j] && canAttack(c, c->monst, c->mov[j], c->mov[j]->monst, af)) {
attackMonster(c->mov[j], AF_NORMAL | AF_GETPLAYER | AF_MSG, c->monst); attackMonster(c->mov[j], AF_NORMAL | AF_GETPLAYER | AF_MSG, c->monst);
animateAttack(c, c->mov[j], LAYER_SMALL, j); animateAttack(c, c->mov[j], LAYER_SMALL, j);
c->aitmp = sval; onpath(c, 0);
// XLATC eagle // XLATC eagle
return; return;
} }
if(from->cpdist == 0 || from->monst) { c->aitmp = sval; return; } if(from->cpdist == 0 || from->monst) { onpath(c, 0); return; }
if(movtype == moDragonHead) { if(movtype == moDragonHead) {
dragon::move(from, c); dragon::move(from, c);
@ -4545,15 +4578,15 @@ void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
} }
moveMonster(from, c, revhint(from, d)); moveMonster(from, c, revhint(from, d));
from->aitmp = sval; onpath(from, 0);
} }
c->aitmp = sval; onpath(c, 0);
// MAXGCELL // MAXGCELL
if(isize(gendfs) < 1000 || c->cpdist <= 6) gendfs.push_back(c); if(isize(gendfs) < 1000 || c->cpdist <= 6) gendfs.push_back(c);
} }
void groupmove(eMonster movtype, flagtype mf) { void groupmove(eMonster movtype, flagtype mf) {
sval++; pathdata pd(0);
gendfs.clear(); gendfs.clear();
if(mf & MF_MOUNT) { if(mf & MF_MOUNT) {
@ -4602,9 +4635,9 @@ void groupmove(eMonster movtype, flagtype mf) {
if(movtype != moDragonHead) for(int i=0; i<isize(dcal); i++) { if(movtype != moDragonHead) for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i]; cell *c = dcal[i];
if((mf & MF_ONLYEAGLE) && c->monst != moEagle && c->monst != moBat) return; if((mf & MF_ONLYEAGLE) && c->monst != moEagle && c->monst != moBat) return;
if(movegroup(c->monst) == movtype && !eq(c->aitmp, sval)) { if(movegroup(c->monst) == movtype && c->pathdist != 0) {
cell *c2 = moveNormal(c, mf); cell *c2 = moveNormal(c, mf);
if(c2) c2->aitmp = sval; onpath(c2, 0);
} }
} }
} }
@ -4665,7 +4698,7 @@ int snake_pair(cell *c) {
void hexvisit(cell *c, cell *from, int d, bool mounted, int colorpair) { void hexvisit(cell *c, cell *from, int d, bool mounted, int colorpair) {
if(!c) return; if(!c) return;
if(cellUnstable(c) || cellEdgeUnstable(c)) return; if(cellUnstable(c) || cellEdgeUnstable(c)) return;
if(eq(c->aitmp, sval)) return; if(c->pathdist == 0) return;
if(cellUnstableOrChasm(c) || cellUnstableOrChasm(from)) return; if(cellUnstableOrChasm(c) || cellUnstableOrChasm(from)) return;
@ -4690,7 +4723,7 @@ void hexvisit(cell *c, cell *from, int d, bool mounted, int colorpair) {
moveHexSnake(from, c, d, mounted); moveHexSnake(from, c, d, mounted);
} }
c->aitmp = sval; onpath(c, 0);
// MAXGCELL // MAXGCELL
if(isize(hexdfs) < 2000 || c->cpdist <= 6) if(isize(hexdfs) < 2000 || c->cpdist <= 6)
@ -4698,18 +4731,18 @@ void hexvisit(cell *c, cell *from, int d, bool mounted, int colorpair) {
} }
void movehex(bool mounted, int colorpair) { void movehex(bool mounted, int colorpair) {
sval++; pathdata pd();
hexdfs.clear(); hexdfs.clear();
if(mounted) { if(mounted) {
if(dragon::target && dragon::target->monst != moHexSnake) { if(dragon::target && dragon::target->monst != moHexSnake) {
hexdfs.push_back(dragon::target); hexdfs.push_back(dragon::target);
dragon::target->aitmp = sval; onpath(dragon::target, 0);
} }
} }
else for(int i=0; i<isize(targets); i++) { else for(cell *c: targets) {
hexdfs.push_back(targets[i]); hexdfs.push_back(c);
targets[i]->aitmp = sval; onpath(c, 0);
} }
//hexdfs.push_back(cwt.c); //hexdfs.push_back(cwt.c);
@ -5202,7 +5235,7 @@ int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
void movegolems(flagtype flags) { void movegolems(flagtype flags) {
if(items[itOrbEmpathy] && items[itOrbSlaying]) if(items[itOrbEmpathy] && items[itOrbSlaying])
flags |= AF_CRUSH; flags |= AF_CRUSH;
computePathdist(moMouse); pathdata pd(moMouse);
int qg = 0; int qg = 0;
for(int i=0; i<isize(golems); i++) { for(int i=0; i<isize(golems); i++) {
cell *c = golems[i]; cell *c = golems[i];
@ -5367,7 +5400,7 @@ void specialMoves() {
} }
if(m == moNecromancer) { if(m == moNecromancer) {
computePathdist(moNecromancer); pathdata pd(moNecromancer);
int gravenum = 0, zombienum = 0; int gravenum = 0, zombienum = 0;
cell *gtab[8], *ztab[8]; cell *gtab[8], *ztab[8];
for(int j=0; j<c->type; j++) if(c->mov[j]) { for(int j=0; j<c->type; j++) if(c->mov[j]) {
@ -5469,7 +5502,7 @@ void specialMoves() {
void moveworms() { void moveworms() {
if(!isize(worms)) return; if(!isize(worms)) return;
computePathdist(moWorm); pathdata pd(moWorm);
int wrm = isize(worms); int wrm = isize(worms);
for(int i=0; i<wrm; i++) { for(int i=0; i<wrm; i++) {
moveWorm(worms[i]); moveWorm(worms[i]);
@ -5732,7 +5765,7 @@ void consMove(cell *c, eMonster param) {
} }
void moveNormals(eMonster param) { void moveNormals(eMonster param) {
computePathdist(param); pathdata pd(param);
for(int d=0; d<8; d++) movesofgood[d].clear(); for(int d=0; d<8; d++) movesofgood[d].clear();

View File

@ -304,6 +304,7 @@ eItem wanderingTreasure(cell *c) {
void wandering() { void wandering() {
if(!canmove) return; if(!canmove) return;
pathdata pd(moYeti);
int seepcount = getSeepcount(); int seepcount = getSeepcount();
int ghostcount = getGhostcount(); int ghostcount = getGhostcount();
if(cwt.c->land == laCA) ghostcount = 0; if(cwt.c->land == laCA) ghostcount = 0;

View File

@ -2937,19 +2937,12 @@ void turn(int delta) {
for(int t=1; t<motypes; t++) if(exists[t]) { for(int t=1; t<motypes; t++) if(exists[t]) {
pd_from = NULL; pathdata pd(1);
// build the path data // build the path data
int pqs = isize(pathq); for(cell *c: targets)
for(int i=0; i<pqs; i++) { onpath(c, isPlayerOn(c) ? 0 : 1);
pathq[i]->pathdist = PINFD;
}
pathq.clear();
for(int i=0; i<isize(targets); i++) {
targets[i]->pathdist = isPlayerOn(targets[i]) ? 0 : 1;
pathq.push_back(targets[i]);
}
int qb = 0; int qb = 0;
for(qb=0; qb < isize(pathq); qb++) { for(qb=0; qb < isize(pathq); qb++) {
@ -2961,8 +2954,7 @@ void turn(int delta) {
// printf("i=%d cd=%d\n", i, c->mov[i]->cpdist); // printf("i=%d cd=%d\n", i, c->mov[i]->cpdist);
if(c2 && c2->pathdist == PINFD && gmatrix.count(c2) && if(c2 && c2->pathdist == PINFD && gmatrix.count(c2) &&
(passable_for(eMonster(t), c, c2, P_CHAIN | P_ONPLAYER) || c->wall == waThumperOn)) { (passable_for(eMonster(t), c, c2, P_CHAIN | P_ONPLAYER) || c->wall == waThumperOn)) {
c2->pathdist = d+1; onpath(c2, d+1);
pathq.push_back(c2);
} }
} }
} }