1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-27 06:27:17 +00:00

bow:: avoid hitting friends

This commit is contained in:
Zeno Rogue 2024-11-03 22:08:21 +01:00
parent bd9e0a7469
commit e72e0f90b5

View File

@ -82,13 +82,15 @@ EX int qadd(cellwalker a, cellwalker b) {
int best_score_res; int best_score_res;
const int BOLT_INVALID = -999999;
EX int bolt_score(cellwalker cw2) { EX int bolt_score(cellwalker cw2) {
int d = cw2.at->cpdist; int d = cw2.at->cpdist;
int ntotal = 2; int ntotal = 2;
if(inmirror(cw2.at)) cw2 = mirror::reflect(cw2); if(inmirror(cw2.at)) cw2 = mirror::reflect(cw2);
if(blocks(cw2.cpeek())) return -1; if(blocks(cw2.cpeek())) return BOLT_INVALID;
if(thruVine(cw2.at, cw2.cpeek())) return -1; if(thruVine(cw2.at, cw2.cpeek())) return BOLT_INVALID;
if(nonAdjacent(cw2.at, cw2.cpeek())) return -1; if(nonAdjacent(cw2.at, cw2.cpeek())) return BOLT_INVALID;
if(cw2.at->monst) { if(cw2.at->monst) {
flagtype attackflags = AF_BOW; flagtype attackflags = AF_BOW;
@ -96,7 +98,9 @@ EX int bolt_score(cellwalker cw2) {
if(items[itOrbSlaying]) attackflags |= AF_CRUSH; if(items[itOrbSlaying]) attackflags |= AF_CRUSH;
if(items[itCurseWeakness]) attackflags |= AF_WEAK; if(items[itCurseWeakness]) attackflags |= AF_WEAK;
if(canAttack(cw2.cpeek(), moPlayer, cw2.at, cw2.at->monst, attackflags)) { if(canAttack(cw2.cpeek(), moPlayer, cw2.at, cw2.at->monst, attackflags)) {
ntotal += 10000; ntotal += 1280 >> d; int sco = 10;
if(isFriendly(cw2.at)) sco = -50;
ntotal += 1000 * sco; ntotal += (128 * sco) >> d;
} }
} }
@ -104,7 +108,9 @@ EX int bolt_score(cellwalker cw2) {
cell *c1 = cw2.at->cmove(t); cell *c1 = cw2.at->cmove(t);
if(!logical_adjacent(cw2.cpeek(), moPlayer, c1)) continue; if(!logical_adjacent(cw2.cpeek(), moPlayer, c1)) continue;
if(canAttack(cw2.cpeek(),moPlayer,c1,c1->monst,AF_STAB)) { if(canAttack(cw2.cpeek(),moPlayer,c1,c1->monst,AF_STAB)) {
ntotal += 10000; ntotal += 1280 >> d; int sco = 10;
if(isFriendly(c1)) sco = -50;
ntotal += 1000 * sco; ntotal += (128 * sco) >> d;
} }
} }
@ -115,19 +121,20 @@ EX vector<int> create_dirseq() {
map<cell*, bowscore> scores; map<cell*, bowscore> scores;
scores[cwt.at].total = 0; scores[cwt.at].total = 0;
int best_score = -1; cell* best_score_at = cwt.at; int best_score = BOLT_INVALID; cell* best_score_at = cwt.at;
for(cell *c: dcal) { for(cell *c: dcal) {
cell *c1 = target_at[c->cpdist]; cell *c1 = target_at[c->cpdist];
if(c1 && c != c1) continue; if(c1 && c != c1) continue;
if(c == c1) { best_score = -1; } if(c == c1) { best_score = BOLT_INVALID; }
bowscore best; bowscore best;
best.total = -1; best.total = BOLT_INVALID;
forCellIdEx(c1, i, c) if(c1->cpdist < c->cpdist && scores.count(c1)) { forCellIdEx(c1, i, c) if(c1->cpdist < c->cpdist && scores.count(c1)) {
auto& last = scores[c1]; auto& last = scores[c1];
auto ocw2 = cellwalker(c, i); auto ocw2 = cellwalker(c, i);
int bonus = bolt_score(ocw2); int bonus = bolt_score(ocw2);
if(bonus < 0) continue; println(hlog, "at ", ocw2, " bonus is ", bonus);
if(bonus == BOLT_INVALID) continue;
int ntotal = last.total + bonus; int ntotal = last.total + bonus;
int dir = 0; int dir = 0;
@ -150,10 +157,10 @@ EX vector<int> create_dirseq() {
best.total = max(best.total, ntotal); best.total = max(best.total, ntotal);
} }
if(best.total > best_score) { best_score = best.total; best_score_at = c; } if(best.total > best_score) { best_score = best.total; best_score_at = c; }
if(best.total > -1) scores[c] = best; if(best.total > BOLT_INVALID) scores[c] = best;
} }
if(best_score == -1) return {}; if(best_score == BOLT_INVALID) return {};
vector<int> dirseq = { NODIR }; vector<int> dirseq = { NODIR };
while(best_score_at != cwt.at) { while(best_score_at != cwt.at) {
@ -197,9 +204,9 @@ EX vector<int> create_dirseq_geometric() {
} }
at = at + best_i; at = at + best_i;
int bonus = bolt_score(at + wstep); int bonus = bolt_score(at + wstep);
best_score_res += bonus; if(bonus != BOLT_INVALID) best_score_res += bonus;
dirseq.push_back(best_i); dirseq.push_back(best_i);
if(bonus < 0) break; if(bonus == BOLT_INVALID) break;
T = T * currentmap->adj(at.at, at.spin); T = T * currentmap->adj(at.at, at.spin);
at = at + wstep; at = at + wstep;
} }