mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
fixed a bug in leader movement by using pathdist; also made pathdist more robust
This commit is contained in:
parent
ad74267080
commit
c6412511f5
107
game.cpp
107
game.cpp
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
18
shmup.cpp
18
shmup.cpp
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user