bool is_valid_pf(int y, int x) { feature_type *f_ptr = NULL; int feat = cave_feat[y][x]; /* Hack -- assume unvisited is permitted */ if (!(cave_info[y][x] & (CAVE_MARK))) return (TRUE); /* Get mimiced feat */ f_ptr = &f_info[f_info[feat].mimic]; /* Optionally alter known traps/doors on movement */ if (OPT(easy_alter) && (tf_has(f_ptr->flags, TF_DOOR_CLOSED) || tf_has(f_ptr->flags, TF_TRAP))) { return (TRUE); } /* Require moveable space */ if (tf_has(f_ptr->flags, TF_WALL)) return (FALSE); /* Don't move over lava, web or void */ if ((feat == FEAT_LAVA) || (feat == FEAT_WEB) || (feat == FEAT_VOID)) return (FALSE); /* Otherwise good */ return (TRUE); }
bool square_isbrokendoor(struct chunk *c, int y, int x) { int feat = c->squares[y][x].feat; return (tf_has(f_info[feat].flags, TF_DOOR_ANY) && tf_has(f_info[feat].flags, TF_PASSABLE) && !tf_has(f_info[feat].flags, TF_CLOSABLE)); }
/** * Instantiate a player trap */ static int pick_trap(int feat, int trap_level) { int trap_index = 0; feature_type *f_ptr = &f_info[feat]; struct trap_kind *kind; bool trap_is_okay = FALSE; /* Paranoia */ if (!tf_has(f_ptr->flags, TF_TRAP)) return -1; /* Try to create a trap appropriate to the level. Make certain that at * least one trap type can be made on any possible level. -LM- */ while (!trap_is_okay) { /* Pick at random. */ trap_index = randint0(z_info->trap_max); /* Get this trap */ kind = &trap_info[trap_index]; /* Ensure that this is a player trap */ if (!kind->name) continue; if (!trf_has(kind->flags, TRF_TRAP)) continue; /* Require that trap_level not be too low */ if (kind->min_depth > trap_level) continue; /* Assume legal until proven otherwise. */ trap_is_okay = TRUE; /* Floor? */ if (tf_has(f_ptr->flags, TF_FLOOR) && !trf_has(kind->flags, TRF_FLOOR)) trap_is_okay = FALSE; /* Check legality of trapdoors. */ if (trf_has(kind->flags, TRF_DOWN)) { /* No trap doors on quest levels */ if (is_quest(player->depth)) trap_is_okay = FALSE; /* No trap doors on the deepest level */ if (player->depth >= z_info->max_depth - 1) trap_is_okay = FALSE; } } /* Return our chosen trap */ return (trap_index); }
/** * Hack -- Check for a "known wall" (see below) */ static int see_wall(int dir, int y, int x) { feature_type *f_ptr; /* Get the new location */ y += ddy[dir]; x += ddx[dir]; /* Illegal grids are not known walls XXX XXX XXX */ if (!in_bounds(y, x)) return (FALSE); f_ptr = &f_info[cave_feat[y][x]]; /* Non-wall grids are not known walls */ if (!tf_has(f_ptr->flags, TF_WALL)) return (FALSE); /* Unknown walls are not known walls */ if (!cave_has(cave_info[y][x], CAVE_MARK)) return (FALSE); /* Default */ return (TRUE); }
/** * Handle falling off cliffs */ void fall_off_cliff(int levels) { int dam; msg("You fall into the darkness!"); /* New chunk */ chunk_change(1, 0, 0); /* Hit the ground... */ if (!tf_has(f_info[cave_feat[p_ptr->py][p_ptr->px]].flags, TF_FALL)) { if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); dam = damroll(2 * levels, 8); (void) inc_timed(TMD_STUN, damroll(2 * levels, 8), TRUE); (void) inc_timed(TMD_CUT, damroll(2 * levels, 8), TRUE); } else { dam = damroll(4 * levels, 8); (void) inc_timed(TMD_STUN, damroll(4 * levels, 8), TRUE); (void) inc_timed(TMD_CUT, damroll(4 * levels, 8), TRUE); } take_hit(dam, "falling off a precipice"); } /* ...or not */ else fall_off_cliff(levels + 1); }
/** * Hack -- Teleport to the target. Oangband asks for a target after * the command. */ static void do_cmd_wiz_bamf(void) { feature_type *f_ptr; /* target starts at player. */ s16b ny = 0; s16b nx = 0; /* Use the targeting function. */ if (!target_set_interactive(TARGET_LOOK, -1, -1)) return; /* grab the target coords. */ target_get(&nx, &ny); /* Test for passable terrain. */ f_ptr = &f_info[cave_feat[ny][nx]]; if (!tf_has(f_ptr->flags, TF_PASSABLE)) { msg("The square you are aiming for is impassable."); } /* The simple act of controlled teleport. */ else teleport_player_to(ny, nx, TRUE); }
/** * Light or Darken the town */ void cave_illuminate(struct chunk *c, bool daytime) { int y, x, i; /* Apply light or darkness */ for (y = 0; y < c->height; y++) for (x = 0; x < c->width; x++) { int d; bool light = FALSE; feature_type *f_ptr = &f_info[c->squares[y][x].feat]; /* Skip grids with no surrounding floors or stairs */ for (d = 0; d < 9; d++) { /* Extract adjacent (legal) location */ int yy = y + ddy_ddd[d]; int xx = x + ddx_ddd[d]; /* Paranoia */ if (!square_in_bounds_fully(c, yy, xx)) continue; /* Test */ if (square_isfloor(c, yy, xx) || square_isstairs(c, yy, xx)) light = TRUE; } if (!light) continue; /* Only interesting grids at night */ if (daytime || !tf_has(f_ptr->flags, TF_FLOOR)) { sqinfo_on(c->squares[y][x].info, SQUARE_GLOW); sqinfo_on(c->squares[y][x].info, SQUARE_MARK); } else { sqinfo_off(c->squares[y][x].info, SQUARE_GLOW); sqinfo_off(c->squares[y][x].info, SQUARE_MARK); } } /* Light shop doorways */ for (y = 0; y < c->height; y++) { for (x = 0; x < c->width; x++) { if (!square_isshop(c, y, x)) continue; for (i = 0; i < 8; i++) { int yy = y + ddy_ddd[i]; int xx = x + ddx_ddd[i]; sqinfo_on(c->squares[yy][xx].info, SQUARE_GLOW); sqinfo_on(c->squares[yy][xx].info, SQUARE_MARK); } } } /* Fully update the visuals */ player->upkeep->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw map, monster list */ player->upkeep->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST); }
/** * Count the number of walls adjacent to the given grid. * * Note -- Assumes "in_bounds_fully(y, x)" */ int next_to_walls(int y, int x) { int i, k = 0; feature_type *f_ptr; /* Count the adjacent wall grids */ for (i = 0; i < 4; i++) { /* Extract the terrain info */ f_ptr = &f_info[cave_feat[y + ddy_ddd[i]][x + ddx_ddd[i]]]; if (tf_has(f_ptr->flags, TF_WALL) && !tf_has(f_ptr->flags, TF_DOOR_ANY)) k++; } return (k); }
/** * Apply text lighting effects */ static void grid_get_attr(grid_data *g, int *a) { feature_type *f_ptr = &f_info[g->f_idx]; /* Save the high-bit, since it's used for attr inversion in GCU */ int a0 = *a & 0x80; /* Remove the high bit so we can add it back again at the end */ *a = (*a & 0x7F); /* Never play with fg colours for treasure */ if (!feat_is_treasure(g->f_idx)) { /* Tint trap detection borders */ if (g->trapborder) *a = (g->in_view ? COLOUR_L_GREEN : COLOUR_GREEN); /* Only apply lighting effects when the attr is white -- * this is to stop e.g. doors going grey when out of LOS */ if (*a == COLOUR_WHITE) { /* If it's a floor tile then we'll tint based on lighting. */ if (tf_has(f_ptr->flags, TF_TORCH)) switch (g->lighting) { case LIGHTING_TORCH: *a = COLOUR_YELLOW; break; case LIGHTING_LIT: *a = COLOUR_L_DARK; break; case LIGHTING_DARK: *a = COLOUR_L_DARK; break; default: break; } /* If it's another kind of tile, only tint when unlit. */ else if (g->lighting == LIGHTING_DARK || g->lighting == LIGHTING_LIT) *a = COLOUR_L_DARK; } else if (feat_is_magma(g->f_idx) || feat_is_quartz(g->f_idx)) { if (!g->in_view) { *a = COLOUR_L_DARK; } } } /* Hybrid or block walls -- for GCU, then for everyone else */ if (a0) { *a = a0 | *a; } else if (use_graphics == GRAPHICS_NONE && feat_is_wall(g->f_idx)) { if (OPT(hybrid_walls)) *a = *a + (MAX_COLORS * BG_DARK); else if (OPT(solid_walls)) *a = *a + (MAX_COLORS * BG_SAME); } }
/** * Determine if a cave grid is allowed to have player traps in it. */ bool square_player_trap_allowed(struct chunk *c, int y, int x) { /* * We currently forbid multiple traps in a grid under normal conditions. * If this changes, various bits of code elsewhere will have to change too. */ if (square_istrap(c, y, x)) return FALSE; /* We currently forbid traps in a grid with objects. */ if (square_object(c, y, x)) return FALSE; /* Check the feature trap flag */ return (tf_has(f_info[c->squares[y][x].feat].flags, TF_TRAP)); }
/** * Places a random trap at the given location. * * The location must be a legal, naked, floor grid. * * Note that all traps start out as "invisible" and "untyped", and then * when they are "discovered" (by detecting them or setting them off), * the trap is "instantiated" as a visible, "typed", trap. */ extern void place_trap(int y, int x) { int d, grass = 0, floor = 0; feature_type *f_ptr = &f_info[cave_feat[y][x]]; /* Paranoia */ if (!in_bounds(y, x)) return; /* Hack - handle trees */ if ((tf_has(f_ptr->flags, TF_TREE)) && (cave_o_idx[y][x] == 0) && (cave_m_idx[y][x] >= 0)) { if (cave_feat[y][x] == FEAT_TREE) cave_set_feat(y, x, FEAT_TREE_INVIS); else if (cave_feat[y][x] == FEAT_TREE2) cave_set_feat(y, x, FEAT_TREE2_INVIS); return; } /* Require empty, clean, floor grid */ if (!cave_naked_bold(y, x)) return; /* Adjacent grids vote for grass or floor */ for (d = 0; d < 8; d++) { if (cave_feat[y + ddy_ddd[d]][x + ddx_ddd[d]] == FEAT_FLOOR) floor++; else if (cave_feat[y + ddy_ddd[d]][x + ddx_ddd[d]] == FEAT_GRASS) grass++; } /* Place an invisible trap */ if (grass > floor) cave_set_feat(y, x, FEAT_GRASS_INVIS); else cave_set_feat(y, x, FEAT_INVIS); }
/** * True if the square is an open door. */ bool square_isopendoor(struct chunk *c, int y, int x) { return (tf_has(f_info[c->squares[y][x].feat].flags, TF_CLOSABLE)); }
/** * True if the feature is passable by the player. */ bool feat_is_passable(int feat) { return tf_has(f_info[feat].flags, TF_PASSABLE); }
/** * True if a monster can walk through the feature. */ bool feat_is_monster_walkable(int feat) { return tf_has(f_info[feat].flags, TF_PASSABLE); }
bool square_isinteresting(struct chunk *c, int y, int x) { int f = c->squares[y][x].feat; return tf_has(f_info[f].flags, TF_INTERESTING); }
/** * True if the square is a mineral wall with treasure (magma/quartz). */ bool feat_is_treasure(int feat) { return (tf_has(f_info[feat].flags, TF_GOLD)); }
/** * True if the square is a magma wall. */ bool feat_is_magma(int feat) { return tf_has(f_info[feat].flags, TF_MAGMA); }
/** * True if the square is a door. * * This includes open, closed, and hidden doors. */ bool square_isdoor(struct chunk *c, int y, int x) { int feat = c->squares[y][x].feat; return tf_has(f_info[feat].flags, TF_DOOR_ANY); }
/** * True if square is a down stair. */ bool square_isdownstairs(struct chunk *c, int y, int x) { int feat = c->squares[y][x].feat; return tf_has(f_info[feat].flags, TF_DOWNSTAIR); }
/** * True if the square is normal open floor. */ bool square_isfloor(struct chunk *c, int y, int x) { return tf_has(f_info[c->squares[y][x].feat].flags, TF_FLOOR); }
/** * True if the square is a quartz wall. */ bool feat_is_quartz(int feat) { return tf_has(f_info[feat].flags, TF_QUARTZ); }
/** * True if the square is a normal granite rock wall. */ bool square_isrock(struct chunk *c, int y, int x) { return (tf_has(f_info[c->squares[y][x].feat].flags, TF_GRANITE) && !tf_has(f_info[c->squares[y][x].feat].flags, TF_DOOR_ANY)); }
bool square_seemslikewall(struct chunk *c, int y, int x) { return tf_has(f_info[c->squares[y][x].feat].flags, TF_ROCK); }
/** * True if the square is a permanent wall. */ bool square_isperm(struct chunk *c, int y, int x) { return (tf_has(f_info[c->squares[y][x].feat].flags, TF_PERMANENT) && tf_has(f_info[c->squares[y][x].feat].flags, TF_ROCK)); }
/** * True is the feature is a solid wall (not rubble). */ bool feat_is_wall(int feat) { return tf_has(f_info[feat].flags, TF_WALL); }
bool square_hasgoldvein(struct chunk *c, int y, int x) { return tf_has(f_info[c->squares[y][x].feat].flags, TF_GOLD); }
/** * True if the feature is a shop entrance. */ bool feat_is_shop(int feat) { return tf_has(f_info[feat].flags, TF_SHOP); }
/** * True if the square is rubble. */ bool square_isrubble(struct chunk *c, int y, int x) { return (!tf_has(f_info[c->squares[y][x].feat].flags, TF_WALL) && tf_has(f_info[c->squares[y][x].feat].flags, TF_ROCK)); }
/** * True if any projectable can pass through the feature. */ bool feat_is_projectable(int feat) { return tf_has(f_info[feat].flags, TF_PROJECT); }
/** * True if the square is a hidden secret door. * * These squares appear as if they were granite--when detected a secret door * is replaced by a closed door. */ bool square_issecretdoor(struct chunk *c, int y, int x) { return (tf_has(f_info[c->squares[y][x].feat].flags, TF_DOOR_ANY) && tf_has(f_info[c->squares[y][x].feat].flags, TF_ROCK)); }