1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 17:10:36 +00:00

fixed some issues with adjacency taken into account incorrectly with Hedgehogs/Flailguards/Pikemen and Warp/halfvines

This commit is contained in:
Zeno Rogue 2018-06-12 16:05:39 +02:00
parent fc23c64c5e
commit c5468db000
2 changed files with 34 additions and 42 deletions

View File

@ -942,6 +942,20 @@ bool isChild(cell *w, cell *killed) {
return w == killed; return w == killed;
} }
bool logical_adjacent(cell *c1, eMonster m1, cell *c2) {
if(!c1 || !c2) return true; // cannot really check
eMonster m2 = c2->monst;
if(!isNeighbor(c1, c2))
return false;
if(thruVine(c1, c2) && !attackThruVine(m1) && !attackThruVine(m2) &&
!checkOrb(m1, itOrbAether) && !checkOrb(m2, itOrbAether))
return false;
if(nonAdjacent(c1, c2) && !attackNonAdjacent(m1) && !attackNonAdjacent(m2) &&
!checkOrb(m1, itOrb37) && !checkOrb(m1, itOrbAether) && !checkOrb(m2, itOrbAether))
return false;
return true;
}
bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) { bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) {
// cannot eat worms // cannot eat worms
@ -1001,21 +1015,12 @@ bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) {
if(m2 == moGreater || m2 == moGreaterM) if(m2 == moGreater || m2 == moGreaterM)
if(!(flags & (AF_MAGIC | AF_SWORD_INTO | AF_HORNS | AF_CRUSH))) return false; if(!(flags & (AF_MAGIC | AF_SWORD_INTO | AF_HORNS | AF_CRUSH))) return false;
if(!(flags & AF_GUN)) { if(!(flags & (AF_GUN | AF_SWORD | AF_SWORD_INTO | AF_MAGIC)))
if(!logical_adjacent(c1, m1, c2)) return false;
if(c1 && c2 && nonAdjacent(c1,c2) && !attackNonAdjacent(m1) && !attackNonAdjacent(m2) && if(!(flags & (AF_LANCE | AF_STAB | AF_BACK | AF_APPROACH | AF_GUN | AF_MAGIC)))
!checkOrb(m1, itOrb37) && !checkOrb(m1, itOrbAether) && !checkOrb(m2, itOrbAether))
return false;
if(c1 && c2 && thruVine(c1,c2) && !attackThruVine(m1) && !attackThruVine(m2) &&
!checkOrb(m1, itOrbAether) && !checkOrb(m2, itOrbAether))
return false;
if(!(flags & (AF_LANCE | AF_STAB | AF_BACK | AF_APPROACH)))
if(c1 && c2 && againstRose(c1, c2) && !ignoresSmell(m1)) if(c1 && c2 && againstRose(c1, c2) && !ignoresSmell(m1))
return false; return false;
}
if(m2 == moShadow && !(flags & AF_SWORD)) return false; if(m2 == moShadow && !(flags & AF_SWORD)) return false;
if(isWorm(m2) && m2 != moTentacleGhost && !isDragon(m2)) return false; if(isWorm(m2) && m2 != moTentacleGhost && !isDragon(m2)) return false;
@ -1051,7 +1056,7 @@ bool stalemate1::isKilled(cell *w) {
if((w == swordnext[b] || w == swordtransit[b]) && canAttack(moveto, who, w, w->monst, AF_SWORD)) if((w == swordnext[b] || w == swordtransit[b]) && canAttack(moveto, who, w, w->monst, AF_SWORD))
return true; return true;
if(isNeighbor(w, moveto) && moveto != comefrom) { if(logical_adjacent(moveto, who, w) && moveto != comefrom) {
int wid = neighborId(moveto, w); int wid = neighborId(moveto, w);
int wfrom = neighborId(moveto, comefrom); int wfrom = neighborId(moveto, comefrom);
int flag = AF_APPROACH; int flag = AF_APPROACH;
@ -1067,7 +1072,7 @@ bool stalemate1::isKilled(cell *w) {
return true; return true;
} }
if(isNeighbor(w, comefrom) && isNeighbor(w, moveto) && moveto != comefrom) if(logical_adjacent(comefrom, who, w) && logical_adjacent(moveto, who, w) && moveto != comefrom)
if(canAttack(moveto, who, w, w->monst, AF_STAB)) if(canAttack(moveto, who, w, w->monst, AF_STAB))
return true; return true;
@ -1155,11 +1160,6 @@ namespace stalemate {
vector<stalemate1> moves; vector<stalemate1> moves;
bool nextturn; bool nextturn;
bool anyKilled() {
for(int i=0; i<size(moves); i++) if(moves[i].killed) return true;
return false;
}
bool isMoveto(cell *c) { bool isMoveto(cell *c) {
for(int i=0; i<size(moves); i++) if(moves[i].moveto == c) return true; for(int i=0; i<size(moves); i++) if(moves[i].moveto == c) return true;
return false; return false;
@ -1228,16 +1228,15 @@ int monstersnear(stalemate1& sm) {
cell *c2 = c->mov[t]; cell *c2 = c->mov[t];
// consider monsters who attack from distance 2 // consider monsters who attack from distance 2
if(c2) for(int u=2; u<=c2->type-2; u++) { if(c2) forCellEx(c3, c2) if(c3 != c) {
cell *c3 = c2->mov[(c->spn(t)+u) % c2->type];
if(!c3) continue;
if(c3->monst != moWitchFlash)
if(nonAdjacent(c, c2) || nonAdjacent(c2,c3) || thruVine(c,c2) || thruVine(c2,c3))
continue;
// only these monsters can attack from two spots... // only these monsters can attack from two spots...
if(c3->monst != moLancer && c3->monst != moWitchSpeed && c3->monst != moWitchFlash) if(!among(c3->monst, moLancer, moWitchSpeed, moWitchFlash))
continue; continue;
if(elec::affected(c3)) continue; // take logical_adjacent into account
if(c3->monst != moWitchFlash)
if(!logical_adjacent(c3, c3->monst, c2) || !logical_adjacent(c2, c3->monst, c))
continue;
if(elec::affected(c3) || stalemate::isKilled(c3)) continue;
if(c3->stuntime) continue; if(c3->stuntime) continue;
// speedwitches can only attack not-fastened monsters, // speedwitches can only attack not-fastened monsters,
// others can only attack if the move is not fastened // others can only attack if the move is not fastened
@ -1250,7 +1249,6 @@ int monstersnear(stalemate1& sm) {
} }
// flashwitches cannot attack if it would kill another enemy // flashwitches cannot attack if it would kill another enemy
if(c3->monst == moWitchFlash && flashWouldKill(c3, 0)) continue; if(c3->monst == moWitchFlash && flashWouldKill(c3, 0)) continue;
if(stalemate::anyKilled() && mirror::isKilledByMirror(c3)) continue;
res++, which = c3->monst; res++, which = c3->monst;
} }
@ -1258,7 +1256,7 @@ int monstersnear(stalemate1& sm) {
if(c2 && if(c2 &&
isArmedEnemy(c2, sm.who) && isArmedEnemy(c2, sm.who) &&
!stalemate::isKilled(c2) && !stalemate::isKilled(c2) &&
(c2->monst != moLancer || isUnarmed(sm.who))) { (c2->monst != moLancer || isUnarmed(sm.who) || !logical_adjacent(c, sm.who, c2))) {
eMonster m = c2->monst; eMonster m = c2->monst;
if(elec::affected(c2)) continue; if(elec::affected(c2)) continue;
if(fast && c2->monst != moWitchSpeed) continue; if(fast && c2->monst != moWitchSpeed) continue;
@ -3515,12 +3513,10 @@ void moveMonster(cell *ct, cell *cf) {
// lancers pierce our friends :( // lancers pierce our friends :(
if(m == moLancer) { if(m == moLancer) {
// printf("lancer stab?\n"); // printf("lancer stab?\n");
for(int u=2; u<=ct->type-2; u++) { forCellEx(c3, ct) if(!logical_adjacent(cf, m, c3))
cell *c3 = ct->mov[(ct->mondir+u)%ct->type];
if(canAttack(ct, moLancer, c3, c3->monst, AF_LANCE | AF_GETPLAYER)) { if(canAttack(ct, moLancer, c3, c3->monst, AF_LANCE | AF_GETPLAYER)) {
attackMonster(c3, AF_LANCE | AF_MSG | AF_GETPLAYER, m); attackMonster(c3, AF_LANCE | AF_MSG | AF_GETPLAYER, m);
} }
}
} }
if(m == moWitchFire) makeflame(cf, 10, false); if(m == moWitchFire) makeflame(cf, 10, false);
@ -3719,11 +3715,9 @@ int moveval(cell *c1, cell *c2, int d, flagtype mf) {
if(m == moLancer) { if(m == moLancer) {
bool lancerok = true; bool lancerok = true;
for(int u=2; u<=c2->type-2; u++) { forCellEx(c3, c2) if(c1 != c3 && !logical_adjacent(c1, m, c3))
cell *c3 = c2->mov[(c1->spn(d)+u)%c2->type]; if(canAttack(c2, moLancer, c3, c3->monst, AF_LANCE | AF_ONLY_ENEMY))
if(c3 && canAttack(c2, moLancer, c3, c3->monst, AF_LANCE | AF_ONLY_ENEMY))
lancerok = false; lancerok = false;
}
if(!lancerok) return 750; if(!lancerok) return 750;
} }
@ -5014,7 +5008,7 @@ void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
if(!c) continue; if(!c) continue;
bool stabthere = false, away = true; bool stabthere = false, away = true;
for(int u=0; u<c->type; u++) if(c->mov[u] == mt) stabthere = true, away = false; if(logical_adjacent(mt, who, c)) stabthere = true, away = false;
if(stabthere && canAttack(mt,who,c,c->monst,AF_STAB)) { if(stabthere && canAttack(mt,who,c,c->monst,AF_STAB)) {
if(c->monst != moHedge) { if(c->monst != moHedge) {
@ -5027,7 +5021,7 @@ void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
if(tkills() > k) numsh++; if(tkills() > k) numsh++;
} }
if(away && c != mt && canAttack(mt,who,c,c->monst,AF_BACK)) { if(away && c != mt && canAttack(mf,who,c,c->monst,AF_BACK)) {
if(c->monst == moVizier && c->hitpoints > 1) { if(c->monst == moVizier && c->hitpoints > 1) {
fightmessage(c->monst, who, true, AF_BACK); fightmessage(c->monst, who, true, AF_BACK);
c->hitpoints--; c->hitpoints--;
@ -5055,9 +5049,8 @@ void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill) {
} }
} }
if(!isUnarmed(who)) for(int t=0; t<mt->type; t++) { if(!isUnarmed(who)) forCellIdEx(c, t, mt) {
cell *c = mt->mov[t]; if(!logical_adjacent(mt, who, c)) continue;
if(!c) continue;
eMonster mm = c->monst; eMonster mm = c->monst;
int flag = AF_APPROACH; int flag = AF_APPROACH;
if(angledist(mt, backdir, t) >= S7/2) flag |= AF_HORNS; if(angledist(mt, backdir, t) >= S7/2) flag |= AF_HORNS;

View File

@ -1360,7 +1360,6 @@ namespace stalemate {
bool isKilled(cell *c); bool isKilled(cell *c);
bool anyKilled();
bool isMoveto(cell *c); bool isMoveto(cell *c);
bool isKilledDirectlyAt(cell *c); bool isKilledDirectlyAt(cell *c);
bool isPushto(cell *c); bool isPushto(cell *c);