/** * Set terrain constants to the indices from terrain.txt */ void set_terrain(void) { FEAT_NONE = lookup_feat("unknown grid"); FEAT_FLOOR = lookup_feat("open floor"); FEAT_CLOSED = lookup_feat("closed door"); FEAT_OPEN = lookup_feat("open door"); FEAT_BROKEN = lookup_feat("broken door"); FEAT_LESS = lookup_feat("up staircase"); FEAT_MORE = lookup_feat("down staircase"); FEAT_SECRET = lookup_feat("secret door"); FEAT_RUBBLE = lookup_feat("pile of rubble"); FEAT_PASS_RUBBLE = lookup_feat("pile of passable rubble"); FEAT_MAGMA = lookup_feat("magma vein"); FEAT_QUARTZ = lookup_feat("quartz vein"); FEAT_MAGMA_K = lookup_feat("magma vein with treasure"); FEAT_QUARTZ_K = lookup_feat("quartz vein with treasure"); FEAT_GRANITE = lookup_feat("granite wall"); FEAT_PERM = lookup_feat("permanent wall"); FEAT_LAVA = lookup_feat("lava flow"); }
/** * This function takes a grid location (x, y) and extracts information the * player is allowed to know about it, filling in the grid_data structure * passed in 'g'. * * The information filled in is as follows: * - g->f_idx is filled in with the terrain's feature type, or FEAT_NONE * if the player doesn't know anything about the grid. The function * makes use of the "mimic" field in terrain in order to allow one * feature to look like another (hiding secret doors, invisible traps, * etc). This will return the terrain type the player "Knows" about, * not necessarily the real terrain. * - g->m_idx is set to the monster index, or 0 if there is none (or the * player doesn't know it). * - g->first_kind is set to the object_kind of the first object in a grid * that the player knows about, or NULL for no objects. * - g->muliple_objects is true if there is more than one object in the * grid that the player knows and cares about (to facilitate any special * floor stack symbol that might be used). * - g->in_view is true if the player can currently see the grid - this can * be used to indicate field-of-view, such as through the * OPT(player, view_bright_light) option. * - g->lighting is set to indicate the lighting level for the grid: * LIGHTING_DARK for unlit grids, LIGHTING_LIT for inherently light * grids (lit rooms, etc), LIGHTING_TORCH for grids lit by the player's * light source, and LIGHTING_LOS for grids in the player's line of sight. * Note that lighting is always LIGHTING_LIT for known "interesting" grids * like walls. * - g->is_player is true if the player is on the given grid. * - g->hallucinate is true if the player is hallucinating something "strange" * for this grid - this should pick a random monster to show if the m_idx * is non-zero, and a random object if first_kind is non-zero. * * NOTES: * This is called pretty frequently, whenever a grid on the map display * needs updating, so don't overcomplicate it. * * Terrain is remembered separately from objects and monsters, so can be * shown even when the player can't "see" it. This leads to things like * doors out of the player's view still change from closed to open and so on. * * TODO: * Hallucination is currently disabled (it was a display-level hack before, * and we need it to be a knowledge-level hack). The idea is that objects * may turn into different objects, monsters into different monsters, and * terrain may be objects, monsters, or stay the same. */ void map_info(unsigned y, unsigned x, struct grid_data *g) { struct object *obj; assert(x < (unsigned) cave->width); assert(y < (unsigned) cave->height); /* Default "clear" values, others will be set later where appropriate. */ g->first_kind = NULL; g->trap = NULL; g->multiple_objects = false; g->lighting = LIGHTING_DARK; g->unseen_object = false; g->unseen_money = false; /* Use real feature (remove later) */ g->f_idx = cave->squares[y][x].feat; if (f_info[g->f_idx].mimic) g->f_idx = lookup_feat(f_info[g->f_idx].mimic); g->in_view = (square_isseen(cave, y, x)) ? true : false; g->is_player = (cave->squares[y][x].mon < 0) ? true : false; g->m_idx = (g->is_player) ? 0 : cave->squares[y][x].mon; g->hallucinate = player->timed[TMD_IMAGE] ? true : false; if (g->in_view) { g->lighting = LIGHTING_LOS; if (!square_isglow(cave, y, x) && OPT(player, view_yellow_light)) g->lighting = LIGHTING_TORCH; /* Remember seen feature */ square_memorize(cave, y, x); } else if (!square_isknown(cave, y, x)) { g->f_idx = FEAT_NONE; } else if (square_isglow(cave, y, x)) { g->lighting = LIGHTING_LIT; } /* Use known feature */ g->f_idx = player->cave->squares[y][x].feat; if (f_info[g->f_idx].mimic) g->f_idx = lookup_feat(f_info[g->f_idx].mimic); /* There is a trap in this square */ if (square_istrap(cave, y, x) && square_isknown(cave, y, x)) { struct trap *trap = cave->squares[y][x].trap; /* Scan the square trap list */ while (trap) { if (trf_has(trap->flags, TRF_TRAP) || trf_has(trap->flags, TRF_RUNE)) { /* Accept the trap - only if not disabled, maybe we need * a special graphic for this */ if (!trap->timeout) { g->trap = trap; break; } } trap = trap->next; } } /* Objects */ for (obj = square_object(player->cave, y, x); obj; obj = obj->next) { if (obj->kind == unknown_gold_kind) { g->unseen_money = true; } else if (obj->kind == unknown_item_kind) { g->unseen_object = true; } else if (ignore_known_item_ok(obj)) { /* Item stays hidden */ } else if (!g->first_kind) { g->first_kind = obj->kind; } else { g->multiple_objects = true; break; } } /* Monsters */ if (g->m_idx > 0) { /* If the monster isn't "visible", make sure we don't list it.*/ struct monster *mon = cave_monster(cave, g->m_idx); if (!monster_is_visible(mon)) g->m_idx = 0; } /* Rare random hallucination on non-outer walls */ if (g->hallucinate && g->m_idx == 0 && g->first_kind == 0) { if (one_in_(128) && (int) g->f_idx != FEAT_PERM) g->m_idx = 1; else if (one_in_(128) && (int) g->f_idx != FEAT_PERM) /* if hallucinating, we just need first_kind to not be NULL */ g->first_kind = k_info; else g->hallucinate = false; } assert((int) g->f_idx <= FEAT_PASS_RUBBLE); if (!g->hallucinate) assert((int)g->m_idx < cave->mon_max); /* All other g fields are 'flags', mostly booleans. */ }