From d11044a80ac27b6edc83fd88c255c62ff810ee08 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Thu, 28 Jun 2018 12:59:35 +0200 Subject: [PATCH] refactoring: sval/aitmp is no more, celllister(manual) used instead --- blizzard.cpp | 8 +- complex.cpp | 229 +++++++++++++++++++++++++------------------------ conformal.cpp | 12 ++- debug.cpp | 2 +- game.cpp | 44 +++------- graph.cpp | 10 +-- hyper.h | 71 +++++++++------ landgen.cpp | 15 ++-- mapeditor.cpp | 34 ++++---- monstergen.cpp | 13 ++- orbs.cpp | 18 ++-- yendor.cpp | 6 +- 12 files changed, 225 insertions(+), 237 deletions(-) diff --git a/blizzard.cpp b/blizzard.cpp index bfbd1a7e..ec3ae3b4 100644 --- a/blizzard.cpp +++ b/blizzard.cpp @@ -59,7 +59,7 @@ vector bcells; int N; blizzardcell* getbcell(cell *c) { - int i = c->aitmp; + int i = c->listindex; if(i<0 || i >= N) return NULL; if(bcells[i]->c != c) return NULL; return bcells[i]; @@ -80,8 +80,8 @@ void drawBlizzards() { N = isize(bcells); for(int i=0; iaitmp, - bc.c->aitmp = i; + bc.tmp = bc.c->listindex, + bc.c->listindex = i; bc.gm = &gmatrix[bc.c]; bc.wmap = windmap::at(bc.c); } @@ -223,7 +223,7 @@ void drawBlizzards() { } for(auto bc: bcells) - bc->c->aitmp = bc->tmp; + bc->c->listindex = bc->tmp; } vector arrowtraps; diff --git a/complex.cpp b/complex.cpp index 0038a7d2..4bf4bed5 100644 --- a/complex.cpp +++ b/complex.cpp @@ -104,8 +104,8 @@ namespace whirlwind { } } - void moveAt(cell *c) { - if(eq(c->aitmp, sval)) return; + void moveAt(cell *c, celllister& cl) { + if(cl.listed(c)) return; calcdirs(c); if(qdirs != 1) return; vector whirlline; @@ -129,7 +129,7 @@ namespace whirlwind { // printf("Cycle built from %p, length = %d\n", c, z); for(int i=0; impdist, whirlline[i]->item ? '*' : ' '); - whirlline[i]->aitmp = sval; + cl.add(whirlline[i]); if(whirlline[i]->mpdist == BARLEV) switchTreasure(whirlline[i]); } @@ -143,16 +143,16 @@ namespace whirlwind { } void move() { - sval++; + celllister cl(manual); for(int i=0; i chargecells; 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) { if(hasdata(c)) { // seen again: set the lowlink - if(!charges[c->aitmp].instack) return; - // printf("edge %d-%d\n", from, c->aitmp); - if(c->aitmp < charges[from].lowlink) - charges[from].lowlink = c->aitmp; + if(!charges[c->listindex].instack) return; + // printf("edge %d-%d\n", from, c->listindex); + if(c->listindex < charges[from].lowlink) + charges[from].lowlink = c->listindex; } else { int id = isize(charges); charges.push_back(chargedata()); {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; } // c->landparam = id; @@ -304,7 +304,7 @@ namespace elec { for(int i=0; itype; i++) { cell *c2 = c->mov[i]; if(!c2) continue; - if(c2->aitmp == from) continue; + if(c2->listindex == from) continue; eCharge ct = getCharge(c2); if(conduct(chh, ct)) connect(id, c2); @@ -349,29 +349,29 @@ namespace elec { c->wall = waMetal; */ } - void listChargedCells(cell *c, eCharge last = ecConductor) { - if(eq(c->aitmp, sval)) return; + void listChargedCells(cell *c, celllister& cl, eCharge last = ecConductor) { + if(cl.listed(c)) return; eCharge here = getCharge(c); /* if(c->cpdist <= 2) { printf("monst=%s ", dnameof(c->monst)); printf("wall=%s ", dnameof(c->wall)); 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(here == ecCharged) chargecells.push_back(c); - c->aitmp = sval; + cl.add(c); for(int i=0; itype; i++) { cell *c2 = c->mov[i]; - if(c2) listChargedCells(c2, here); + if(c2) listChargedCells(c2, cl, here); } } void init() { chargecells.clear(); if(!haveelec && !afterOrb) return; - sval++; - for(int i=0; iaitmp = charges[i].otmp; + charges[i].c->listindex = charges[i].otmp; charges.resize(0); } @@ -429,8 +429,8 @@ namespace elec { } bool affected(cell *c) { - if(c->aitmp >= 0 && c->aitmp < isize(charges) && charges[c->aitmp].c == c) - return charges[c->aitmp].fire; + if(c->listindex >= 0 && c->listindex < isize(charges) && charges[c->listindex].c == c) + return charges[c->listindex].fire; return false; } @@ -1011,9 +1011,9 @@ namespace whirlpool { generate(wto); } - void moveAt(cell *c) { + void moveAt(cell *c, celllister& cl) { if(c->land != laWhirlpool) return; - if(eq(c->aitmp, sval)) return; + if(cl.listed(c)) return; if(!(euclid || c->master->alt)) return; cell *c2 = get(c, 1); if(!c2) return; @@ -1027,7 +1027,7 @@ namespace whirlpool { int z = isize(whirlline); for(int i=0; iaitmp = sval; + cl.add(whirlline[i]); whirlMove(NULL, whirlline[0]); @@ -1038,16 +1038,16 @@ namespace whirlpool { } void move() { - sval++; + celllister cl(manual); for(int i=0; iaitmp); + int& i(c->listindex); if(i >= 0 && i < isize(buginfo) && buginfo[i].where == c) return; i = isize(buginfo); @@ -1528,9 +1528,9 @@ namespace hive { for(int dir=0; dirtype; dir++) { cell *c2 = c->mov[dir]; 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; - int j = c2->aitmp; + int j = c2->listindex; if(buginfo[j].where != c2) continue; if(buginfo[j].dist[k] < d) goodmoves++; bugQueueInsert(k, j, d+1); @@ -1610,11 +1610,11 @@ namespace hive { qual = c2->monst == moDeadBug ? -60: isBugEnemy(c2,k) ? 2 : -20; else if(!passable(c2, c, 0)) qual = passable(c2, c, P_DEADLY) ? -30 : -60; - else if(c2->aitmp < 0 || c2->aitmp >= isize(buginfo)) qual = -15; - else if(buginfo[c2->aitmp].where != c2) qual = -15; - else if(buginfo[c2->aitmp].dist[k] < b.dist[k]) + else if(c2->listindex < 0 || c2->listindex >= isize(buginfo)) qual = -15; + else if(buginfo[c2->listindex].where != c2) qual = -15; + else if(buginfo[c2->listindex].dist[k] < b.dist[k]) qual = 1; - else if(buginfo[c2->aitmp].dist[k] == b.dist[k]) + else if(buginfo[c2->listindex].dist[k] == b.dist[k]) qual = 0; // printf("%d->#%d %d: %d\n", i, dir, c2->tmp, qual); if(qual > bqual) bqual = qual, q=0; @@ -1664,7 +1664,7 @@ namespace hive { } void bugcitycell(cell *c, int d) { - short& i = c->aitmp; + int& i = c->listindex; if(i >= 0 && i < isize(buginfo) && buginfo[i].where == c) return; i = isize(buginfo); @@ -1793,14 +1793,13 @@ namespace heat { vector offscreen2; - sval++; + celllister cl(manual); int gr = gamerange(); for(cell *c: offscreen_heat) { if(c->cpdist > gr && !doall) { - if(eq(c->aitmp, sval)) continue; - c->aitmp = sval; + if(!cl.add(c)) continue; if(isIcyLand(c)) { if(HEAT(c) < .01 && HEAT(c) > -.01) HEAT(c) = 0; @@ -1941,13 +1940,12 @@ namespace heat { vector offscreen2; - sval++; + celllister cl(manual); vector& allcells = currentmap->allcells(); for(int x: {0,1}) for(cell *c: x==0 ? allcells : offscreen_fire) { - if(eq(c->aitmp, sval)) continue; - c->aitmp = sval; + if(!cl.add(c)) continue; if(isFireOrMagma(c)) { if(c->wall == waMagma) c->wparam = 20; @@ -2046,94 +2044,98 @@ void livecaves() { vector bringlife; int gr = gamerange(); + int heatvals[dcs]; + for(int i=0; icpdist > gr+1) break; + int & hv = heatvals[i]; + if(c->wall == waCavefloor || c->wall == waCavewall || c->wall == waDeadTroll) { - c->aitmp = 0; + hv = 0; if(c->monst == moDarkTroll) c->monst = moTroll; if(c->item || c->monst || c->cpdist == 0) continue; forCellEx(c2, c) { 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)) - c->aitmp--, bringlife.push_back(c2); - else if(w == waCavefloor) c->aitmp++; - else if(w == waCavewall) c->aitmp--; - else if(w == waRubble) c->aitmp--; - else if(w == waGargoyle) c->aitmp--; - else if(w == waGargoyleFloor) c->aitmp--; - else if(w == waGargoyleBridge) c->aitmp--; + hv--, bringlife.push_back(c2); + else if(w == waCavefloor) hv++; + else if(w == waCavewall) hv--; + else if(w == waRubble) hv--; + else if(w == waGargoyle) hv--; + else if(w == waGargoyleFloor) hv--; + else if(w == waGargoyleBridge) hv--; else if(w == waStone) ; - else if(w == waDeadTroll) c->aitmp -= 5; - else if(w == waDeadTroll2) c->aitmp -= 3; - else if(w == waPetrified || w == waPetrifiedBridge) c->aitmp -= 2; - else if(w == waVinePlant) c->aitmp--; + else if(w == waDeadTroll) hv -= 5; + else if(w == waDeadTroll2) hv -= 3; + else if(w == waPetrified || w == waPetrifiedBridge) hv -= 2; + else if(w == waVinePlant) hv--; else if(chaosmode && c2->land != laCaves && c2->land != laEmerald) ; 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)) - c->aitmp+=100; - if(w == waThumperOn) c->aitmp+=100; - if(w == waFire) c->aitmp+=100; - if(w == waBigStatue) c->aitmp-=100; - if(c2->item && !peace::on) c->aitmp+=2; - if(c2->monst == moZombie) c->aitmp += 10; - if(c2->monst == moGhost) c->aitmp += 10; - if(c2->monst == moTentacleGhost) c->aitmp += 10; - if(c2->monst == moFriendlyGhost) c->aitmp += 10; - if(c2->monst == moSkeleton) c->aitmp ++; - if(c2->monst == moGargoyle) c->aitmp--; - if(c2->monst == moDraugr) c->aitmp--; - if(isDragon(c2->monst)) c->aitmp++; - if(c2->monst == moNecromancer) c->aitmp += 10; - if(c2->monst == moWormtail) c->aitmp++; - if(c2->monst == moTentacletail) c->aitmp-=2; - if(isIvy(c2)) c->aitmp--; - if(isDemon(c2)) c->aitmp-=3; + hv+=100; + if(w == waThumperOn) hv+=100; + if(w == waFire) hv+=100; + if(w == waBigStatue) hv-=100; + if(c2->item && !peace::on) hv+=2; + if(c2->monst == moZombie) hv += 10; + if(c2->monst == moGhost) hv += 10; + if(c2->monst == moTentacleGhost) hv += 10; + if(c2->monst == moFriendlyGhost) hv += 10; + if(c2->monst == moSkeleton) hv ++; + if(c2->monst == moGargoyle) hv--; + if(c2->monst == moDraugr) hv--; + if(isDragon(c2->monst)) hv++; + if(c2->monst == moNecromancer) hv += 10; + if(c2->monst == moWormtail) hv++; + if(c2->monst == moTentacletail) hv-=2; + if(isIvy(c2)) hv--; + if(isDemon(c2)) hv-=3; // if(c2->monst) c->tmp++; // if(c2->monst == moTroll) c->tmp -= 3; } } else if(c->land == laLivefjord) { - c->aitmp = 0; + hv = 0; if(c->monst == moWaterElemental) - c->aitmp += 1000; + hv += 1000; if(isPlayerInBoatOn(c) && markOrb(itOrbWater)) - c->aitmp += 1000; + hv += 1000; if(c->monst == moEarthElemental) - c->aitmp -= 1000; + hv -= 1000; if(isPlayerOn(c) && markOrb(itOrbDigging)) - c->aitmp -= 1000; + hv -= 1000; for(int j=0; jtype; j++) if(c->mov[j]) { cell *c2 = c->mov[j]; 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) ; 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) - c->aitmp -= 10; + hv -= 10; if(c2->wall == waBigStatue) - c->aitmp -= 10; + hv -= 10; if(c2->wall == waSea || c2->wall == waBoat) - c->aitmp += (c2->land == laLivefjord ? 1 : 100); + hv += (c2->land == laLivefjord ? 1 : 100); if(c2->monst == moWaterElemental) - c->aitmp += 1000; + hv += 1000; if(isPlayerOn(c2) && c2->wall == waBoat && markOrb(itOrbWater)) - c->aitmp += 1000; + hv += 1000; if(c2->monst == moEarthElemental) - c->aitmp -= 1000; + hv -= 1000; if(isPlayerOn(c2) && markOrb(itOrbDigging)) - c->aitmp -= 1000; + hv -= 1000; if(items[itOrbEmpathy] && isFriendly(c2) && markEmpathy(itOrbDigging)) - c->aitmp -= 1000; + hv -= 1000; if(c2->wall == waBarrier) { bool landbar = false; @@ -2143,8 +2145,8 @@ void livecaves() { if(!isSealand(c3->land)) landbar = true; } - if(landbar) c->aitmp -= 5; - else c->aitmp += 5; + if(landbar) hv -= 5; + else hv += 5; } } } @@ -2153,13 +2155,14 @@ void livecaves() { for(int i=0; icpdist > gr+1) break; + int hv = heatvals[i]; if(c->wall == waCavefloor || c->wall == waCavewall) { // if(c->land != laCaves) continue; // if(c->wall == waThumper || c->wall == waBonfire) continue; - if(c->aitmp > 0) c->wall = waCavefloor; - if(c->aitmp < 0) { + if(hv > 0) c->wall = waCavefloor; + if(hv < 0) { c->wall = waCavewall; if(c->land != laCaves && c->land != laDeadCaves && c->land != laEmerald && !gardener) { gardener = true; @@ -2168,14 +2171,14 @@ void livecaves() { } } else if(c->land == laLivefjord) { - if(c->aitmp > 0 && c->wall == waStrandedBoat) c->wall = waBoat; - if(c->aitmp > 0 && c->wall == waNone) { + if(hv > 0 && c->wall == waStrandedBoat) c->wall = waBoat; + if(hv > 0 && c->wall == waNone) { if(c->item && c->cpdist == 1 && markOrb(itOrbWater)) collectItem(c); c->wall = waSea; } - if(c->aitmp < 0 && c->wall == waBoat) c->wall = waStrandedBoat; - if(c->aitmp < 0 && c->wall == waSea) c->wall = waNone; + if(hv < 0 && c->wall == waBoat) c->wall = waStrandedBoat; + if(hv < 0 && c->wall == waSea) c->wall = waNone; } } @@ -2573,6 +2576,7 @@ namespace kraken { } void attacks() { + pathdata pd(2); bool offboat[MAXPLAYER]; for(int i=0; i > acells; acells.push_back(make_pair(c2, c)); forCellIdEx(c3, i, c) { - c3->monst = moKrakenT, c3->mondir = c->spn(i), - c3->aitmp = sval; + c3->monst = moKrakenT, c3->mondir = c->spn(i), onpath(c3, 0); int i0 = (i+c->spn(c->mondir)-c->mondir+99) % c2->type; c3->hitpoints = hpcount[i0]; acells.push_back(make_pair(c2->mov[i0], c3)); @@ -2665,7 +2668,7 @@ namespace kraken { } commitAnimations(LAYER_BIG); sleep(c); - c->aitmp = sval; + onpath(c, 0); return; } @@ -2834,23 +2837,21 @@ namespace prairie { if(c2) c->mondir = neighborId(c, c2); } - void moveAt(cell *c) { - if(eq(c->aitmp, sval)) return; + void moveAt(cell *c, celllister& cl) { + if(!cl.add(c)) return; vector whirlline; whirlline.push_back(c); - c->aitmp = sval; cell *c2 = prev(c); - while(c2 && !eq(c2->aitmp, sval)) { - whirlline.push_back(c2), c2->aitmp = sval; + while(c2 && !cl.add(c2)) { + whirlline.push_back(c2); c2 = prev(c2); // in sphere/quotient geometries, never break before a bull if((sphere || quotient) && !c2->monst) break; } reverse(whirlline.begin(), whirlline.end()); 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); - // for(int i=0; iaitmp = sval; if(shmup::on) { for(int i=0; icpdist <= gamerange()) { generateBeast(whirlline[i]); @@ -2887,10 +2888,10 @@ namespace prairie { } void move() { - sval++; + celllister cl(manual); for(int i=0; i inmovehistory, inkillhistory, infindhistory; + void restore() { - sval++; + inmovehistory.clear(); + inkillhistory.clear(); + infindhistory.clear(); for(int i=0; iaitmp = sval; + inmovehistory.insert(movehistory[i]); sval++; int sk = isize(killhistory); for(int i=0; imonst; killhistory[i].first->monst = m; - killhistory[i].first->aitmp = sval; + inkillhistory.insert(killhistory[i].first); } int si = isize(findhistory); for(int i=0; iitem; findhistory[i].first->item = m; - findhistory[i].first->aitmp = sval; + infindhistory.insert(findhistory[i].first); } } diff --git a/debug.cpp b/debug.cpp index caf827ef..92a140ae 100644 --- a/debug.cpp +++ b/debug.cpp @@ -333,7 +333,7 @@ void debugScreen() { dialog::addSelItem("celldist", its(celldist(mouseover)), 0); dialog::addSelItem("pathdist", its(mouseover->pathdist), 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) dialog::addSelItem("whirl", gp::disp(gp::get_local_info(mouseover).relative), 0); dialog::addBreak(50); diff --git a/game.cpp b/game.cpp index 4657094d..9597c60a 100644 --- a/game.cpp +++ b/game.cpp @@ -170,7 +170,7 @@ void initcell(cell *c) { c->cpdist = INFD; // current distance from the player c->pathdist = PINFD;// current distance from the player, along paths (used by yetis) c->landparam = 0; c->landflags = 0; c->wparam = 0; - c->aitmp = 0; + c->listindex = -1; c->wall = waNone; c->item = itNone; c->monst = moNone; @@ -2836,26 +2836,6 @@ void computePathdist(eMonster param) { } // 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 > butterflies; void addButterfly(cell *c) { @@ -5786,12 +5766,11 @@ void moveNormals(eMonster param) { } } -void markAmbush(cell *c) { - if(eq(c->aitmp, sval)) return; - c->aitmp = sval; +void markAmbush(cell *c, celllister& cl) { + if(!cl.add(c)) return; forCellEx(c2, c) if(c2->cpdist < c->cpdist) - markAmbush(c2); + markAmbush(c2, cl); } int ambush_distance; @@ -5799,30 +5778,30 @@ bool ambushed; void checkAmbushState() { if(havewhat & HF_HUNTER) { - sval++; + celllister cl(manual); for(cell *c: dcal) { if(c->monst == moHunterDog) { if(c->cpdist > ambush_distance) ambush_distance = c->cpdist; - markAmbush(c); + markAmbush(c, cl); } if(c->monst == moHunterGuard && c->cpdist <= 4) - markAmbush(c); + markAmbush(c, cl); } if(items[itHunting] > 5 && items[itHunting] <= 22) { int q = 0; for(int i=0; iaitmp, sval)) - q++; + if(cl.listed(c2)) + q++; if(q == 1) havewhat |= HF_FAILED_AMBUSH; if(q == 2) { for(int i=0; iaitmp, sval)) + if(cl.listed(c2)) forCellEx(c3, playerpos(i)) if(c3 != c2 && isNeighbor(c2,c3)) - if(eq(c3->aitmp, sval)) + if(cl.listed(c3)) havewhat |= HF_FAILED_AMBUSH; } if(havewhat & HF_FAILED_AMBUSH && ambushed) { @@ -6546,7 +6525,6 @@ int ambush(cell *c, eItem what) { celllister cl(c, maxdist, 1000000, NULL); cell *c0 = c; int d = 0; - cl.prepare(); int dogs0 = 0; for(cell *cx: cl.lst) { int dh = cl.getdist(cx); diff --git a/graph.cpp b/graph.cpp index ad8075fa..eafc7877 100644 --- a/graph.cpp +++ b/graph.cpp @@ -586,7 +586,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks, 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; @@ -1809,7 +1809,7 @@ bool dont_face_pc = false; 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()) poly_outline = @@ -2981,7 +2981,7 @@ void setcolors(cell *c, int& wcol, int &fcol) { } 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; else fcol = wcol; @@ -3648,7 +3648,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { bool hidden = itemHidden(c); bool hiddens = itemHiddenFromSight(c); - if(conformal::includeHistory && eq(c->aitmp, sval)) { + if(conformal::includeHistory && conformal::infindhistory.count(c)) { hidden = true; hiddens = false; } @@ -4211,7 +4211,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { 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); char xch = winf[c->wall].glyph; diff --git a/hyper.h b/hyper.h index f2d38f5d..ff6b4508 100644 --- a/hyper.h +++ b/hyper.h @@ -369,10 +369,7 @@ struct cell : gcell { // wall parameter, used for remaining power of Bonfires and Thumpers char wparam; - // 'tmp' is used for: - // pathfinding algorithm used by monsters with atypical movement (which do not use pathdist) - // bugs' pathfinding algorithm - short aitmp; + int listindex; uint32_t spintable; int spin(int d) { return tspin(spintable, d); } @@ -1064,6 +1061,7 @@ namespace conformal { extern vector > killhistory; extern vector > findhistory; extern vector movehistory; + extern set inmovehistory, inkillhistory, infindhistory; extern bool includeHistory; extern ld rotation; extern int do_rotate; @@ -1199,7 +1197,6 @@ bool isAlchAny(cell *c); #define MODECODES 255 extern cellwalker cwt; // player character position -extern int sval; extern array items; extern array kills; @@ -2546,28 +2543,37 @@ extern vector allmaps; // list all cells in distance at most maxdist, or until when maxcount cells are reached +extern struct manual_t {} manual; + struct celllister { vector lst; vector tmps; vector dists; - void add(cell *c, int d) { - if(eq(c->aitmp, sval)) return; - c->aitmp = sval; - tmps.push_back(c->aitmp); + bool listed(cell *c) { + return c->listindex >= 0 && c->listindex < isize(lst) && lst[c->listindex] == c; + } + + bool add(cell *c) { + if(listed(c)) return false; + tmps.push_back(c->listindex); 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() { - for(int i=0; iaitmp = tmps[i]; + for(int i=0; ilistindex = tmps[i]; + } + + celllister(manual_t) { } celllister(cell *orig, int maxdist, int maxcount, cell *breakon) { - lst.clear(); - tmps.clear(); - dists.clear(); - sval++; add(orig, 0); cell *last = orig; for(int i=0; iaitmp = 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; - } - + int getdist(cell *c) { return dists[c->listindex]; } }; hrmap *newAltMap(heptagon *o); @@ -3569,4 +3566,28 @@ bool confusingGeometry(); 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(); + } + }; + } diff --git a/landgen.cpp b/landgen.cpp index e6f1a2f8..b2b6e5cf 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -60,12 +60,8 @@ bool reptilecheat = false; #define ONEMPTY if(d == 7 && passable(c, NULL, 0) && !safety) -vector noescape_list; - -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); +bool blizzard_no_escape1(cell *c, celllister &cl) { + if(!cl.add(c)) return true; if(c->item == itOrbSafety) return false; forCellEx(c2, c) { @@ -73,16 +69,15 @@ bool blizzard_no_escape1(cell *c) { continue; if(c2->land != laBlizzard && passable(c2, NULL, 0)) return false; - if(!againstWind(c2, c) && !blizzard_no_escape1(c2)) + if(!againstWind(c2, c) && !blizzard_no_escape1(c2, cl)) return false; } return true; } bool blizzard_no_escape(cell *c) { - sval++; - noescape_list.resize(0); - return blizzard_no_escape1(c); + celllister cl(manual); + return blizzard_no_escape1(c, cl); } bool out_ruin(cell *c) { diff --git a/mapeditor.cpp b/mapeditor.cpp index 3a298e22..7fe592ef 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -267,8 +267,9 @@ namespace mapstream { c->bardir = NOBARRIERS; // fixspin(rspin, loadChar(), c->type); if(vernum < 7400) { - load(c->aitmp); - c->wparam = c->aitmp; + short z; + load(z); + c->wparam = z; } else load(c->wparam); load(c->landparam); @@ -620,7 +621,7 @@ namespace mapeditor { vector > spill_list; - void list_spill(cellwalker tgt, cellwalker src) { + void list_spill(cellwalker tgt, cellwalker src, celllister& cl) { spill_list.clear(); sval++; spill_list.emplace_back(tgt, src); int crad = 0, nextstepat = 0; @@ -633,8 +634,7 @@ namespace mapeditor { for(int i=0; itype; i++) { auto sd2 = sd; sd2.first = sd2.first + i + wstep; - if(eq(sd2.first.c->aitmp, sval)) continue; - sd2.first.c->aitmp = sval; + if(!cl.add(sd2.first.c)) continue; if(sd2.second.c) { sd2.second = sd2.second + i + wstep; if(sd2.second.c->land == laNone) continue; @@ -668,7 +668,7 @@ namespace mapeditor { } #endif - void editAt(cellwalker where) { + void editAt(cellwalker where, celllister& cl) { if(painttype == 4 && radius) { if(where.c->type != copysource.c->type) return; @@ -677,7 +677,7 @@ namespace mapeditor { where += 1; } if(painttype != 4) copysource.c = NULL; - list_spill(where, copysource); + list_spill(where, copysource, cl); for(auto& st: spill_list) editCell(st); @@ -685,34 +685,30 @@ namespace mapeditor { void allInPattern(cellwalker where) { + celllister cl(manual); if(!patterns::whichPattern) { - editAt(where); + editAt(where, cl); return; } - vector v; - v.push_back(where.c); - sval++; - where.c->aitmp = sval; + cl.add(where.c); int at = 0; - while(at < isize(v)) { - cell *c2 = v[at]; + while(at < isize(cl.lst)) { + cell *c2 = cl.lst[at]; at++; - forCellEx(c3, c2) - if(!eq(c3->aitmp, sval)) - c3->aitmp = sval, v.push_back(c3); + forCellEx(c3, c2) cl.add(c3); } auto si = patterns::getpatterninfo0(where.c); int cdir = where.spin; if(cdir >= 0) cdir = cdir - si.dir; - for(cell* c2: v) { + for(cell* c2: cl.lst) { auto si2 = patterns::getpatterninfo0(c2); 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; } } diff --git a/monstergen.cpp b/monstergen.cpp index 9053e047..43cf6786 100644 --- a/monstergen.cpp +++ b/monstergen.cpp @@ -242,18 +242,17 @@ int getSeepcount() { } bool canReachPlayer(cell *cf, eMonster m) { - vector v; - sval++; - v.push_back(cf); cf->aitmp = sval; - for(int i=0; itype; j++) { cell *c2 = c->mov[j]; 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(isPlayerOn(c2)) return true; - c2->aitmp = sval; v.push_back(c2); + cl.add(c2); } } return false; diff --git a/orbs.cpp b/orbs.cpp index 1c101395..0ccc6f4e 100644 --- a/orbs.cpp +++ b/orbs.cpp @@ -247,19 +247,16 @@ bool distanceBound(cell *c1, cell *c2, int d) { } void checkFreedom(cell *cf) { - sval++; - static vector avcells; - avcells.clear(); - avcells.push_back(cf); - cf->aitmp = sval; - for(int i=0; icpdist >= 5) return; for(int i=0; itype; i++) { cell *c2 = c->mov[i]; // todo leader + if(cl.listed(c2)) 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; bool monsterhere = false; for(int j=0; jtype; j++) { @@ -267,10 +264,7 @@ void checkFreedom(cell *cf) { if(c3 && c3->monst && !isFriendly(c3)) monsterhere = true; } - if(!monsterhere) { - c2->aitmp = sval; - avcells.push_back(c2); - } + if(!monsterhere) cl.add(c2); } } addMessage(XLAT("Your %1 activates!", itOrbFreedom)); diff --git a/yendor.cpp b/yendor.cpp index 9235d9cb..5cd95291 100644 --- a/yendor.cpp +++ b/yendor.cpp @@ -1011,14 +1011,14 @@ namespace peace { clister.emplace_back(cp, cp); int id = 0; - sval++; + celllister cl(manual); while(id < isize(clister)) { cell *c = clister[id].first; cell *fr = clister[id].second; setdist(c, 5, NULL); 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; bool next; if(specialland == laRlyeh) @@ -1031,7 +1031,7 @@ namespace peace { goto again; } clister.emplace_back(c2, fr); - c2->aitmp = sval; + cl.add(c2); } id++; }