1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-05-15 05:34:08 +00:00

Merge branch 'master' into misc-windows

This commit is contained in:
Zeno Rogue 2018-06-28 15:13:42 +02:00 committed by GitHub
commit 0d0eb06886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 400 additions and 330 deletions

View File

@ -970,15 +970,6 @@ int wallchance(cell *c, bool deepOcean) {
50; 50;
} }
bool mouse_reachability_test(cell *c) {
if(c->pathdist != PINFD)
return true;
forCellEx(c2, c)
if(passable(c, c2, 0) && c2->mpdist < c->mpdist)
return mouse_reachability_test(c2);
return false;
}
bool horo_ok() { bool horo_ok() {
// do the horocycles work in the current geometry? // do the horocycles work in the current geometry?
// (they work in ALL hyperbolic geometries currently!) // (they work in ALL hyperbolic geometries currently!)
@ -1139,7 +1130,7 @@ void buildBigStuff(cell *c, cell *from) {
createAlternateMap(c, 2, hsA); createAlternateMap(c, 2, hsA);
if(c->land == laPalace && ctof(c) && !princess::generating && !shmup::on && multi::players == 1 && horo_ok() && !weirdhyperbolic && if(c->land == laPalace && ctof(c) && !princess::generating && !shmup::on && multi::players == 1 && horo_ok() && !weirdhyperbolic &&
(princess::forceMouse ? mouse_reachability_test(from) : (princess::forceMouse ? canReachPlayer(from, moMouse) :
(hrand(2000) < (peace::on ? 100 : 20))) && (hrand(2000) < (peace::on ? 100 : 20))) &&
!c->master->alt && !c->master->alt &&
(princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on) { (princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on) {

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

@ -2513,3 +2513,15 @@ non-game:
2018.06.24 01:19 Update 10.4g 2018.06.24 01:19 Update 10.4g
- fixed Arrow Traps not killing anything (and possibly other similar cases) - fixed Arrow Traps not killing anything (and possibly other similar cases)
- fixed the 'skip start menu' option
2018.06.28 14:14 Update 10.4h
- fixed the map not being generated far enough in non-std geometries after Teleport (and other orbs)
- fixed the missing message when picking up orbs from a boat
- rewritten various pathfinding (and similar) algorithms in a more robust way
- Orb of Freedom is now checked after the Terracotta Warriors, and it consider active arrow traps as impassable
- kills-at-once achievements now also count the 'original' kill; it no longer counts if a monster performs the killing
- in quotient geometries, the whole world is now generated from the start (otherwise e.g. Blizzard breaks down); also the windmap (used in Blizzard/Volcanic) is now generated correctly in field quotient
- an option to display all floors as 'full', i.e., without spaces between them ('r' in map/graphics editor)
- new commandline options: -fsh (floor shape display) and -noshadow (disable shadows)
- fixed a bug with Orb of Mirror display in OSM

File diff suppressed because one or more lines are too long

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);

131
game.cpp
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;
@ -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,8 +2829,7 @@ 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));
} }
} }
} }
@ -3770,6 +3780,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
@ -3941,7 +3953,7 @@ void beastAttack(cell *c, bool player) {
if(c2->monst && c2->stuntime) { if(c2->monst && c2->stuntime) {
cellwalker bull (c, d); cellwalker bull (c, d);
int subdir = determinizeBullPush(bull); int subdir = determinizeBullPush(bull);
int pushdir = 0; int pushdir = NOHINT;
cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return passable(c, c2, P_BLOW); }, pushdir); cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return passable(c, c2, P_BLOW); }, pushdir);
if(c3 && c3 != c2) if(c3 && c3 != c2)
pushMonster(c3, c2, pushdir); pushMonster(c3, c2, pushdir);
@ -3954,7 +3966,7 @@ void beastAttack(cell *c, bool player) {
if(c2->wall == waThumperOn) { if(c2->wall == waThumperOn) {
cellwalker bull (c, d); cellwalker bull (c, d);
int subdir = determinizeBullPush(bull); int subdir = determinizeBullPush(bull);
int pushdir = 0; int pushdir = NOHINT;
cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, c); }, pushdir); cell *c3 = determinePush(bull, c2, subdir, [c2] (cell *c) { return canPushThumperOn(c, c2, c); }, pushdir);
if(c3 && c3 != c2) if(c3 && c3 != c2)
pushThumper(c2, c3); pushThumper(c2, c3);
@ -4379,7 +4391,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 +4473,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 +4530,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 +4545,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 +4558,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 +4615,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 +4678,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 +4703,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 +4711,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(3);
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);
@ -4977,9 +4990,11 @@ void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) {
sideAttack(mf, dir, who, 2, itOrbSide2); sideAttack(mf, dir, who, 2, itOrbSide2);
sideAttack(mf, dir, who, 3, itOrbSide3); sideAttack(mf, dir, who, 3, itOrbSide3);
if(who == moPlayer) {
int kills = tkills() - k + bonuskill; int kills = tkills() - k + bonuskill;
if(kills >= 5) achievement_gain("MELEE5"); if(kills >= 5) achievement_gain("MELEE5");
} }
}
void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) { void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
int numsh = 0, numflail = 0, numlance = 0, numslash = 0; int numsh = 0, numflail = 0, numlance = 0, numslash = 0;
@ -5067,6 +5082,7 @@ void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
} }
} }
if(who == moPlayer) {
if(numsh) achievement_count("STAB", numsh, 0); if(numsh) achievement_count("STAB", numsh, 0);
if(numlance && numflail && numsh) achievement_gain("MELEE3"); if(numlance && numflail && numsh) achievement_gain("MELEE3");
@ -5078,6 +5094,7 @@ void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
lastdouble = turncount; lastdouble = turncount;
} }
} }
}
bool cellDangerous(cell *c) { bool cellDangerous(cell *c) {
return cellUnstableOrChasm(c) || isFire(c) || c->wall == waClosedGate; return cellUnstableOrChasm(c) || isFire(c) || c->wall == waClosedGate;
@ -5198,7 +5215,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];
@ -5363,7 +5380,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]) {
@ -5465,7 +5482,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]);
@ -5728,7 +5745,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();
@ -5749,12 +5766,11 @@ void moveNormals(eMonster param) {
} }
} }
void markAmbush(cell *c) { void markAmbush(cell *c, manual_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;
@ -5762,30 +5778,30 @@ bool ambushed;
void checkAmbushState() { void checkAmbushState() {
if(havewhat & HF_HUNTER) { if(havewhat & HF_HUNTER) {
sval++; manual_celllister cl;
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) {
@ -6330,7 +6346,7 @@ void collectMessage(cell *c2, eItem which) {
else if(which == itGreenStone) else if(which == itGreenStone)
addMessage(XLAT("Another Dead Orb.")); addMessage(XLAT("Another Dead Orb."));
else if(itemclass(which) != IC_TREASURE) { else if(itemclass(which) != IC_TREASURE) {
if(c2->wall != waBoat && !inv::activating) if(!inv::activating)
addMessage(XLAT("You have found %the1!", which)); addMessage(XLAT("You have found %the1!", which));
} }
else if(which == itBabyTortoise) { else if(which == itBabyTortoise) {
@ -6509,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);
@ -7191,15 +7206,15 @@ void monstersTurn() {
heat::processheat(); heat::processheat();
// if(elec::havecharge) elec::drawcharges(); // if(elec::havecharge) elec::drawcharges();
orbbull::check();
if(!phase1) terracotta();
if(items[itOrbFreedom]) if(items[itOrbFreedom])
for(int i=0; i<numplayers(); i++) for(int i=0; i<numplayers(); i++)
if(multi::playerActive(i)) if(multi::playerActive(i))
checkFreedom(playerpos(i)); checkFreedom(playerpos(i));
orbbull::check();
if(!phase1) terracotta();
DEBT("check"); DEBT("check");
checkmove(); checkmove();
if(canmove) elec::checklightningfast(); if(canmove) elec::checklightningfast();
@ -7644,6 +7659,8 @@ bool movepcto(int d, int subdir, bool checkonly) {
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK); mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK);
int tk = tkills();
if(goodTortoise) { if(goodTortoise) {
items[itBabyTortoise] += 4; items[itBabyTortoise] += 4;
updateHi(itBabyTortoise, items[itBabyTortoise]); updateHi(itBabyTortoise, items[itBabyTortoise]);
@ -7672,7 +7689,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
} }
} }
sideAttack(cwt.c, d, moPlayer, 0); sideAttack(cwt.c, d, moPlayer, tkills() - tk);
lastmovetype = lmAttack; lastmove = c2; lastmovetype = lmAttack; lastmove = c2;
swordAttackStatic(); swordAttackStatic();
} }

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;

88
hyper.h
View File

@ -2,9 +2,9 @@
// It is quite chaotic. // It is quite chaotic.
// version numbers // version numbers
#define VER "10.4g" #define VER "10.4h"
#define VERNUM 10407 #define VERNUM 10408
#define VERNUM_HEX 0xA0B7 #define VERNUM_HEX 0xA0B8
#include <stdarg.h> #include <stdarg.h>
@ -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,34 +2543,42 @@ 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
struct celllister { struct manual_celllister {
vector<cell*> lst; vector<cell*> lst;
vector<int> tmps; vector<int> tmps;
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);
lst.push_back(c);
dists.push_back(d);
} }
~celllister() { bool add(cell *c) {
for(int i=0; i<isize(lst); i++) lst[i]->aitmp = tmps[i]; if(listed(c)) return false;
tmps.push_back(c->listindex);
c->listindex = isize(lst);
lst.push_back(c);
return true;
}
~manual_celllister() {
for(int i=0; i<isize(lst); i++) lst[i]->listindex = tmps[i];
}
};
struct celllister : manual_celllister {
vector<int> dists;
void add_at(cell *c, int d) {
if(add(c)) dists.push_back(d);
} }
celllister(cell *orig, int maxdist, int maxcount, cell *breakon) { celllister(cell *orig, int maxdist, int maxcount, cell *breakon) {
lst.clear(); add_at(orig, 0);
tmps.clear();
dists.clear();
sval++;
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++) {
cell *c = lst[i]; cell *c = lst[i];
if(maxdist) forCellCM(c2, c) { if(maxdist) forCellCM(c2, c) {
add(c2, dists[i]+1); add_at(c2, dists[i]+1);
if(c2 == breakon) return; if(c2 == breakon) return;
} }
if(c == last) { if(c == last) {
@ -2583,16 +2588,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 +3565,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, manual_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++; manual_celllister cl;
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) {
@ -383,7 +378,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
c->monst = moVizier; c->monst = moVizier;
c->hitpoints = palaceHP(); c->hitpoints = palaceHP();
} }
else if(princess::forceVizier && from->pathdist != PINFD) { else if(princess::forceVizier && hrand(100) < 10 && canReachPlayer(c, moVizier)) {
c->monst = moVizier; c->monst = moVizier;
c->hitpoints = palaceHP(); c->hitpoints = palaceHP();
princess::forceVizier = false; princess::forceVizier = false;

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, manual_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, manual_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) {
manual_celllister cl;
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; manual_celllister cl;
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;
@ -304,6 +303,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

@ -247,29 +247,24 @@ bool distanceBound(cell *c1, cell *c2, int d) {
} }
void checkFreedom(cell *cf) { void checkFreedom(cell *cf) {
sval++; manual_celllister cl;
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;
bool monsterhere = false; bool monsterhere = false;
for(int j=0; j<c2->type; j++) { for(int j=0; j<c2->type; j++) {
cell *c3 = c2->mov[j]; cell *c3 = c2->mov[j];
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));
@ -541,8 +536,7 @@ void teleportTo(cell *dest) {
drainOrb(itOrbTeleport); drainOrb(itOrbTeleport);
movecost(cwt.c, dest); movecost(cwt.c, dest);
playerMoveEffects(cwt.c, dest); playerMoveEffects(cwt.c, dest);
for(int i=9; i>=0; i--) afterplayermoved();
setdist(dest, i, NULL);
bfs(); bfs();
} }
return; return;
@ -557,9 +551,7 @@ void teleportTo(cell *dest) {
addMessage(XLAT("You teleport to a new location!")); addMessage(XLAT("You teleport to a new location!"));
mirror::destroyAll(); mirror::destroyAll();
for(int i=9; i>=0; i--) afterplayermoved();
setdist(cwt.c, i, NULL);
bfs(); bfs();
sword::reset(); sword::reset();
@ -1179,11 +1171,13 @@ eItem targetRangedOrb(cell *c, orbAction a) {
} }
// (4a) colt // (4a) colt
if(!shmup::on && items[itRevolver] && c->monst && canAttack(cwt.c, moPlayer, c, c->monst, AF_GUN) if(!shmup::on && items[itRevolver] && c->monst && canAttack(cwt.c, moPlayer, c, c->monst, AF_GUN)) {
&& c->pathdist <= GUNRANGE && !monstersnearO(a, cwt.c, c, moPlayer, NULL, cwt.c)) { pathdata pd(moEagle);
if(c->pathdist <= GUNRANGE && !monstersnearO(a, cwt.c, c, moPlayer, NULL, cwt.c)) {
if(!isCheck(a)) gun_attack(c); if(!isCheck(a)) gun_attack(c);
return itRevolver; return itRevolver;
} }
}
// (5) psi blast (non-shmup variant) // (5) psi blast (non-shmup variant)
if(!shmup::on && items[itOrbPsi] && c->monst && (isDragon(c->monst) || !isWorm(c)) && c->monst != moShadow && c->monst != moKrakenH) { if(!shmup::on && items[itOrbPsi] && c->monst && (isDragon(c->monst) || !isWorm(c)) && c->monst != moShadow && c->monst != moKrakenH) {

View File

@ -388,6 +388,8 @@ void bantar_frame() {
case 4: case 4:
xdst = .5, ydst = 0; xdst = .5, ydst = 0;
break; break;
default:
xdst = ydst = 0;
} }
/* ld xpos = (!(i&2)) ? xdst : -xdst; /* ld xpos = (!(i&2)) ? xdst : -xdst;

View File

@ -287,15 +287,15 @@ struct cellcrawler {
vector<cellcrawlerdata> data; vector<cellcrawlerdata> data;
void store(const cellwalker& o, int from, int spin) { void store(const cellwalker& o, int from, int spin, manual_celllister& cl) {
if(eq(o.c->aitmp, sval)) return; if(!add(o.c)) return;
o.c->aitmp = sval;
data.emplace_back(o, from, spin); data.emplace_back(o, from, spin);
} }
void build(const cellwalker& start) { void build(const cellwalker& start) {
sval++; sval++;
data.clear(); data.clear();
manual_celllister cl;
store(start, 0, 0); store(start, 0, 0);
for(int i=0; i<isize(data); i++) { for(int i=0; i<isize(data); i++) {
cellwalker cw0 = data[i].orig; cellwalker cw0 = data[i].orig;
@ -594,6 +594,8 @@ void showbestsamples() {
whowon[i]->samples++; whowon[i]->samples++;
} }
int kohrestrict = 1000000;
void sominit(int initto) { void sominit(int initto) {
if(inited < 1 && initto >= 1) { if(inited < 1 && initto >= 1) {
@ -615,6 +617,11 @@ void sominit(int initto) {
} }
else allcells = currentmap->allcells(); else allcells = currentmap->allcells();
if(isize(allcells) > kohrestrict) {
sort(allcells.begin(), allcells.end(), [] (cell *c1, cell *c2) { return hdist0(tC0(shmup::ggmatrix(c1))) < hdist0(tC0(shmup::ggmatrix(c2))); });
allcells.resize(kohrestrict);
}
cells = isize(allcells); cells = isize(allcells);
net.resize(cells); net.resize(cells);
for(int i=0; i<cells; i++) net[i].where = allcells[i], allcells[i]->landparam = i; for(int i=0; i<cells; i++) net[i].where = allcells[i], allcells[i]->landparam = i;
@ -1177,6 +1184,9 @@ int readArgs() {
start_game(); start_game();
verify_crawlers(); verify_crawlers();
} }
else if(argis("-somrestrict")) {
shift(); kohrestrict = argi();
}
else return 1; else return 1;
return 0; return 0;

View File

@ -706,6 +706,7 @@ namespace sag {
forgetedges(i); forgetedges(i);
} }
shmup::fixStorage();
} }
vector<edgeinfo> sagedges; vector<edgeinfo> sagedges;
@ -815,6 +816,8 @@ namespace sag {
printf("loglikelihood = %lf\n", (double) loglik); printf("loglikelihood = %lf\n", (double) loglik);
} }
ld min_visible_weight = .1;
void readsag(const char *fname) { void readsag(const char *fname) {
maxweight = 0; maxweight = 0;
FILE *f = fopen(fname, "rt"); FILE *f = fopen(fname, "rt");
@ -869,7 +872,7 @@ namespace sag {
} */ } */
for(int i=0; i<isize(sagedges); i++) { for(int i=0; i<isize(sagedges); i++) {
edgeinfo& ei = sagedges[i]; edgeinfo& ei = sagedges[i];
ei.visible = ei.weight >= 0.1; ei.visible = ei.weight >= min_visible_weight;
// (ei.weight >= maxwei[ei.i] / 5 || ei.weight >= maxwei[ei.j] / 5); // (ei.weight >= maxwei[ei.i] / 5 || ei.weight >= maxwei[ei.j] / 5);
ei.weight2 = pow((double) ei.weight, (double) edgepower) * edgemul; ei.weight2 = pow((double) ei.weight, (double) edgepower) * edgemul;
@ -1410,6 +1413,9 @@ int readArgs() {
shift(); sag::hightemp = argf(); shift(); sag::hightemp = argf();
shift(); sag::lowtemp = argf(); shift(); sag::lowtemp = argf();
} }
else if(argis("-sagmin")) {
shift(); sag::min_visible_weight = argf();
}
// (2) read the edge data // (2) read the edge data
else if(argis("-sagpar")) { else if(argis("-sagpar")) {
PHASE(3); PHASE(3);

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);
} }
} }
} }

View File

@ -292,6 +292,9 @@ void initgame() {
checkmove(); checkmove();
playermoved = true; playermoved = true;
if(quotient || sphere)
for(cell *c: currentmap->allcells()) setdist(c, 8, NULL);
if(!cheater) gamerange_bonus = genrange_bonus = 0; if(!cheater) gamerange_bonus = genrange_bonus = 0;
} }

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++; manual_celllister cl;
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++;
} }