// All purpose function to check is spot is free for travel into. bool is_blocked(location to_check) { short i,gr; ter_num_t ter; if(is_out()) { if(impassable(univ.out[to_check.x][to_check.y])) { return true; } if(to_check == univ.party.p_loc) return true; for(i = 0; i < univ.party.out_c.size(); i++) if((univ.party.out_c[i].exists)) if(univ.party.out_c[i].m_loc == to_check) return true; return false; } if((is_town()) || (is_combat())) { ter = univ.town->terrain(to_check.x,to_check.y); gr = univ.scenario.ter_types[ter].picture; // Terrain blocking? if(impassable(ter)) { return true; } // Keep away from marked specials during combat if((is_combat()) && univ.town.is_spot(to_check.x, to_check.y)) return true; if((is_combat()) && (univ.scenario.ter_types[coord_to_ter(to_check.x,to_check.y)].trim_type == eTrimType::CITY)) return true; // TODO: Maybe replace eTrimType::CITY with a blockage == clear/special && is_special() check // Note: The purpose of the above check is to avoid portals. // Party there? if(is_town()) if(to_check == univ.town.p_loc) return true; if(is_combat()) for(i = 0; i < 6; i++) if(univ.party[i].main_status == eMainStatus::ALIVE && to_check == univ.party[i].combat_pos) return true; // Monster there? if(univ.target_there(to_check, TARG_MONST)) return true; // Magic barrier? if(univ.town.is_force_barr(to_check.x,to_check.y)) return true; if(univ.town.is_force_cage(to_check.x,to_check.y)) return true; return false; } return true; }
char pickrandomdirection() { char direction; int x; int y; int timeout = 100; do { direction = '1' + (rand() % 9); whereidbe(direction, &x, &y); if (!impassable(framebuffer[y * 80 + x], x, y)) { break; } timeout--; } while (timeout); if (!timeout) { return 's'; } return direction; }
void spawnnode(int x, int y, char direction, node_t *parent, char target, int targetx, int targety) { int idx; int tx; int ty; if (nodecount >= 2048) { dump_nodes(); fprintf(logfile, "Ran out of nodes to %c @ %i.%i (I'm at %i.%i)\n", target, targetx, targety, myx, myy); return; } if (y < 2 || y > 22) { return; } whereidbe(direction, &tx, &ty); if (notebuffer[myy * 80 + myx] & NOTE_OPENDOOR || notebuffer[ty * 80 + tx] & NOTE_OPENDOOR) { if (notebuffer[ty * 80 + tx] & NOTE_OPENDOOR && ismonster(target) && targetx == tx && targety == ty) { // just trap against the next if } else if (direction == '1' || direction == '3' || direction == '7' || direction == '9') { return; } } /*if (notebuffer[ty * 80 + tx] & NOTE_TRAP) { return; }*/ for (idx = 0; idx < nodecount; idx++) { if (node[idx].x == x && node[idx].y == y) { return; } } if (impassable(framebuffer[y * 80 + x], x, y) && (framebuffer[y * 80 + x] != target || x != targetx || y != targety)) { return; } if (framebuffer[y * 80 + x] == ' ' && (target != ' ' || x != targetx || y != targety)) { return; } node[nodecount].x = x; node[nodecount].y = y; node[nodecount].closed = 0; node[nodecount].direction = direction; node[nodecount].parent = parent; nodecount++; }
bool outd_is_blocked(location to_check) { short i; if(overall_mode == MODE_OUTDOORS) { if(impassable(univ.out[to_check.x][to_check.y])) { return true; } for(i = 0; i < 10; i++) if((univ.party.out_c[i].exists)) if(univ.party.out_c[i].m_loc == to_check) return true; return false; } return false; }
/* Consider moving TO (x,y) BY dir; to reach the destination from * (x,y) took pathcost. */ void evaluate(int x, int y, int dir, int pathcost) { int dx = dxes[dir], dy = dyes[dir]; int fx = x - dx, fy = y - dy; int ix = 80*y + x, fix = 80*fy + fx; int newscore = pathcost + 1 + heuristic(fx,fy); node_t *from_node = &nodes[fix]; /* Let's not be pathing off the map */ if (fx < 0 || fx >= 80 || fy < 1 || fy >= 22) return; if (x == to_x && y == to_y && ismonster(to_object)) { /* Special rule for attacking monsters - normal terrain * effects do not apply in this case */ } else { /* Don't path into impassible terrain */ if (impassable(framebuffer[ix], x, y)) return; if (dx && dy) { /* Moving diagonally! Check if there are doorways. */ if (notebuffer[fix] & NOTE_OPENDOOR) return; if (notebuffer[ix] & NOTE_OPENDOOR) return; } /* Don't path into traps unless forced */ if (notebuffer[ix] & NOTE_TRAP) newscore += 1000; /* prefer a trap over 1001 squares of walking */ } if (from_node->score != SCORE_CLOSED && newscore < from_node->score) { /* Ooh. A better way to solve (fx,fy). */ from_node->score = newscore; from_node->dir = dir; } }
void spawnnode(int x, int y, char direction, node_t *parent, char target, int targetx, int targety, int cx, int cy, unsigned char test) { int idx; int tx; int ty; if (nodecount >= 2048) { dump_nodes(); fprintf(logfile, "Ran out of nodes to %c @ %i.%i (I'm at %i.%i)\n", target, targetx, targety, myx, myy); return; } if (y < 2 || y > 22) { return; } whereidbe(direction, &tx, &ty); if (notebuffer[cy * 80 + cx] & NOTE_OPENDOOR || notebuffer[y * 80 + x] & NOTE_OPENDOOR || notebuffer[ty * 80 + tx] & NOTE_OPENDOOR) { if (notebuffer[ty * 80 + tx] & NOTE_OPENDOOR && ismonster(target) && targetx == tx && targety == ty) { // just trap against the next if } else if (direction == '1' || direction == '3' || direction == '7' || direction == '9') { return; } } // if it's a trap, don't step on it, unless it's unavoidable (no way to // path around it) /* if (notebuffer[ty * 80 + tx] & NOTE_TRAP && avoidabletrap(tx, ty) && (framebuffer[ty * 80 + tx] != target || tx != x || ty != y)) { return; } */ for (idx = 0; idx < nodecount; idx++) { if (node[idx].x == x && node[idx].y == y) { return; } } if (impassable(framebuffer[y * 80 + x], x, y)) { // don't move into a NOTOUCH monster no matter what, unless // we're only TESTING pathability if (framebuffer[y * 80 + x] == target && x == targetx && y == targety && (target != NOTOUCH_MONSTER || test)) { // trap against else for clarity } else { return; } } if (framebuffer[y * 80 + x] == ' ' && (target != ' ' || x != targetx || y != targety)) { return; } node[nodecount].x = x; node[nodecount].y = y; node[nodecount].closed = 0; node[nodecount].direction = direction; node[nodecount].parent = parent; node[nodecount].used = 0; if (parent) { node[nodecount].score = makescore(targetx, targety, x, y, target) + parent->score; } else { node[nodecount].score = makescore(targetx, targety, x, y, target); } nodecount++; }