1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-06-25 22:52:49 +00:00

refactoring: sval/aitmp is no more, celllister(manual) used instead

This commit is contained in:
Zeno Rogue 2018-06-28 12:59:35 +02:00
parent ed8ff63ce4
commit d11044a80a
12 changed files with 225 additions and 237 deletions

View File

@ -59,7 +59,7 @@ vector<blizzardcell*> bcells;
int N; int N;
blizzardcell* getbcell(cell *c) { blizzardcell* getbcell(cell *c) {
int i = c->aitmp; int i = c->listindex;
if(i<0 || i >= N) return NULL; if(i<0 || i >= N) return NULL;
if(bcells[i]->c != c) return NULL; if(bcells[i]->c != c) return NULL;
return bcells[i]; return bcells[i];
@ -80,8 +80,8 @@ void drawBlizzards() {
N = isize(bcells); N = isize(bcells);
for(int i=0; i<N; i++) { for(int i=0; i<N; i++) {
auto& bc = *bcells[i]; auto& bc = *bcells[i];
bc.tmp = bc.c->aitmp, bc.tmp = bc.c->listindex,
bc.c->aitmp = i; bc.c->listindex = i;
bc.gm = &gmatrix[bc.c]; bc.gm = &gmatrix[bc.c];
bc.wmap = windmap::at(bc.c); bc.wmap = windmap::at(bc.c);
} }
@ -223,7 +223,7 @@ void drawBlizzards() {
} }
for(auto bc: bcells) for(auto bc: bcells)
bc->c->aitmp = bc->tmp; bc->c->listindex = bc->tmp;
} }
vector<cell*> arrowtraps; vector<cell*> arrowtraps;

View File

@ -104,8 +104,8 @@ namespace whirlwind {
} }
} }
void moveAt(cell *c) { void moveAt(cell *c, celllister& cl) {
if(eq(c->aitmp, sval)) return; if(cl.listed(c)) return;
calcdirs(c); calcdirs(c);
if(qdirs != 1) return; if(qdirs != 1) return;
vector<cell*> whirlline; vector<cell*> whirlline;
@ -129,7 +129,7 @@ namespace whirlwind {
// printf("Cycle built from %p, length = %d\n", c, z); // printf("Cycle built from %p, length = %d\n", c, z);
for(int i=0; i<z; i++) { for(int i=0; i<z; i++) {
// printf("%d%c", whirlline[i]->mpdist, whirlline[i]->item ? '*' : ' '); // printf("%d%c", whirlline[i]->mpdist, whirlline[i]->item ? '*' : ' ');
whirlline[i]->aitmp = sval; cl.add(whirlline[i]);
if(whirlline[i]->mpdist == BARLEV) if(whirlline[i]->mpdist == BARLEV)
switchTreasure(whirlline[i]); switchTreasure(whirlline[i]);
} }
@ -143,16 +143,16 @@ namespace whirlwind {
} }
void move() { void move() {
sval++; celllister cl(manual);
for(int i=0; i<isize(dcal); i++) { for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i]; cell *c = dcal[i];
moveAt(c); moveAt(c, cl);
} }
// Keys and Orbs of Yendor always move // Keys and Orbs of Yendor always move
using namespace yendor; using namespace yendor;
for(int i=0; i<isize(yi); i++) { for(int i=0; i<isize(yi); i++) {
moveAt(yi[i].path[0]); moveAt(yi[i].path[0], cl);
moveAt(yi[i].path[YDIST-1]); moveAt(yi[i].path[YDIST-1], cl);
} }
} }
@ -265,23 +265,23 @@ namespace elec {
vector<cell*> chargecells; vector<cell*> chargecells;
bool hasdata(cell *c) { bool hasdata(cell *c) {
return c->aitmp >= 0 && c->aitmp < isize(charges) && charges[c->aitmp].c == c; return c->listindex >= 0 && c->listindex < isize(charges) && charges[c->listindex].c == c;
} }
void connect(int from, cell *c) { void connect(int from, cell *c) {
if(hasdata(c)) { if(hasdata(c)) {
// seen again: set the lowlink // seen again: set the lowlink
if(!charges[c->aitmp].instack) return; if(!charges[c->listindex].instack) return;
// printf("edge %d-%d\n", from, c->aitmp); // printf("edge %d-%d\n", from, c->listindex);
if(c->aitmp < charges[from].lowlink) if(c->listindex < charges[from].lowlink)
charges[from].lowlink = c->aitmp; charges[from].lowlink = c->listindex;
} }
else { else {
int id = isize(charges); int id = isize(charges);
charges.push_back(chargedata()); charges.push_back(chargedata());
{chargedata& ch(charges[id]); {chargedata& ch(charges[id]);
ch.c = c; ch.otmp = c->aitmp; ch.lowlink = id; c->aitmp = id; ch.c = c; ch.otmp = c->listindex; ch.lowlink = id; c->listindex = id;
ch.instack = true; ch.fire = false; ch.instack = true; ch.fire = false;
} }
// c->landparam = id; // c->landparam = id;
@ -304,7 +304,7 @@ namespace elec {
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
cell *c2 = c->mov[i]; cell *c2 = c->mov[i];
if(!c2) continue; if(!c2) continue;
if(c2->aitmp == from) continue; if(c2->listindex == from) continue;
eCharge ct = getCharge(c2); eCharge ct = getCharge(c2);
if(conduct(chh, ct)) if(conduct(chh, ct))
connect(id, c2); connect(id, c2);
@ -349,29 +349,29 @@ namespace elec {
c->wall = waMetal; */ c->wall = waMetal; */
} }
void listChargedCells(cell *c, eCharge last = ecConductor) { void listChargedCells(cell *c, celllister& cl, eCharge last = ecConductor) {
if(eq(c->aitmp, sval)) return; if(cl.listed(c)) return;
eCharge here = getCharge(c); eCharge here = getCharge(c);
/* if(c->cpdist <= 2) { /* if(c->cpdist <= 2) {
printf("monst=%s ", dnameof(c->monst)); printf("monst=%s ", dnameof(c->monst));
printf("wall=%s ", dnameof(c->wall)); printf("wall=%s ", dnameof(c->wall));
printf("c=%p here=%d last=%d\n", c, here, last); printf("c=%p here=%d last=%d\n", c, here, last);
} */ } */
if(here == ecIsolator) c->aitmp = sval; if(here == ecIsolator) cl.add(c);
if(!conduct(last, here)) return; if(!conduct(last, here)) return;
if(here == ecCharged) chargecells.push_back(c); if(here == ecCharged) chargecells.push_back(c);
c->aitmp = sval; cl.add(c);
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
cell *c2 = c->mov[i]; cell *c2 = c->mov[i];
if(c2) listChargedCells(c2, here); if(c2) listChargedCells(c2, cl, here);
} }
} }
void init() { void init() {
chargecells.clear(); chargecells.clear();
if(!haveelec && !afterOrb) return; if(!haveelec && !afterOrb) return;
sval++; celllister cl(manual);
for(int i=0; i<isize(dcal); i++) listChargedCells(dcal[i]); for(int i=0; i<isize(dcal); i++) listChargedCells(dcal[i], cl);
charges.resize(2); charges.resize(2);
charges[0].lowlink = 0; charges[1].lowlink = 1; charges[0].lowlink = 0; charges[1].lowlink = 1;
@ -406,7 +406,7 @@ namespace elec {
void cleanup() { void cleanup() {
for(int i=2; i<isize(charges); i++) for(int i=2; i<isize(charges); i++)
charges[i].c->aitmp = charges[i].otmp; charges[i].c->listindex = charges[i].otmp;
charges.resize(0); charges.resize(0);
} }
@ -429,8 +429,8 @@ namespace elec {
} }
bool affected(cell *c) { bool affected(cell *c) {
if(c->aitmp >= 0 && c->aitmp < isize(charges) && charges[c->aitmp].c == c) if(c->listindex >= 0 && c->listindex < isize(charges) && charges[c->listindex].c == c)
return charges[c->aitmp].fire; return charges[c->listindex].fire;
return false; return false;
} }
@ -1011,9 +1011,9 @@ namespace whirlpool {
generate(wto); generate(wto);
} }
void moveAt(cell *c) { void moveAt(cell *c, celllister& cl) {
if(c->land != laWhirlpool) return; if(c->land != laWhirlpool) return;
if(eq(c->aitmp, sval)) return; if(cl.listed(c)) return;
if(!(euclid || c->master->alt)) return; if(!(euclid || c->master->alt)) return;
cell *c2 = get(c, 1); cell *c2 = get(c, 1);
if(!c2) return; if(!c2) return;
@ -1027,7 +1027,7 @@ namespace whirlpool {
int z = isize(whirlline); int z = isize(whirlline);
for(int i=0; i<z; i++) for(int i=0; i<z; i++)
whirlline[i]->aitmp = sval; cl.add(whirlline[i]);
whirlMove(NULL, whirlline[0]); whirlMove(NULL, whirlline[0]);
@ -1038,16 +1038,16 @@ namespace whirlpool {
} }
void move() { void move() {
sval++; celllister cl(manual);
for(int i=0; i<isize(dcal); i++) { for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i]; cell *c = dcal[i];
moveAt(c); moveAt(c, cl);
} }
// Keys and Orbs of Yendor always move // Keys and Orbs of Yendor always move
using namespace yendor; using namespace yendor;
for(int i=0; i<isize(yi); i++) { for(int i=0; i<isize(yi); i++) {
moveAt(yi[i].path[0]); moveAt(yi[i].path[0], cl);
moveAt(yi[i].path[YDIST-1]); moveAt(yi[i].path[YDIST-1], cl);
} }
} }
} }
@ -1466,7 +1466,7 @@ namespace hive {
} }
void bugcell(cell *c) { void bugcell(cell *c) {
short& i(c->aitmp); int& i(c->listindex);
if(i >= 0 && i < isize(buginfo) && buginfo[i].where == c) if(i >= 0 && i < isize(buginfo) && buginfo[i].where == c)
return; return;
i = isize(buginfo); i = isize(buginfo);
@ -1528,9 +1528,9 @@ namespace hive {
for(int dir=0; dir<c->type; dir++) { for(int dir=0; dir<c->type; dir++) {
cell *c2 = c->mov[dir]; cell *c2 = c->mov[dir];
if(!c2) continue; if(!c2) continue;
if(c2->aitmp < 0 || c2->aitmp >= isize(buginfo)) continue; if(c2->listindex < 0 || c2->listindex >= isize(buginfo)) continue;
if(!passable(c, c2, P_MONSTER)) continue; if(!passable(c, c2, P_MONSTER)) continue;
int j = c2->aitmp; int j = c2->listindex;
if(buginfo[j].where != c2) continue; if(buginfo[j].where != c2) continue;
if(buginfo[j].dist[k] < d) goodmoves++; if(buginfo[j].dist[k] < d) goodmoves++;
bugQueueInsert(k, j, d+1); bugQueueInsert(k, j, d+1);
@ -1610,11 +1610,11 @@ namespace hive {
qual = c2->monst == moDeadBug ? -60: isBugEnemy(c2,k) ? 2 : -20; qual = c2->monst == moDeadBug ? -60: isBugEnemy(c2,k) ? 2 : -20;
else if(!passable(c2, c, 0)) else if(!passable(c2, c, 0))
qual = passable(c2, c, P_DEADLY) ? -30 : -60; qual = passable(c2, c, P_DEADLY) ? -30 : -60;
else if(c2->aitmp < 0 || c2->aitmp >= isize(buginfo)) qual = -15; else if(c2->listindex < 0 || c2->listindex >= isize(buginfo)) qual = -15;
else if(buginfo[c2->aitmp].where != c2) qual = -15; else if(buginfo[c2->listindex].where != c2) qual = -15;
else if(buginfo[c2->aitmp].dist[k] < b.dist[k]) else if(buginfo[c2->listindex].dist[k] < b.dist[k])
qual = 1; qual = 1;
else if(buginfo[c2->aitmp].dist[k] == b.dist[k]) else if(buginfo[c2->listindex].dist[k] == b.dist[k])
qual = 0; qual = 0;
// printf("%d->#%d %d: %d\n", i, dir, c2->tmp, qual); // printf("%d->#%d %d: %d\n", i, dir, c2->tmp, qual);
if(qual > bqual) bqual = qual, q=0; if(qual > bqual) bqual = qual, q=0;
@ -1664,7 +1664,7 @@ namespace hive {
} }
void bugcitycell(cell *c, int d) { void bugcitycell(cell *c, int d) {
short& i = c->aitmp; int& i = c->listindex;
if(i >= 0 && i < isize(buginfo) && buginfo[i].where == c) if(i >= 0 && i < isize(buginfo) && buginfo[i].where == c)
return; return;
i = isize(buginfo); i = isize(buginfo);
@ -1793,14 +1793,13 @@ namespace heat {
vector<cell*> offscreen2; vector<cell*> offscreen2;
sval++; celllister cl(manual);
int gr = gamerange(); int gr = gamerange();
for(cell *c: offscreen_heat) { for(cell *c: offscreen_heat) {
if(c->cpdist > gr && !doall) { if(c->cpdist > gr && !doall) {
if(eq(c->aitmp, sval)) continue; if(!cl.add(c)) continue;
c->aitmp = sval;
if(isIcyLand(c)) { if(isIcyLand(c)) {
if(HEAT(c) < .01 && HEAT(c) > -.01) if(HEAT(c) < .01 && HEAT(c) > -.01)
HEAT(c) = 0; HEAT(c) = 0;
@ -1941,13 +1940,12 @@ namespace heat {
vector<cell*> offscreen2; vector<cell*> offscreen2;
sval++; celllister cl(manual);
vector<cell*>& allcells = currentmap->allcells(); vector<cell*>& allcells = currentmap->allcells();
for(int x: {0,1}) for(cell *c: x==0 ? allcells : offscreen_fire) { for(int x: {0,1}) for(cell *c: x==0 ? allcells : offscreen_fire) {
if(eq(c->aitmp, sval)) continue; if(!cl.add(c)) continue;
c->aitmp = sval;
if(isFireOrMagma(c)) { if(isFireOrMagma(c)) {
if(c->wall == waMagma) c->wparam = 20; if(c->wall == waMagma) c->wparam = 20;
@ -2046,94 +2044,98 @@ void livecaves() {
vector<cell*> bringlife; vector<cell*> bringlife;
int gr = gamerange(); int gr = gamerange();
int heatvals[dcs];
for(int i=0; i<dcs; i++) { for(int i=0; i<dcs; i++) {
cell *c = allcells[i]; cell *c = allcells[i];
if(!doall && c->cpdist > gr+1) break; if(!doall && c->cpdist > gr+1) break;
int & hv = heatvals[i];
if(c->wall == waCavefloor || c->wall == waCavewall || c->wall == waDeadTroll) { if(c->wall == waCavefloor || c->wall == waCavewall || c->wall == waDeadTroll) {
c->aitmp = 0; hv = 0;
if(c->monst == moDarkTroll) c->monst = moTroll; if(c->monst == moDarkTroll) c->monst = moTroll;
if(c->item || c->monst || c->cpdist == 0) continue; if(c->item || c->monst || c->cpdist == 0) continue;
forCellEx(c2, c) { forCellEx(c2, c) {
eWall w = c2->wall; eWall w = c2->wall;
if(w == waDeadfloor) c->aitmp++, bringlife.push_back(c2); if(w == waDeadfloor) hv++, bringlife.push_back(c2);
else if(w == waDeadwall || (w == waDeadfloor2 && !c2->monst)) else if(w == waDeadwall || (w == waDeadfloor2 && !c2->monst))
c->aitmp--, bringlife.push_back(c2); hv--, bringlife.push_back(c2);
else if(w == waCavefloor) c->aitmp++; else if(w == waCavefloor) hv++;
else if(w == waCavewall) c->aitmp--; else if(w == waCavewall) hv--;
else if(w == waRubble) c->aitmp--; else if(w == waRubble) hv--;
else if(w == waGargoyle) c->aitmp--; else if(w == waGargoyle) hv--;
else if(w == waGargoyleFloor) c->aitmp--; else if(w == waGargoyleFloor) hv--;
else if(w == waGargoyleBridge) c->aitmp--; else if(w == waGargoyleBridge) hv--;
else if(w == waStone) ; else if(w == waStone) ;
else if(w == waDeadTroll) c->aitmp -= 5; else if(w == waDeadTroll) hv -= 5;
else if(w == waDeadTroll2) c->aitmp -= 3; else if(w == waDeadTroll2) hv -= 3;
else if(w == waPetrified || w == waPetrifiedBridge) c->aitmp -= 2; else if(w == waPetrified || w == waPetrifiedBridge) hv -= 2;
else if(w == waVinePlant) c->aitmp--; else if(w == waVinePlant) hv--;
else if(chaosmode && c2->land != laCaves && c2->land != laEmerald) ; else if(chaosmode && c2->land != laCaves && c2->land != laEmerald) ;
else if(c2->land == laTrollheim) ; // trollheim floor does not count else if(c2->land == laTrollheim) ; // trollheim floor does not count
else if(w != waBarrier) c->aitmp += 5; else if(w != waBarrier) hv += 5;
if(sword::at(c)) c->aitmp += 500; if(sword::at(c)) hv += 500;
if(c2->cpdist == 0 && markOrb(itOrbDigging)) c->aitmp+=100; if(c2->cpdist == 0 && markOrb(itOrbDigging)) hv+=100;
if(items[itOrbEmpathy] && isFriendly(c2) && markEmpathy(itOrbDigging)) if(items[itOrbEmpathy] && isFriendly(c2) && markEmpathy(itOrbDigging))
c->aitmp+=100; hv+=100;
if(w == waThumperOn) c->aitmp+=100; if(w == waThumperOn) hv+=100;
if(w == waFire) c->aitmp+=100; if(w == waFire) hv+=100;
if(w == waBigStatue) c->aitmp-=100; if(w == waBigStatue) hv-=100;
if(c2->item && !peace::on) c->aitmp+=2; if(c2->item && !peace::on) hv+=2;
if(c2->monst == moZombie) c->aitmp += 10; if(c2->monst == moZombie) hv += 10;
if(c2->monst == moGhost) c->aitmp += 10; if(c2->monst == moGhost) hv += 10;
if(c2->monst == moTentacleGhost) c->aitmp += 10; if(c2->monst == moTentacleGhost) hv += 10;
if(c2->monst == moFriendlyGhost) c->aitmp += 10; if(c2->monst == moFriendlyGhost) hv += 10;
if(c2->monst == moSkeleton) c->aitmp ++; if(c2->monst == moSkeleton) hv ++;
if(c2->monst == moGargoyle) c->aitmp--; if(c2->monst == moGargoyle) hv--;
if(c2->monst == moDraugr) c->aitmp--; if(c2->monst == moDraugr) hv--;
if(isDragon(c2->monst)) c->aitmp++; if(isDragon(c2->monst)) hv++;
if(c2->monst == moNecromancer) c->aitmp += 10; if(c2->monst == moNecromancer) hv += 10;
if(c2->monst == moWormtail) c->aitmp++; if(c2->monst == moWormtail) hv++;
if(c2->monst == moTentacletail) c->aitmp-=2; if(c2->monst == moTentacletail) hv-=2;
if(isIvy(c2)) c->aitmp--; if(isIvy(c2)) hv--;
if(isDemon(c2)) c->aitmp-=3; if(isDemon(c2)) hv-=3;
// if(c2->monst) c->tmp++; // if(c2->monst) c->tmp++;
// if(c2->monst == moTroll) c->tmp -= 3; // if(c2->monst == moTroll) c->tmp -= 3;
} }
} }
else if(c->land == laLivefjord) { else if(c->land == laLivefjord) {
c->aitmp = 0; hv = 0;
if(c->monst == moWaterElemental) if(c->monst == moWaterElemental)
c->aitmp += 1000; hv += 1000;
if(isPlayerInBoatOn(c) && markOrb(itOrbWater)) if(isPlayerInBoatOn(c) && markOrb(itOrbWater))
c->aitmp += 1000; hv += 1000;
if(c->monst == moEarthElemental) if(c->monst == moEarthElemental)
c->aitmp -= 1000; hv -= 1000;
if(isPlayerOn(c) && markOrb(itOrbDigging)) if(isPlayerOn(c) && markOrb(itOrbDigging))
c->aitmp -= 1000; hv -= 1000;
for(int j=0; j<c->type; j++) if(c->mov[j]) { for(int j=0; j<c->type; j++) if(c->mov[j]) {
cell *c2 = c->mov[j]; cell *c2 = c->mov[j];
if(c2->wall == waNone || c2->wall == waStrandedBoat) if(c2->wall == waNone || c2->wall == waStrandedBoat)
c->aitmp -= (c2->land == laLivefjord ? 1 : 100); hv -= (c2->land == laLivefjord ? 1 : 100);
if(c2->wall == waTempFloor || c2->wall == waTempBridge || c2->wall == waTempBridgeBlocked) if(c2->wall == waTempFloor || c2->wall == waTempBridge || c2->wall == waTempBridgeBlocked)
; ;
else if(c2->wall == waDeadTroll || c2->wall == waDeadTroll2 || c2->wall == waThumperOn || isFire(c2) || snakelevel(c2)) else if(c2->wall == waDeadTroll || c2->wall == waDeadTroll2 || c2->wall == waThumperOn || isFire(c2) || snakelevel(c2))
c->aitmp -= 10; hv -= 10;
else if(c2->wall == waPetrified || c2->wall == waPetrifiedBridge) else if(c2->wall == waPetrified || c2->wall == waPetrifiedBridge)
c->aitmp -= 10; hv -= 10;
if(c2->wall == waBigStatue) if(c2->wall == waBigStatue)
c->aitmp -= 10; hv -= 10;
if(c2->wall == waSea || c2->wall == waBoat) if(c2->wall == waSea || c2->wall == waBoat)
c->aitmp += (c2->land == laLivefjord ? 1 : 100); hv += (c2->land == laLivefjord ? 1 : 100);
if(c2->monst == moWaterElemental) if(c2->monst == moWaterElemental)
c->aitmp += 1000; hv += 1000;
if(isPlayerOn(c2) && c2->wall == waBoat && markOrb(itOrbWater)) if(isPlayerOn(c2) && c2->wall == waBoat && markOrb(itOrbWater))
c->aitmp += 1000; hv += 1000;
if(c2->monst == moEarthElemental) if(c2->monst == moEarthElemental)
c->aitmp -= 1000; hv -= 1000;
if(isPlayerOn(c2) && markOrb(itOrbDigging)) if(isPlayerOn(c2) && markOrb(itOrbDigging))
c->aitmp -= 1000; hv -= 1000;
if(items[itOrbEmpathy] && isFriendly(c2) && markEmpathy(itOrbDigging)) if(items[itOrbEmpathy] && isFriendly(c2) && markEmpathy(itOrbDigging))
c->aitmp -= 1000; hv -= 1000;
if(c2->wall == waBarrier) { if(c2->wall == waBarrier) {
bool landbar = false; bool landbar = false;
@ -2143,8 +2145,8 @@ void livecaves() {
if(!isSealand(c3->land)) if(!isSealand(c3->land))
landbar = true; landbar = true;
} }
if(landbar) c->aitmp -= 5; if(landbar) hv -= 5;
else c->aitmp += 5; else hv += 5;
} }
} }
} }
@ -2153,13 +2155,14 @@ void livecaves() {
for(int i=0; i<dcs; i++) { for(int i=0; i<dcs; i++) {
cell *c = allcells[i]; cell *c = allcells[i];
if(!doall && c->cpdist > gr+1) break; if(!doall && c->cpdist > gr+1) break;
int hv = heatvals[i];
if(c->wall == waCavefloor || c->wall == waCavewall) { if(c->wall == waCavefloor || c->wall == waCavewall) {
// if(c->land != laCaves) continue; // if(c->land != laCaves) continue;
// if(c->wall == waThumper || c->wall == waBonfire) continue; // if(c->wall == waThumper || c->wall == waBonfire) continue;
if(c->aitmp > 0) c->wall = waCavefloor; if(hv > 0) c->wall = waCavefloor;
if(c->aitmp < 0) { if(hv < 0) {
c->wall = waCavewall; c->wall = waCavewall;
if(c->land != laCaves && c->land != laDeadCaves && c->land != laEmerald && !gardener) { if(c->land != laCaves && c->land != laDeadCaves && c->land != laEmerald && !gardener) {
gardener = true; gardener = true;
@ -2168,14 +2171,14 @@ void livecaves() {
} }
} }
else if(c->land == laLivefjord) { else if(c->land == laLivefjord) {
if(c->aitmp > 0 && c->wall == waStrandedBoat) c->wall = waBoat; if(hv > 0 && c->wall == waStrandedBoat) c->wall = waBoat;
if(c->aitmp > 0 && c->wall == waNone) { if(hv > 0 && c->wall == waNone) {
if(c->item && c->cpdist == 1 && markOrb(itOrbWater)) if(c->item && c->cpdist == 1 && markOrb(itOrbWater))
collectItem(c); collectItem(c);
c->wall = waSea; c->wall = waSea;
} }
if(c->aitmp < 0 && c->wall == waBoat) c->wall = waStrandedBoat; if(hv < 0 && c->wall == waBoat) c->wall = waStrandedBoat;
if(c->aitmp < 0 && c->wall == waSea) c->wall = waNone; if(hv < 0 && c->wall == waSea) c->wall = waNone;
} }
} }
@ -2573,6 +2576,7 @@ namespace kraken {
} }
void attacks() { void attacks() {
pathdata pd(2);
bool offboat[MAXPLAYER]; bool offboat[MAXPLAYER];
for(int i=0; i<MAXPLAYER; i++) offboat[i] = false; for(int i=0; i<MAXPLAYER; i++) offboat[i] = false;
for(int i=0; i<isize(dcal); i++) { for(int i=0; i<isize(dcal); i++) {
@ -2632,8 +2636,7 @@ namespace kraken {
vector<pair<cell*, cell*> > acells; vector<pair<cell*, cell*> > acells;
acells.push_back(make_pair(c2, c)); acells.push_back(make_pair(c2, c));
forCellIdEx(c3, i, c) { forCellIdEx(c3, i, c) {
c3->monst = moKrakenT, c3->mondir = c->spn(i), c3->monst = moKrakenT, c3->mondir = c->spn(i), onpath(c3, 0);
c3->aitmp = sval;
int i0 = (i+c->spn(c->mondir)-c->mondir+99) % c2->type; int i0 = (i+c->spn(c->mondir)-c->mondir+99) % c2->type;
c3->hitpoints = hpcount[i0]; c3->hitpoints = hpcount[i0];
acells.push_back(make_pair(c2->mov[i0], c3)); acells.push_back(make_pair(c2->mov[i0], c3));
@ -2665,7 +2668,7 @@ namespace kraken {
} }
commitAnimations(LAYER_BIG); commitAnimations(LAYER_BIG);
sleep(c); sleep(c);
c->aitmp = sval; onpath(c, 0);
return; return;
} }
@ -2834,23 +2837,21 @@ namespace prairie {
if(c2) c->mondir = neighborId(c, c2); if(c2) c->mondir = neighborId(c, c2);
} }
void moveAt(cell *c) { void moveAt(cell *c, celllister& cl) {
if(eq(c->aitmp, sval)) return; if(!cl.add(c)) return;
vector<cell*> whirlline; vector<cell*> whirlline;
whirlline.push_back(c); whirlline.push_back(c);
c->aitmp = sval;
cell *c2 = prev(c); cell *c2 = prev(c);
while(c2 && !eq(c2->aitmp, sval)) { while(c2 && !cl.add(c2)) {
whirlline.push_back(c2), c2->aitmp = sval; whirlline.push_back(c2);
c2 = prev(c2); c2 = prev(c2);
// in sphere/quotient geometries, never break before a bull // in sphere/quotient geometries, never break before a bull
if((sphere || quotient) && !c2->monst) break; if((sphere || quotient) && !c2->monst) break;
} }
reverse(whirlline.begin(), whirlline.end()); reverse(whirlline.begin(), whirlline.end());
c2 = next(c); c2 = next(c);
while(c2 && !eq(c2->aitmp, sval)) whirlline.push_back(c2), c2->aitmp = sval, c2 = next(c2); while(c2 && cl.add(c2)) whirlline.push_back(c2), c2 = next(c2);
int qty = isize(whirlline); int qty = isize(whirlline);
// for(int i=0; i<qty; i++) whirlline[i]->aitmp = sval;
if(shmup::on) { if(shmup::on) {
for(int i=0; i<qty; i++) if(whirlline[i]->cpdist <= gamerange()) { for(int i=0; i<qty; i++) if(whirlline[i]->cpdist <= gamerange()) {
generateBeast(whirlline[i]); generateBeast(whirlline[i]);
@ -2887,10 +2888,10 @@ namespace prairie {
} }
void move() { void move() {
sval++; celllister cl(manual);
for(int i=0; i<isize(dcal); i++) { for(int i=0; i<isize(dcal); i++) {
cell *c = dcal[i]; cell *c = dcal[i];
if(isriver(c)) moveAt(c); if(isriver(c)) moveAt(c, cl);
} }
for(int i=0; i<isize(beaststogen); i++) for(int i=0; i<isize(beaststogen); i++)
generateBeast(beaststogen[i]); generateBeast(beaststogen[i]);

View File

@ -823,24 +823,28 @@ namespace conformal {
else if(doexiton(sym, uni)) popScreen(); else if(doexiton(sym, uni)) popScreen();
} }
set<cell*> inmovehistory, inkillhistory, infindhistory;
void restore() { void restore() {
sval++; inmovehistory.clear();
inkillhistory.clear();
infindhistory.clear();
for(int i=0; i<isize(movehistory); i++) for(int i=0; i<isize(movehistory); i++)
movehistory[i]->aitmp = sval; inmovehistory.insert(movehistory[i]);
sval++; sval++;
int sk = isize(killhistory); int sk = isize(killhistory);
for(int i=0; i<sk; i++) { for(int i=0; i<sk; i++) {
eMonster m = killhistory[i].second; eMonster m = killhistory[i].second;
killhistory[i].second = killhistory[i].first->monst; killhistory[i].second = killhistory[i].first->monst;
killhistory[i].first->monst = m; killhistory[i].first->monst = m;
killhistory[i].first->aitmp = sval; inkillhistory.insert(killhistory[i].first);
} }
int si = isize(findhistory); int si = isize(findhistory);
for(int i=0; i<si; i++) { for(int i=0; i<si; i++) {
eItem m = findhistory[i].second; eItem m = findhistory[i].second;
findhistory[i].second = findhistory[i].first->item; findhistory[i].second = findhistory[i].first->item;
findhistory[i].first->item = m; findhistory[i].first->item = m;
findhistory[i].first->aitmp = sval; infindhistory.insert(findhistory[i].first);
} }
} }

View File

@ -333,7 +333,7 @@ void debugScreen() {
dialog::addSelItem("celldist", its(celldist(mouseover)), 0); dialog::addSelItem("celldist", its(celldist(mouseover)), 0);
dialog::addSelItem("pathdist", its(mouseover->pathdist), 0); dialog::addSelItem("pathdist", its(mouseover->pathdist), 0);
dialog::addSelItem("celldistAlt", mouseover->master->alt ? its(celldistAlt(mouseover)) : "--", 0); dialog::addSelItem("celldistAlt", mouseover->master->alt ? its(celldistAlt(mouseover)) : "--", 0);
dialog::addSelItem("temporary", its(mouseover->aitmp), 0); dialog::addSelItem("temporary", its(mouseover->listindex), 0);
if(gp::on) if(gp::on)
dialog::addSelItem("whirl", gp::disp(gp::get_local_info(mouseover).relative), 0); dialog::addSelItem("whirl", gp::disp(gp::get_local_info(mouseover).relative), 0);
dialog::addBreak(50); dialog::addBreak(50);

View File

@ -170,7 +170,7 @@ void initcell(cell *c) {
c->cpdist = INFD; // current distance from the player c->cpdist = INFD; // current distance from the player
c->pathdist = PINFD;// current distance from the player, along paths (used by yetis) c->pathdist = PINFD;// current distance from the player, along paths (used by yetis)
c->landparam = 0; c->landflags = 0; c->wparam = 0; c->landparam = 0; c->landflags = 0; c->wparam = 0;
c->aitmp = 0; c->listindex = -1;
c->wall = waNone; c->wall = waNone;
c->item = itNone; c->item = itNone;
c->monst = moNone; c->monst = moNone;
@ -2836,26 +2836,6 @@ void computePathdist(eMonster param) {
} }
// 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) {
@ -5786,12 +5766,11 @@ void moveNormals(eMonster param) {
} }
} }
void markAmbush(cell *c) { void markAmbush(cell *c, celllister& cl) {
if(eq(c->aitmp, sval)) return; if(!cl.add(c)) return;
c->aitmp = sval;
forCellEx(c2, c) forCellEx(c2, c)
if(c2->cpdist < c->cpdist) if(c2->cpdist < c->cpdist)
markAmbush(c2); markAmbush(c2, cl);
} }
int ambush_distance; int ambush_distance;
@ -5799,30 +5778,30 @@ bool ambushed;
void checkAmbushState() { void checkAmbushState() {
if(havewhat & HF_HUNTER) { if(havewhat & HF_HUNTER) {
sval++; celllister cl(manual);
for(cell *c: dcal) { for(cell *c: dcal) {
if(c->monst == moHunterDog) { if(c->monst == moHunterDog) {
if(c->cpdist > ambush_distance) if(c->cpdist > ambush_distance)
ambush_distance = c->cpdist; ambush_distance = c->cpdist;
markAmbush(c); markAmbush(c, cl);
} }
if(c->monst == moHunterGuard && c->cpdist <= 4) if(c->monst == moHunterGuard && c->cpdist <= 4)
markAmbush(c); markAmbush(c, cl);
} }
if(items[itHunting] > 5 && items[itHunting] <= 22) { if(items[itHunting] > 5 && items[itHunting] <= 22) {
int q = 0; int q = 0;
for(int i=0; i<numplayers(); i++) for(int i=0; i<numplayers(); i++)
forCellEx(c2, playerpos(i)) forCellEx(c2, playerpos(i))
if(eq(c2->aitmp, sval)) if(cl.listed(c2))
q++; q++;
if(q == 1) havewhat |= HF_FAILED_AMBUSH; if(q == 1) havewhat |= HF_FAILED_AMBUSH;
if(q == 2) { if(q == 2) {
for(int i=0; i<numplayers(); i++) for(int i=0; i<numplayers(); i++)
forCellEx(c2, playerpos(i)) forCellEx(c2, playerpos(i))
if(eq(c2->aitmp, sval)) if(cl.listed(c2))
forCellEx(c3, playerpos(i)) forCellEx(c3, playerpos(i))
if(c3 != c2 && isNeighbor(c2,c3)) if(c3 != c2 && isNeighbor(c2,c3))
if(eq(c3->aitmp, sval)) if(cl.listed(c3))
havewhat |= HF_FAILED_AMBUSH; havewhat |= HF_FAILED_AMBUSH;
} }
if(havewhat & HF_FAILED_AMBUSH && ambushed) { if(havewhat & HF_FAILED_AMBUSH && ambushed) {
@ -6546,7 +6525,6 @@ int ambush(cell *c, eItem what) {
celllister cl(c, maxdist, 1000000, NULL); celllister cl(c, maxdist, 1000000, NULL);
cell *c0 = c; cell *c0 = c;
int d = 0; int d = 0;
cl.prepare();
int dogs0 = 0; int dogs0 = 0;
for(cell *cx: cl.lst) { for(cell *cx: cl.lst) {
int dh = cl.getdist(cx); int dh = cl.getdist(cx);

View File

@ -586,7 +586,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
poly_outline = OUTLINE_OTHER; poly_outline = OUTLINE_OTHER;
} }
if(c && conformal::includeHistory && eq(c->aitmp, sval)) poly_outline = OUTLINE_DEAD; if(c && conformal::includeHistory && conformal::infindhistory.count(c)) poly_outline = OUTLINE_DEAD;
if(!mmitem && it) return true; if(!mmitem && it) return true;
@ -1809,7 +1809,7 @@ bool dont_face_pc = false;
bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) { bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
bool darkhistory = conformal::includeHistory && eq(c->aitmp, sval); bool darkhistory = conformal::includeHistory && conformal::inkillhistory.count(c);
if(doHighlight()) if(doHighlight())
poly_outline = poly_outline =
@ -2981,7 +2981,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
} }
case waFloorA: case waFloorB: // isAlch case waFloorA: case waFloorB: // isAlch
if(c->item && !(conformal::includeHistory && eq(c->aitmp, sval))) if(c->item && !(conformal::includeHistory && conformal::infindhistory.count(c)))
fcol = wcol = iinf[c->item].color; fcol = wcol = iinf[c->item].color;
else else
fcol = wcol; fcol = wcol;
@ -3648,7 +3648,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
bool hidden = itemHidden(c); bool hidden = itemHidden(c);
bool hiddens = itemHiddenFromSight(c); bool hiddens = itemHiddenFromSight(c);
if(conformal::includeHistory && eq(c->aitmp, sval)) { if(conformal::includeHistory && conformal::infindhistory.count(c)) {
hidden = true; hidden = true;
hiddens = false; hiddens = false;
} }
@ -4211,7 +4211,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
queuepoly((*Vdp), shHeptaMarker, wmblack ? 0x80808080 : 0x00000080); queuepoly((*Vdp), shHeptaMarker, wmblack ? 0x80808080 : 0x00000080);
} }
if(conformal::includeHistory && eq(c->aitmp, sval-1)) if(conformal::includeHistory && conformal::inmovehistory.count(c))
queuepoly((*Vdp), shHeptaMarker, 0x000000C0); queuepoly((*Vdp), shHeptaMarker, 0x000000C0);
char xch = winf[c->wall].glyph; char xch = winf[c->wall].glyph;

71
hyper.h
View File

@ -369,10 +369,7 @@ struct cell : gcell {
// wall parameter, used for remaining power of Bonfires and Thumpers // wall parameter, used for remaining power of Bonfires and Thumpers
char wparam; char wparam;
// 'tmp' is used for: int listindex;
// pathfinding algorithm used by monsters with atypical movement (which do not use pathdist)
// bugs' pathfinding algorithm
short aitmp;
uint32_t spintable; uint32_t spintable;
int spin(int d) { return tspin(spintable, d); } int spin(int d) { return tspin(spintable, d); }
@ -1064,6 +1061,7 @@ namespace conformal {
extern vector<pair<cell*, eMonster> > killhistory; extern vector<pair<cell*, eMonster> > killhistory;
extern vector<pair<cell*, eItem> > findhistory; extern vector<pair<cell*, eItem> > findhistory;
extern vector<cell*> movehistory; extern vector<cell*> movehistory;
extern set<cell*> inmovehistory, inkillhistory, infindhistory;
extern bool includeHistory; extern bool includeHistory;
extern ld rotation; extern ld rotation;
extern int do_rotate; extern int do_rotate;
@ -1199,7 +1197,6 @@ bool isAlchAny(cell *c);
#define MODECODES 255 #define MODECODES 255
extern cellwalker cwt; // player character position extern cellwalker cwt; // player character position
extern int sval;
extern array<int, ittypes> items; extern array<int, ittypes> items;
extern array<int, motypes> kills; extern array<int, motypes> kills;
@ -2546,28 +2543,37 @@ extern vector<hrmap*> allmaps;
// list all cells in distance at most maxdist, or until when maxcount cells are reached // list all cells in distance at most maxdist, or until when maxcount cells are reached
extern struct manual_t {} manual;
struct celllister { struct celllister {
vector<cell*> lst; vector<cell*> lst;
vector<int> tmps; vector<int> tmps;
vector<int> dists; vector<int> dists;
void add(cell *c, int d) { bool listed(cell *c) {
if(eq(c->aitmp, sval)) return; return c->listindex >= 0 && c->listindex < isize(lst) && lst[c->listindex] == c;
c->aitmp = sval; }
tmps.push_back(c->aitmp);
bool add(cell *c) {
if(listed(c)) return false;
tmps.push_back(c->listindex);
lst.push_back(c); lst.push_back(c);
dists.push_back(d); c->listindex = isize(lst);
return true;
}
void add(cell *c, int d) {
if(add(c)) dists.push_back(d);
} }
~celllister() { ~celllister() {
for(int i=0; i<isize(lst); i++) lst[i]->aitmp = tmps[i]; for(int i=0; i<isize(lst); i++) lst[i]->listindex = tmps[i];
}
celllister(manual_t) {
} }
celllister(cell *orig, int maxdist, int maxcount, cell *breakon) { celllister(cell *orig, int maxdist, int maxcount, cell *breakon) {
lst.clear();
tmps.clear();
dists.clear();
sval++;
add(orig, 0); add(orig, 0);
cell *last = orig; cell *last = orig;
for(int i=0; i<isize(lst); i++) { for(int i=0; i<isize(lst); i++) {
@ -2583,16 +2589,7 @@ struct celllister {
} }
} }
void prepare() { int getdist(cell *c) { return dists[c->listindex]; }
for(int i=0; i<isize(lst); i++) lst[i]->aitmp = i;
}
int getdist(cell *c) { return dists[c->aitmp]; }
bool listed(cell *c) {
return c->aitmp >= 0 && c->aitmp < isize(lst) && lst[c->aitmp] == c;
}
}; };
hrmap *newAltMap(heptagon *o); hrmap *newAltMap(heptagon *o);
@ -3569,4 +3566,28 @@ bool confusingGeometry();
int revhint(cell *c, int hint); int revhint(cell *c, int hint);
extern int pathlock;
extern void computePathdist(eMonster m);
extern void onpath(cell *c, int d);
extern void clear_pathdata();
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();
}
};
} }

View File

@ -60,12 +60,8 @@ bool reptilecheat = false;
#define ONEMPTY if(d == 7 && passable(c, NULL, 0) && !safety) #define ONEMPTY if(d == 7 && passable(c, NULL, 0) && !safety)
vector<cell*> noescape_list; bool blizzard_no_escape1(cell *c, celllister &cl) {
if(!cl.add(c)) return true;
bool blizzard_no_escape1(cell *c) {
if(c->aitmp >= 0 && c->aitmp < isize(noescape_list) && noescape_list[c->aitmp] == c)
return true;
c->aitmp = isize(noescape_list); noescape_list.push_back(c);
if(c->item == itOrbSafety) if(c->item == itOrbSafety)
return false; return false;
forCellEx(c2, c) { forCellEx(c2, c) {
@ -73,16 +69,15 @@ bool blizzard_no_escape1(cell *c) {
continue; continue;
if(c2->land != laBlizzard && passable(c2, NULL, 0)) if(c2->land != laBlizzard && passable(c2, NULL, 0))
return false; return false;
if(!againstWind(c2, c) && !blizzard_no_escape1(c2)) if(!againstWind(c2, c) && !blizzard_no_escape1(c2, cl))
return false; return false;
} }
return true; return true;
} }
bool blizzard_no_escape(cell *c) { bool blizzard_no_escape(cell *c) {
sval++; celllister cl(manual);
noescape_list.resize(0); return blizzard_no_escape1(c, cl);
return blizzard_no_escape1(c);
} }
bool out_ruin(cell *c) { bool out_ruin(cell *c) {

View File

@ -267,8 +267,9 @@ namespace mapstream {
c->bardir = NOBARRIERS; c->bardir = NOBARRIERS;
// fixspin(rspin, loadChar(), c->type); // fixspin(rspin, loadChar(), c->type);
if(vernum < 7400) { if(vernum < 7400) {
load(c->aitmp); short z;
c->wparam = c->aitmp; load(z);
c->wparam = z;
} }
else load(c->wparam); else load(c->wparam);
load(c->landparam); load(c->landparam);
@ -620,7 +621,7 @@ namespace mapeditor {
vector<pair<cellwalker, cellwalker> > spill_list; vector<pair<cellwalker, cellwalker> > spill_list;
void list_spill(cellwalker tgt, cellwalker src) { void list_spill(cellwalker tgt, cellwalker src, celllister& cl) {
spill_list.clear(); sval++; spill_list.clear(); sval++;
spill_list.emplace_back(tgt, src); spill_list.emplace_back(tgt, src);
int crad = 0, nextstepat = 0; int crad = 0, nextstepat = 0;
@ -633,8 +634,7 @@ namespace mapeditor {
for(int i=0; i<sd.first.c->type; i++) { for(int i=0; i<sd.first.c->type; i++) {
auto sd2 = sd; auto sd2 = sd;
sd2.first = sd2.first + i + wstep; sd2.first = sd2.first + i + wstep;
if(eq(sd2.first.c->aitmp, sval)) continue; if(!cl.add(sd2.first.c)) continue;
sd2.first.c->aitmp = sval;
if(sd2.second.c) { if(sd2.second.c) {
sd2.second = sd2.second + i + wstep; sd2.second = sd2.second + i + wstep;
if(sd2.second.c->land == laNone) continue; if(sd2.second.c->land == laNone) continue;
@ -668,7 +668,7 @@ namespace mapeditor {
} }
#endif #endif
void editAt(cellwalker where) { void editAt(cellwalker where, celllister& cl) {
if(painttype == 4 && radius) { if(painttype == 4 && radius) {
if(where.c->type != copysource.c->type) return; if(where.c->type != copysource.c->type) return;
@ -677,7 +677,7 @@ namespace mapeditor {
where += 1; where += 1;
} }
if(painttype != 4) copysource.c = NULL; if(painttype != 4) copysource.c = NULL;
list_spill(where, copysource); list_spill(where, copysource, cl);
for(auto& st: spill_list) for(auto& st: spill_list)
editCell(st); editCell(st);
@ -685,34 +685,30 @@ namespace mapeditor {
void allInPattern(cellwalker where) { void allInPattern(cellwalker where) {
celllister cl(manual);
if(!patterns::whichPattern) { if(!patterns::whichPattern) {
editAt(where); editAt(where, cl);
return; return;
} }
vector<cell*> v; cl.add(where.c);
v.push_back(where.c);
sval++;
where.c->aitmp = sval;
int at = 0; int at = 0;
while(at < isize(v)) { while(at < isize(cl.lst)) {
cell *c2 = v[at]; cell *c2 = cl.lst[at];
at++; at++;
forCellEx(c3, c2) forCellEx(c3, c2) cl.add(c3);
if(!eq(c3->aitmp, sval))
c3->aitmp = sval, v.push_back(c3);
} }
auto si = patterns::getpatterninfo0(where.c); auto si = patterns::getpatterninfo0(where.c);
int cdir = where.spin; int cdir = where.spin;
if(cdir >= 0) cdir = cdir - si.dir; if(cdir >= 0) cdir = cdir - si.dir;
for(cell* c2: v) { for(cell* c2: cl.lst) {
auto si2 = patterns::getpatterninfo0(c2); auto si2 = patterns::getpatterninfo0(c2);
if(si2.id == si.id) { if(si2.id == si.id) {
editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + si2.dir, c2) : -1)); editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + si2.dir, c2) : -1), cl);
modelcell[si2.id] = c2; modelcell[si2.id] = c2;
} }
} }

View File

@ -242,18 +242,17 @@ int getSeepcount() {
} }
bool canReachPlayer(cell *cf, eMonster m) { bool canReachPlayer(cell *cf, eMonster m) {
vector<cell*> v; celllister cl(manual);
sval++; cl.add(cf);
v.push_back(cf); cf->aitmp = sval; for(int i=0; i<isize(cl.lst) && i < 10000; i++) {
for(int i=0; i<isize(v); i++) { cell *c = cl.lst[i];
cell *c = v[i];
for(int j=0; j<c->type; j++) { for(int j=0; j<c->type; j++) {
cell *c2 = c->mov[j]; cell *c2 = c->mov[j];
if(!c2) continue; if(!c2) continue;
if(eq(c2->aitmp, sval)) continue; if(cl.listed(c2)) continue;
if(!passable_for(m, c2, c, P_MONSTER | P_ONPLAYER | P_CHAIN)) continue; if(!passable_for(m, c2, c, P_MONSTER | P_ONPLAYER | P_CHAIN)) continue;
if(isPlayerOn(c2)) return true; if(isPlayerOn(c2)) return true;
c2->aitmp = sval; v.push_back(c2); cl.add(c2);
} }
} }
return false; return false;

View File

@ -247,19 +247,16 @@ bool distanceBound(cell *c1, cell *c2, int d) {
} }
void checkFreedom(cell *cf) { void checkFreedom(cell *cf) {
sval++; celllister cl(manual);
static vector<cell*> avcells; cl.add(cf);
avcells.clear(); for(int i=0; i<isize(cl.lst); i++) {
avcells.push_back(cf); cell *c = cl.lst[i];
cf->aitmp = sval;
for(int i=0; i<isize(avcells); i++) {
cell *c = avcells[i];
if(c->cpdist >= 5) return; if(c->cpdist >= 5) return;
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
cell *c2 = c->mov[i]; cell *c2 = c->mov[i];
// todo leader // todo leader
if(cl.listed(c2)) continue;
if(!passable(c2, c, P_ISPLAYER | P_MIRROR | P_LEADER)) continue; if(!passable(c2, c, P_ISPLAYER | P_MIRROR | P_LEADER)) continue;
if(eq(c2->aitmp, sval)) continue;
if(c2->wall == waArrowTrap && c2->wparam == 2) continue; if(c2->wall == waArrowTrap && c2->wparam == 2) continue;
bool monsterhere = false; bool monsterhere = false;
for(int j=0; j<c2->type; j++) { for(int j=0; j<c2->type; j++) {
@ -267,10 +264,7 @@ void checkFreedom(cell *cf) {
if(c3 && c3->monst && !isFriendly(c3)) if(c3 && c3->monst && !isFriendly(c3))
monsterhere = true; monsterhere = true;
} }
if(!monsterhere) { if(!monsterhere) cl.add(c2);
c2->aitmp = sval;
avcells.push_back(c2);
}
} }
} }
addMessage(XLAT("Your %1 activates!", itOrbFreedom)); addMessage(XLAT("Your %1 activates!", itOrbFreedom));

View File

@ -1011,14 +1011,14 @@ namespace peace {
clister.emplace_back(cp, cp); clister.emplace_back(cp, cp);
int id = 0; int id = 0;
sval++; celllister cl(manual);
while(id < isize(clister)) { while(id < isize(clister)) {
cell *c = clister[id].first; cell *c = clister[id].first;
cell *fr = clister[id].second; cell *fr = clister[id].second;
setdist(c, 5, NULL); setdist(c, 5, NULL);
forCellEx(c2,c) forCellEx(c2,c)
if(!eq(c2->aitmp, sval) && passable(c2, c, 0) && (c2->land == specialland || c2->land == laTemple) && !c2->item) { if(!cl.listed(c2) && passable(c2, c, 0) && (c2->land == specialland || c2->land == laTemple) && !c2->item) {
if(!id) fr = c2; if(!id) fr = c2;
bool next; bool next;
if(specialland == laRlyeh) if(specialland == laRlyeh)
@ -1031,7 +1031,7 @@ namespace peace {
goto again; goto again;
} }
clister.emplace_back(c2, fr); clister.emplace_back(c2, fr);
c2->aitmp = sval; cl.add(c2);
} }
id++; id++;
} }