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;
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() {
if(pathlock) { printf("path error: compute_graphical_distance\n"); }
cell *c1 = centerover.c ? centerover.c : pd_from ? pd_from : cwt.c;
int sr = get_sightrange_ambush();
if(pd_from == c1 && pd_range == sr) return;
for(auto c: pathq) c->pathdist = PINFD;
pathq.clear();
clear_pathdata();
pd_from = c1;
pd_range = sr;
@ -2765,23 +2785,14 @@ void compute_graphical_distance() {
if(qb == 0) forCellCM(c1, c) ;
forCellEx(c1, c)
if(c1->pathdist == PINFD)
c1->pathdist = c->pathdist + 1,
pathq.push_back(c1);
onpath(c1, c->pathdist + 1);
}
}
}
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++) {
pathq.push_back(targets[i]);
targets[i]->pathdist = isPlayerOn(targets[i]) ? 0 : 1;
reachedfrom.push_back(hrand(targets[i]->type));
}
for(cell *c: targets)
onpath(c, isPlayerOn(c) ? 0 : 1, hrand(c->type));
int qtarg = isize(targets);
@ -2818,14 +2829,33 @@ void computePathdist(eMonster param) {
continue;
}
c2->pathdist = d+1;
pathq.push_back(c2); reachedfrom.push_back(c->spn(i));
onpath(c2, d+1, c->spn(i));
}
}
}
}
// 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;
void addButterfly(cell *c) {
@ -3770,6 +3800,8 @@ int moveval(cell *c1, cell *c2, int d, flagtype mf) {
// actually they just run away
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
// prefer straight direction when wandering
@ -4379,7 +4411,7 @@ void removeIvy(cell *c) {
void moveivy() {
if(isize(ivies) == 0) return;
computePathdist(moIvyRoot);
pathdata pd(moIvyRoot);
for(int i=0; i<isize(ivies); i++) {
cell *c = ivies[i];
cell *co = c;
@ -4461,7 +4493,7 @@ bool isTargetOrAdjacent(cell *c) {
void groupmove2(cell *c, cell *from, int d, eMonster movtype, flagtype mf) {
if(!c) return;
if(eq(c->aitmp, sval)) return;
if(c->pathdist == 0) return;
if(movtype == moKrakenH && isTargetOrAdjacent(from)) ;
/* 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;
// in the gravity lands, eagles cannot ascend in their second move
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_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)) {
attackMonster(c->mov[j], AF_NORMAL | AF_GETPLAYER | AF_MSG, c->monst);
animateAttack(c, c->mov[j], LAYER_SMALL, j);
c->aitmp = sval;
onpath(c, 0);
// XLATC eagle
return;
}
if(from->cpdist == 0 || from->monst) { c->aitmp = sval; return; }
if(from->cpdist == 0 || from->monst) { onpath(c, 0); return; }
if(movtype == moDragonHead) {
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));
from->aitmp = sval;
onpath(from, 0);
}
c->aitmp = sval;
onpath(c, 0);
// MAXGCELL
if(isize(gendfs) < 1000 || c->cpdist <= 6) gendfs.push_back(c);
}
void groupmove(eMonster movtype, flagtype mf) {
sval++;
pathdata pd(0);
gendfs.clear();
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++) {
cell *c = dcal[i];
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);
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) {
if(!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;
@ -4690,7 +4723,7 @@ void hexvisit(cell *c, cell *from, int d, bool mounted, int colorpair) {
moveHexSnake(from, c, d, mounted);
}
c->aitmp = sval;
onpath(c, 0);
// MAXGCELL
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) {
sval++;
pathdata pd();
hexdfs.clear();
if(mounted) {
if(dragon::target && dragon::target->monst != moHexSnake) {
hexdfs.push_back(dragon::target);
dragon::target->aitmp = sval;
onpath(dragon::target, 0);
}
}
else for(int i=0; i<isize(targets); i++) {
hexdfs.push_back(targets[i]);
targets[i]->aitmp = sval;
else for(cell *c: targets) {
hexdfs.push_back(c);
onpath(c, 0);
}
//hexdfs.push_back(cwt.c);
@ -5202,7 +5235,7 @@ int movevalue(eMonster m, cell *c, cell *c2, flagtype flags) {
void movegolems(flagtype flags) {
if(items[itOrbEmpathy] && items[itOrbSlaying])
flags |= AF_CRUSH;
computePathdist(moMouse);
pathdata pd(moMouse);
int qg = 0;
for(int i=0; i<isize(golems); i++) {
cell *c = golems[i];
@ -5367,7 +5400,7 @@ void specialMoves() {
}
if(m == moNecromancer) {
computePathdist(moNecromancer);
pathdata pd(moNecromancer);
int gravenum = 0, zombienum = 0;
cell *gtab[8], *ztab[8];
for(int j=0; j<c->type; j++) if(c->mov[j]) {
@ -5469,7 +5502,7 @@ void specialMoves() {
void moveworms() {
if(!isize(worms)) return;
computePathdist(moWorm);
pathdata pd(moWorm);
int wrm = isize(worms);
for(int i=0; i<wrm; i++) {
moveWorm(worms[i]);
@ -5732,7 +5765,7 @@ void consMove(cell *c, eMonster param) {
}
void moveNormals(eMonster param) {
computePathdist(param);
pathdata pd(param);
for(int d=0; d<8; d++) movesofgood[d].clear();

View File

@ -304,6 +304,7 @@ eItem wanderingTreasure(cell *c) {
void wandering() {
if(!canmove) return;
pathdata pd(moYeti);
int seepcount = getSeepcount();
int ghostcount = getGhostcount();
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]) {
pd_from = NULL;
pathdata pd(1);
// build the path data
int pqs = isize(pathq);
for(int i=0; i<pqs; i++) {
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]);
}
for(cell *c: targets)
onpath(c, isPlayerOn(c) ? 0 : 1);
int qb = 0;
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);
if(c2 && c2->pathdist == PINFD && gmatrix.count(c2) &&
(passable_for(eMonster(t), c, c2, P_CHAIN | P_ONPLAYER) || c->wall == waThumperOn)) {
c2->pathdist = d+1;
pathq.push_back(c2);
onpath(c2, d+1);
}
}
}