void npc_next_pos_line_of_sight_tunnel(dungeon *d, character *c, pair_t next) { pair_t dir; dir[dim_y] = d->PC->position[dim_y] - c->position[dim_y]; dir[dim_x] = d->PC->position[dim_x] - c->position[dim_x]; if (dir[dim_y]) { dir[dim_y] /= abs(dir[dim_y]); } if (dir[dim_x]) { dir[dim_x] /= abs(dir[dim_x]); } dir[dim_x] += next[dim_x]; dir[dim_y] += next[dim_y]; if (hardnesspair(dir) <= 60) { if (hardnesspair(dir)) { hardnesspair(dir) = 0; mappair(dir) = ter_floor_hall; /* Update distance maps because map has changed. */ dijkstra(d); dijkstra_tunnel(d); } next[dim_x] = dir[dim_x]; next[dim_y] = dir[dim_y]; } else { hardnesspair(dir) -= 60; } }
void npc_next_pos_rand_tunnel(dungeon *d, character *c, pair_t next) { pair_t n; union { uint32_t i; uint8_t a[4]; } r; do { n[dim_y] = next[dim_y]; n[dim_x] = next[dim_x]; r.i = rand(); if (r.a[0] > 85 /* 255 / 3 */) { if (r.a[0] & 1) { n[dim_y]--; } else { n[dim_y]++; } } if (r.a[1] > 85 /* 255 / 3 */) { if (r.a[1] & 1) { n[dim_x]--; } else { n[dim_x]++; } } } while (mappair(n) == ter_wall_immutable); if (hardnesspair(n) <= 85) { if (hardnesspair(n)) { hardnesspair(n) = 0; mappair(n) = ter_floor_hall; /* Update distance maps because map has changed. */ dijkstra(d); dijkstra_tunnel(d); } next[dim_x] = n[dim_x]; next[dim_y] = n[dim_y]; } else { hardnesspair(n) -= 85; } }
static int place_rooms(dungeon_t *d) { pair_t p; uint32_t i; int success; room_t *r; for (success = 0; !success; ) { success = 1; for (i = 0; success && i < d->num_rooms; i++) { r = d->rooms + i; r->position[dim_x] = 1 + rand() % (DUNGEON_X - 2 - r->size[dim_x]); r->position[dim_y] = 1 + rand() % (DUNGEON_Y - 2 - r->size[dim_y]); for (p[dim_y] = r->position[dim_y] - 1; success && p[dim_y] < r->position[dim_y] + r->size[dim_y] + 1; p[dim_y]++) { for (p[dim_x] = r->position[dim_x] - 1; success && p[dim_x] < r->position[dim_x] + r->size[dim_x] + 1; p[dim_x]++) { if (mappair(p) >= ter_floor) { success = 0; empty_dungeon(d); } else if ((p[dim_y] != r->position[dim_y] - 1) && (p[dim_y] != r->position[dim_y] + r->size[dim_y]) && (p[dim_x] != r->position[dim_x] - 1) && (p[dim_x] != r->position[dim_x] + r->size[dim_x])) { mappair(p) = ter_floor_room; hardnesspair(p) = 0; } } } } } return 0; }
void npc_next_pos_gradient(dungeon *d, npc *c, pair_t next) { /* Handles both tunneling and non-tunneling versions */ pair_t min_next; uint16_t min_cost; if (c->characteristics & NPC_TUNNEL) { min_cost = (d->pc_tunnel[next[dim_y] - 1][next[dim_x]] + (d->hardness[next[dim_y] - 1][next[dim_x]] / 60)); min_next[dim_x] = next[dim_x]; min_next[dim_y] = next[dim_y] - 1; if ((d->pc_tunnel[next[dim_y] + 1][next[dim_x] ] + (d->hardness[next[dim_y] + 1][next[dim_x]] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y] + 1][next[dim_x]] + (d->hardness[next[dim_y] + 1][next[dim_x]] / 60)); min_next[dim_x] = next[dim_x]; min_next[dim_y] = next[dim_y] + 1; } if ((d->pc_tunnel[next[dim_y] ][next[dim_x] + 1] + (d->hardness[next[dim_y] ][next[dim_x] + 1] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y]][next[dim_x] + 1] + (d->hardness[next[dim_y]][next[dim_x] + 1] / 60)); min_next[dim_x] = next[dim_x] + 1; min_next[dim_y] = next[dim_y]; } if ((d->pc_tunnel[next[dim_y] ][next[dim_x] - 1] + (d->hardness[next[dim_y] ][next[dim_x] - 1] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y]][next[dim_x] - 1] + (d->hardness[next[dim_y]][next[dim_x] - 1] / 60)); min_next[dim_x] = next[dim_x] - 1; min_next[dim_y] = next[dim_y]; } if ((d->pc_tunnel[next[dim_y] - 1][next[dim_x] + 1] + (d->hardness[next[dim_y] - 1][next[dim_x] + 1] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y] - 1][next[dim_x] + 1] + (d->hardness[next[dim_y] - 1][next[dim_x] + 1] / 60)); min_next[dim_x] = next[dim_x] + 1; min_next[dim_y] = next[dim_y] - 1; } if ((d->pc_tunnel[next[dim_y] + 1][next[dim_x] + 1] + (d->hardness[next[dim_y] + 1][next[dim_x] + 1] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y] + 1][next[dim_x] + 1] + (d->hardness[next[dim_y] + 1][next[dim_x] + 1] / 60)); min_next[dim_x] = next[dim_x] + 1; min_next[dim_y] = next[dim_y] + 1; } if ((d->pc_tunnel[next[dim_y] - 1][next[dim_x] - 1] + (d->hardness[next[dim_y] - 1][next[dim_x] - 1] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y] - 1][next[dim_x] - 1] + (d->hardness[next[dim_y] - 1][next[dim_x] - 1] / 60)); min_next[dim_x] = next[dim_x] - 1; min_next[dim_y] = next[dim_y] - 1; } if ((d->pc_tunnel[next[dim_y] + 1][next[dim_x] - 1] + (d->hardness[next[dim_y] + 1][next[dim_x] - 1] / 60)) < min_cost) { min_cost = (d->pc_tunnel[next[dim_y] + 1][next[dim_x] - 1] + (d->hardness[next[dim_y] + 1][next[dim_x] - 1] / 60)); min_next[dim_x] = next[dim_x] - 1; min_next[dim_y] = next[dim_y] + 1; } if (hardnesspair(min_next) <= 60) { if (hardnesspair(min_next)) { hardnesspair(min_next) = 0; mappair(min_next) = ter_floor_hall; /* Update distance maps because map has changed. */ dijkstra(d); dijkstra_tunnel(d); } next[dim_x] = min_next[dim_x]; next[dim_y] = min_next[dim_y]; } else { hardnesspair(min_next) -= 60; } } else { /* Make monsters prefer cardinal directions */ if (d->pc_distance[next[dim_y] - 1][next[dim_x] ] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_y]--; return; } if (d->pc_distance[next[dim_y] + 1][next[dim_x] ] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_y]++; return; } if (d->pc_distance[next[dim_y] ][next[dim_x] + 1] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_x]++; return; } if (d->pc_distance[next[dim_y] ][next[dim_x] - 1] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_x]--; return; } if (d->pc_distance[next[dim_y] - 1][next[dim_x] + 1] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_y]--; next[dim_x]++; return; } if (d->pc_distance[next[dim_y] + 1][next[dim_x] + 1] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_y]++; next[dim_x]++; return; } if (d->pc_distance[next[dim_y] - 1][next[dim_x] - 1] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_y]--; next[dim_x]--; return; } if (d->pc_distance[next[dim_y] + 1][next[dim_x] - 1] < d->pc_distance[next[dim_y]][next[dim_x]]) { next[dim_y]++; next[dim_x]--; return; } } }
/* This is the same basic algorithm as in move.c, but * * subtle differences make it difficult to reuse. */ static void dijkstra_corridor(dungeon_t *d, pair_t from, pair_t to) { static corridor_path_t path[DUNGEON_Y][DUNGEON_X], *p; static uint32_t initialized = 0; heap_t h; uint32_t x, y; if (!initialized) { for (y = 0; y < DUNGEON_Y; y++) { for (x = 0; x < DUNGEON_X; x++) { path[y][x].pos[dim_y] = y; path[y][x].pos[dim_x] = x; } } initialized = 1; } for (y = 0; y < DUNGEON_Y; y++) { for (x = 0; x < DUNGEON_X; x++) { path[y][x].cost = INT_MAX; } } path[from[dim_y]][from[dim_x]].cost = 0; heap_init(&h, corridor_path_cmp, NULL); for (y = 0; y < DUNGEON_Y; y++) { for (x = 0; x < DUNGEON_X; x++) { if (mapxy(x, y) != ter_wall_immutable) { path[y][x].hn = heap_insert(&h, &path[y][x]); } else { path[y][x].hn = NULL; } } } while ((p = (corridor_path_t *) heap_remove_min(&h))) { p->hn = NULL; if ((p->pos[dim_y] == to[dim_y]) && p->pos[dim_x] == to[dim_x]) { for (x = to[dim_x], y = to[dim_y]; (x != from[dim_x]) || (y != from[dim_y]); p = &path[y][x], x = p->from[dim_x], y = p->from[dim_y]) { if (mapxy(x, y) != ter_floor_room) { mapxy(x, y) = ter_floor_hall; hardnessxy(x, y) = 0; } } heap_delete(&h); return; } if ((path[p->pos[dim_y] - 1][p->pos[dim_x] ].hn) && (path[p->pos[dim_y] - 1][p->pos[dim_x] ].cost > p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_x] != from[dim_x]) ? 48 : 0))) { path[p->pos[dim_y] - 1][p->pos[dim_x] ].cost = p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_x] != from[dim_x]) ? 48 : 0); path[p->pos[dim_y] - 1][p->pos[dim_x] ].from[dim_y] = p->pos[dim_y]; path[p->pos[dim_y] - 1][p->pos[dim_x] ].from[dim_x] = p->pos[dim_x]; heap_decrease_key_no_replace(&h, path[p->pos[dim_y] - 1] [p->pos[dim_x] ].hn); } if ((path[p->pos[dim_y] ][p->pos[dim_x] - 1].hn) && (path[p->pos[dim_y] ][p->pos[dim_x] - 1].cost > p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_y] != from[dim_y]) ? 48 : 0))) { path[p->pos[dim_y] ][p->pos[dim_x] - 1].cost = p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_y] != from[dim_y]) ? 48 : 0); path[p->pos[dim_y] ][p->pos[dim_x] - 1].from[dim_y] = p->pos[dim_y]; path[p->pos[dim_y] ][p->pos[dim_x] - 1].from[dim_x] = p->pos[dim_x]; heap_decrease_key_no_replace(&h, path[p->pos[dim_y] ] [p->pos[dim_x] - 1].hn); } if ((path[p->pos[dim_y] ][p->pos[dim_x] + 1].hn) && (path[p->pos[dim_y] ][p->pos[dim_x] + 1].cost > p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_y] != from[dim_y]) ? 48 : 0))) { path[p->pos[dim_y] ][p->pos[dim_x] + 1].cost = p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_y] != from[dim_y]) ? 48 : 0); path[p->pos[dim_y] ][p->pos[dim_x] + 1].from[dim_y] = p->pos[dim_y]; path[p->pos[dim_y] ][p->pos[dim_x] + 1].from[dim_x] = p->pos[dim_x]; heap_decrease_key_no_replace(&h, path[p->pos[dim_y] ] [p->pos[dim_x] + 1].hn); } if ((path[p->pos[dim_y] + 1][p->pos[dim_x] ].hn) && (path[p->pos[dim_y] + 1][p->pos[dim_x] ].cost > p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_x] != from[dim_x]) ? 48 : 0))) { path[p->pos[dim_y] + 1][p->pos[dim_x] ].cost = p->cost + (hardnesspair(p->pos) ? hardnesspair(p->pos) : 8) + ((p->pos[dim_x] != from[dim_x]) ? 48 : 0); path[p->pos[dim_y] + 1][p->pos[dim_x] ].from[dim_y] = p->pos[dim_y]; path[p->pos[dim_y] + 1][p->pos[dim_x] ].from[dim_x] = p->pos[dim_x]; heap_decrease_key_no_replace(&h, path[p->pos[dim_y] + 1] [p->pos[dim_x] ].hn); } } }