/* * Summon a creature of the specified type * * XXX XXX XXX This function is rather dangerous */ static void do_cmd_wiz_named(int r_idx, bool slp) { int py = p_ptr->py; int px = p_ptr->px; int i, x, y; cave_type *c_ptr; /* Paranoia */ /* if (!r_idx) return; */ /* Prevent illegal monsters */ if (r_idx >= max_r_idx) return; /* Try 10 times */ for (i = 0; i < 10; i++) { int d = 1; /* Pick a location */ scatter(&y, &x, py, px, d); /* paranoia */ if (!in_bounds2(y, x)) continue; /* Require empty grids */ c_ptr = area(y, x); if (!cave_empty_grid(c_ptr)) continue; /* Place it (allow groups) */ if (place_monster_aux(y, x, r_idx, slp, TRUE, FALSE, FALSE)) break; } }
/* * Summon a creature of the specified type * * This function is rather dangerous XXX XXX XXX */ static void do_cmd_wiz_named(int r_idx, bool slp) { int py = p_ptr->py; int px = p_ptr->px; int i, x, y; /* Paranoia */ if (!r_idx) return; if (r_idx >= z_info->r_max-1) return; /* Try 10 times */ for (i = 0; i < 10; i++) { int d = 1; /* Pick a location */ scatter(&y, &x, py, px, d, 0); /* Require empty grids */ if (!cave_empty_bold(y, x)) continue; /* Place it (allow groups) */ if (place_monster_aux(y, x, r_idx, slp, TRUE)) break; } }
/** * Summon a creature of the specified type * * This function is rather dangerous XXX XXX XXX */ static void do_cmd_wiz_named(int r_idx, bool slp) { monster_race *r_ptr = &r_info[r_idx]; int py = p_ptr->py; int px = p_ptr->px; int i, x, y; /* Paranoia */ if (!r_idx) return; if (r_idx >= z_info->r_max) return; /* Try 10 times */ for (i = 0; i < 10; i++) { int d = 1; /* Pick a location */ scatter(&y, &x, py, px, d, 0); /* Require grids that the monster can exist in */ if (!cave_exist_mon(r_ptr, y, x, FALSE)) continue; /* Place it (allow groups) */ if (place_monster_aux(y, x, r_idx, slp, TRUE)) break; } }
/* * Town logic flow for generation of arena -KMW- */ static void battle_gen(void) { int y, x, i; int qy = 0; int qx = 0; /* Start with solid walls */ for (y = 0; y < MAX_HGT; y++) { for (x = 0; x < MAX_WID; x++) { /* Create "solid" perma-wall */ place_solid_perm_bold(y, x); /* Illuminate and memorize the walls */ cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); } } /* Then place some floors */ for (y = qy + 1; y < qy + SCREEN_HGT - 1; y++) { for (x = qx + 1; x < qx + SCREEN_WID - 1; x++) { /* Create empty floor */ cave[y][x].feat = feat_floor; } } build_battle(); for(i=0;i<4;i++) { place_monster_aux(0, py + 8 + (i/2)*4, px - 2 + (i%2)*4, battle_mon[i], (PM_NO_KAGE | PM_NO_PET)); set_friendly(&m_list[cave[py+8+(i/2)*4][px-2+(i%2)*4].m_idx]); } for(i = 1; i < m_max; i++) { monster_type *m_ptr = &m_list[i]; if (!m_ptr->r_idx) continue; /* Hack -- Detect monster */ m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW); /* Update the monster */ update_mon(i, FALSE); } }
/*! * @brief 闘技場への入場処理 / Town logic flow for generation of arena -KMW- * @return なし */ static void arena_gen(void) { int y, x; int qy = 0; int qx = 0; /* Smallest area */ cur_hgt = SCREEN_HGT; cur_wid = SCREEN_WID; /* Start with solid walls */ for (y = 0; y < MAX_HGT; y++) { for (x = 0; x < MAX_WID; x++) { /* Create "solid" perma-wall */ place_solid_perm_bold(y, x); /* Illuminate and memorize the walls */ cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); } } /* Then place some floors */ for (y = qy + 1; y < qy + SCREEN_HGT - 1; y++) { for (x = qx + 1; x < qx + SCREEN_WID - 1; x++) { /* Create empty floor */ cave[y][x].feat = feat_floor; } } build_arena(); if(!place_monster_aux(0, p_ptr->y + 5, p_ptr->x, arena_info[p_ptr->arena_number].r_idx, (PM_NO_KAGE | PM_NO_PET))) { p_ptr->exit_bldg = TRUE; p_ptr->arena_number++; #ifdef JP msg_print("相手は欠場した。あなたの不戦勝だ。"); #else msg_print("The enemy is unable appear. You won by default."); #endif } }
/* * Town logic flow for generation of arena -KMW- */ static void arena_gen(void) { int y, x; int qy = 0; int qx = 0; /* Smallest area */ cur_hgt = SCREEN_HGT; cur_wid = SCREEN_WID; /* Start with solid walls */ for (y = 0; y < MAX_HGT; y++) { for (x = 0; x < MAX_WID; x++) { /* Create "solid" perma-wall */ place_solid_perm_bold(y, x); /* Illuminate and memorize the walls */ cave[y][x].info |= (CAVE_GLOW | CAVE_MARK | CAVE_AWARE); } } /* Then place some floors */ for (y = qy + 1; y < qy + SCREEN_HGT - 1; y++) { for (x = qx + 1; x < qx + SCREEN_WID - 1; x++) { /* Create empty floor */ cave[y][x].feat = feat_floor; } } build_arena(); place_monster_aux(0, py + 5, px, arena_info[p_ptr->arena_number].r_idx, (PM_NO_KAGE | PM_NO_PET)); }
/* * Generate a new dungeon level * * Note that "dun_body" adds about 4000 bytes of memory to the stack. */ static bool cave_gen(void) { int i, j, k, y, x, y1, x1; int extraloot,ctx; int sizelootadjustment,totalattempts; int max_vault_ok = 3; int feat1, feat2; cave_type *c_ptr; bool destroyed = FALSE; bool empty_level = FALSE; bool cavern = FALSE; bool lairlevel = FALSE; /* Lair Level */ int lotsorooms = 0; int laketype = 0; int droom_min = DUN_ROOMS_MIN; int droom_max = DUN_ROOMS_MAX; int dmod = p_ptr->depth; int dmod2 = p_ptr->depth * 3; dun_data dun_body; if (dmod < 1) dmod = 1; if (one_in_(2)) lotsorooms = randint1(9)+1; /* Prepare allocation table */ get_mon_num_prep(get_monster_hook(), NULL); /* Global data */ dun = &dun_body; droom_min += dmod; droom_max += dmod2; if (droom_min > droom_max) droom_min = droom_max - 10; if (droom_max < droom_min) droom_max = droom_min + 10; if (droom_min < 1) { droom_min = 5; droom_max = 15; } if (lotsorooms) { droom_min *= lotsorooms; droom_max *= lotsorooms; } if (droom_min > 100) droom_min = 100; if (droom_max > 300) droom_max = 300; if (one_in_(11)) lairlevel = TRUE; extraloot = 0; ctx = 0; sizelootadjustment = 0; totalattempts = 0; sizelootadjustment = ((max_hgt - min_hgt) / 22) + ((max_wid - min_wid) / 66); if (sizelootadjustment < 1) sizelootadjustment = 1; if (max_hgt - min_hgt < 23) max_vault_ok--; if (max_wid - min_wid < 34) max_vault_ok--; /* Hack - no vaults in moria mode */ if (ironman_moria) max_vault_ok = 0; /* Randomize the dungeon creation values */ dun_rooms = rand_range(droom_min, droom_max); dun_tun_rnd = rand_range(DUN_TUN_RND_MIN, DUN_TUN_RND_MAX); dun_tun_chg = rand_range(DUN_TUN_CHG_MIN, DUN_TUN_CHG_MAX); dun_tun_con = rand_range(DUN_TUN_CON_MIN, DUN_TUN_CON_MAX); dun_tun_pen = rand_range(DUN_TUN_PEN_MIN, DUN_TUN_PEN_MAX); dun_tun_jct = rand_range(DUN_TUN_JCT_MIN, DUN_TUN_JCT_MAX); /* Empty arena levels */ if (ironman_empty_levels || (empty_levels && one_in_(EMPTY_LEVEL))) { empty_level = TRUE; if (cheat_room) msg_print("Arena level."); } /* Hack -- Start with basic granite */ for (y = min_hgt; y < max_hgt; y++) { for (x = min_wid; x < max_wid; x++) { if (empty_level) cave[y][x].feat = FEAT_FLOOR; else /* Create granite wall */ cave[y][x].feat = FEAT_WALL_EXTRA; } } /* Possible "destroyed" level */ if ((p_ptr->depth > 15) && one_in_(DUN_DEST) && (small_levels)) { destroyed = TRUE; /* extra rubble around the place looks cool */ build_lake(LAKE_DESTROY); } /* Make a lake some of the time */ if (one_in_(LAKE_LEVEL) && !empty_level && !destroyed && terrain_streams) { /* Lake of Water */ if (p_ptr->depth > 52) laketype = LAKE_WATER; /* Lake of Lava */ if (p_ptr->depth > 90) laketype = LAKE_LAVA; if (laketype != 0) { if (cheat_room) msg_print("Lake on the level."); build_lake(laketype); } } if (one_in_(DUN_CAV1/(p_ptr->depth + DUN_CAV2)) && !empty_level && (laketype == 0) && !destroyed && (p_ptr->depth >= MIN_CAVERN)) { cavern = TRUE; /* make a large fractal cave in the middle of the dungeon */ if (cheat_room) msg_print("Cavern on level."); build_cavern(); } /* Hack -- No destroyed "quest" levels */ if (quest_number(p_ptr->depth)) destroyed = FALSE; /* Actual maximum number of rooms on this level */ dun->row_rooms = (max_hgt - min_hgt) / BLOCK_HGT; dun->col_rooms = (max_wid - min_hgt) / BLOCK_WID; /* Initialize the room table */ for (y = 0; y < dun->row_rooms; y++) { for (x = 0; x < dun->col_rooms; x++) { dun->room_map[y][x] = FALSE; } } /* No "crowded" rooms yet */ dun->crowded = 0; /* No rooms yet */ dun->cent_n = 0; /* Build some rooms */ for (i = 0; i < dun_rooms; i++) { /* Pick a block for the room */ y = randint0(dun->row_rooms); x = randint0(dun->col_rooms); /* Align dungeon rooms */ if (dungeon_align) { /* Slide some rooms right */ if ((x % 3) == 0) x++; /* Slide some rooms left */ if ((x % 3) == 2) x--; } /* Attempt an "unusual" room */ if (ironman_rooms || (randint0(DUN_UNUSUAL) < p_ptr->depth)) { /* Roll for room type */ k = randint0(100); /* Attempt a very unusual room */ if ((ironman_rooms && (randint0(DUN_UNUSUAL) < p_ptr->depth * 2)) || (randint0(DUN_UNUSUAL) < p_ptr->depth)) { #ifdef FORCE_V_IDX if (room_build(y, x, 8)) continue; #else /* Type 8 -- Greater vault (10%) */ if (k < 10) { if (max_vault_ok > 1) { if (room_build(y, x, 8)) continue; } else { if (cheat_room) msg_format("Refusing a greater vault. %d", max_vault_ok); } } /* Type 7 -- Lesser vault (13%) */ if (k < 23) { if (max_vault_ok > 0) { if (room_build(y, x, 7)) continue; } else { if (cheat_room) msg_print("Refusing a lesser vault."); } } /* Type 5 -- Monster nest (8%) */ if ((k < 31) && room_build(y, x, 5)) continue; /* Type 6 -- Monster pit (5%) */ if ((k < 36) && room_build(y, x, 6)) continue; /* Type 10 -- Random vault (11%) */ if (k < 47) { if (max_vault_ok > 0) { if (room_build(y, x, 10)) continue; } else { if (cheat_room) msg_print("Refusing a random vault."); } } #endif } /* Type 4 -- Large room (15%) */ if ((k < 15) && room_build(y, x, 4)) continue; /* Type 14 -- Large room (10%) */ if ((k < 25) && room_build(y, x, 14)) continue; /* Type 13 -- Large Feature room (5%) */ if ((k < 30) && room_build(y, x, 13)) continue; /* Type 3 -- Cross room (20%) */ if ((k < 50) && room_build(y, x, 3)) continue; /* Type 2 -- Overlapping (25%) */ if ((k < 75) && room_build(y, x, 2)) continue; /* Type 11 -- Parallelagram (5%) */ if ((k < 80) && room_build(y, x, 15)) continue; /* Type 11 -- Circular (5%) */ if ((k < 85) && room_build(y, x, 11)) continue; /* Type 12 -- Crypt (15%) */ if ((k < 100) && room_build(y, x, 12)) continue; } /* The deeper you are, the more cavelike the rooms are */ k = randint1(100); /* No caves when a cavern exists: they look bad */ if ((k < p_ptr->depth) && (!cavern) && (!empty_level) && (laketype == 0)) { /* Type 9 -- Fractal cave */ if (room_build(y, x, 9)) continue; } else { /* Attempt a "trivial" room */ if (room_build(y, x, 1)) continue; } } /* Make a hole in the dungeon roof sometimes at level 1 */ if ((p_ptr->depth == 1) && terrain_streams) { while (one_in_(DUN_MOS_DEN)) { place_trees(rand_range(min_wid + 1, max_wid - 2), rand_range(min_hgt + 1, max_hgt - 2)); } } /* Destroy the level if necessary */ if (destroyed) destroy_level(); /* Hack -- Add some rivers */ if (one_in_(3) && (randint1(p_ptr->depth) > 5) && terrain_streams) { /* Choose water or lava */ if (randint0(MAX_DEPTH * 2) > p_ptr->depth) { feat1 = FEAT_DEEP_WATER; feat2 = FEAT_SHAL_WATER; } else { feat1 = FEAT_DEEP_LAVA; feat2 = FEAT_SHAL_LAVA; } /* Only add river if matches lake type or if have no lake at all */ if (((laketype == 1) && (feat1 == FEAT_DEEP_LAVA)) || ((laketype == 2) && (feat1 == FEAT_DEEP_WATER)) || (laketype == 0)) { add_river(feat1, feat2); } } /* Special boundary walls -- Top */ for (x = min_wid; x < max_wid; x++) { /* Clear previous contents, add "solid" perma-wall */ cave[min_hgt][x].feat = FEAT_PERM_SOLID; } /* Special boundary walls -- Bottom */ for (x = min_wid; x < max_wid; x++) { /* Clear previous contents, add "solid" perma-wall */ cave[max_hgt - 1][x].feat = FEAT_PERM_SOLID; } /* Special boundary walls -- Left */ for (y = min_hgt; y < max_hgt; y++) { /* Clear previous contents, add "solid" perma-wall */ cave[y][min_wid].feat = FEAT_PERM_SOLID; } /* Special boundary walls -- Right */ for (y = min_hgt; y < max_hgt; y++) { /* Clear previous contents, add "solid" perma-wall */ cave[y][max_wid - 1].feat = FEAT_PERM_SOLID; } /* Hack -- Scramble the room order */ for (i = 0; i < dun->cent_n; i++) { int pick1 = randint0(dun->cent_n); int pick2 = randint0(dun->cent_n); y1 = dun->cent[pick1].y; x1 = dun->cent[pick1].x; dun->cent[pick1].y = dun->cent[pick2].y; dun->cent[pick1].x = dun->cent[pick2].x; dun->cent[pick2].y = y1; dun->cent[pick2].x = x1; } /* Start with no tunnel doors */ dun->door_n = 0; /* Hack -- connect the first room to the last room */ y = dun->cent[dun->cent_n-1].y; x = dun->cent[dun->cent_n-1].x; /* Connect all the rooms together */ for (i = 0; i < dun->cent_n; i++) { /* Reset the arrays */ dun->tunn_n = 0; dun->wall_n = 0; /* Connect the room to the previous room */ #ifdef PILLAR_TUNNELS if ((randint1(20) > p_ptr->depth) && one_in_(4)) { /* make catacomb-like tunnel */ (void)build_tunnel2(dun->cent[i].x, dun->cent[i].y, x, y, 3, 30); } else if (randint1(p_ptr->depth) > 50) #else if (randint1(p_ptr->depth) > 50) #endif /* PILLAR_TUNNELS */ { /* make cave-like tunnel */ (void)build_tunnel2(dun->cent[i].x, dun->cent[i].y, x, y, 2, 2); } else { /* make normal tunnel */ build_tunnel(dun->cent[i].y, dun->cent[i].x, y, x); } /* Turn the tunnel into corridor */ for (j = 0; j < dun->tunn_n; j++) { /* Access the grid */ y = dun->tunn[j].y; x = dun->tunn[j].x; /* Access the grid */ c_ptr = &cave[y][x]; /* Deleting a locked or jammed door is problematical */ delete_field_location(c_ptr); /* Clear previous contents (if not a lake), add a floor */ if ((c_ptr->feat < FEAT_DEEP_WATER) || (c_ptr->feat > FEAT_SHAL_LAVA)) { c_ptr->feat = FEAT_FLOOR; } } /* Apply the piercings that we found */ for (j = 0; j < dun->wall_n; j++) { /* Access the grid */ y = dun->wall[j].y; x = dun->wall[j].x; /* Access the grid */ c_ptr = &cave[y][x]; /* Deleting a locked or jammed door is problematical */ delete_field_location(c_ptr); /* Clear previous contents, add up floor */ c_ptr->feat = FEAT_FLOOR; /* Occasional doorway */ if (randint0(100) < dun_tun_pen) { /* Place a random door */ place_random_door(y, x); } } /* Remember the "previous" room */ y = dun->cent[i].y; x = dun->cent[i].x; } /* Place intersection doors */ for (i = 0; i < dun->door_n; i++) { /* Extract junction location */ y = dun->door[i].y; x = dun->door[i].x; /* Try placing doors */ try_door(y, x - 1); try_door(y, x + 1); try_door(y - 1, x); try_door(y + 1, x); } /* Hack -- Add some magma streamers */ for (i = 0; i < DUN_STR_MAG; i++) { build_streamer(FEAT_MAGMA, DUN_STR_MC); } /* Hack -- Add some quartz streamers */ for (i = 0; i < DUN_STR_QUA; i++) { build_streamer(FEAT_QUARTZ, DUN_STR_QC); } /* Place 3 or 4 down stairs near some walls */ if (!alloc_stairs(FEAT_MORE, rand_range(3, 4), 3)) return FALSE; /* Place 1 or 2 up stairs near some walls */ if (!alloc_stairs(FEAT_LESS, rand_range(3, 4), 3)) return FALSE; /* Handle the quest monster placements */ for (i = 0; i < max_quests; i++) { if ((quest[i].status == QUEST_STATUS_TAKEN) && ((quest[i].type == QUEST_TYPE_KILL_LEVEL) || (quest[i].type == QUEST_TYPE_RANDOM)) && (quest[i].level == p_ptr->depth) && !(quest[i].flags & QUEST_FLAG_PRESET)) { monster_race *r_ptr = &r_info[quest[i].r_idx]; /* Hack -- "unique" monsters must be "unique" */ if ((r_ptr->flags1 & RF1_UNIQUE) && (r_ptr->cur_num >= r_ptr->max_num)) { /* The unique is already dead */ quest[i].status = QUEST_STATUS_FINISHED; } else { bool group; /* Hard quests -> revive all monsters */ if (ironman_hard_quests) { quest[i].cur_num = 0; } for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++) { for (k = 0; k < SAFE_MAX_ATTEMPTS; k++) { /* Find an empty grid */ while (TRUE) { y = rand_range(min_hgt + 1, max_hgt - 2); x = rand_range(min_wid + 1, max_wid - 2); /* Access the grid */ c_ptr = &cave[y][x]; if (!cave_naked_grid(c_ptr)) continue; if (distance(y, x, p_ptr->py, p_ptr->px) < 10) continue; else break; } if (r_ptr->flags1 & RF1_FRIENDS) group = FALSE; else group = TRUE; /* Try to place the monster */ if (place_monster_aux(y, x, quest[i].r_idx, FALSE, group, FALSE, FALSE)) { /* Success */ break; } else { /* Failure - Try again */ continue; } } } } } } /* Basic "amount" */ k = (p_ptr->depth / 3); if (k > 10) k = 10; if (k < 2) k = 2; /* Pick a base number of monsters */ i = MIN_M_ALLOC_LEVEL; if (!(lairlevel)) { /* To make small levels a bit more playable */ if (max_hgt < MAX_HGT || max_wid < MAX_WID) { int small_tester = i; i = (i * max_hgt) / MAX_HGT; i = (i * max_wid) / MAX_WID; i += 1; if (i > small_tester) i = small_tester; else if (cheat_hear) { msg_format("Reduced monsters base from %d to %d", small_tester, i); } } i += randint1(8); /* Put some monsters in the dungeon */ for (i = i + k; i > 0; i--) { (void)alloc_monster(0, TRUE); } } if (lairlevel) { int r_idx = get_mon_num(p_ptr->depth + randint1(12) + 3), attempts = (randint1(200)+100); monster_race *r_ptr = &r_info[r_idx]; attempts += ((10 + sizelootadjustment) * r_ptr->level); if (cheat_room) msg_print("Smile! Then Die!"); totalattempts = 0; while (attempts && (totalattempts <= 10000)) { /* attempts--;*/ ctx = 0; y = rand_range(min_hgt + 1, max_hgt - 2); x = rand_range(min_wid + 1, max_wid - 2); /* Access the grid */ c_ptr = &cave[y][x]; if (!cave_naked_grid(c_ptr)) ctx = 1; if (distance(y, x, p_ptr->py, p_ptr->px) < 10) ctx = 1; /* Try to place the monster */ if (ctx == 0) { if (place_monster_aux(y, x, r_idx, FALSE, (one_in_(10)) ? TRUE : FALSE, FALSE, FALSE)) { extraloot++; attempts--; } } totalattempts++; } } /* Place some traps in the dungeon */ alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(k)); /* Put some rubble in corridors */ alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k)); /* Put some objects in rooms */ alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3)); if (lairlevel) { alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(k*30)); /* Hack - Make loot desirable! */ /* AKA - Sucker in the PC */ dun_theme.treasure = qreward_theme[p_ptr->pclass].treasure; dun_theme.combat = qreward_theme[p_ptr->pclass].combat; dun_theme.magic = qreward_theme[p_ptr->pclass].magic; dun_theme.tools = qreward_theme[p_ptr->pclass].tools; /* Put loot! in the dungeon */ alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, extraloot); alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, extraloot); } /* Hack - Reset the object theme */ dun_theme.treasure = 20; dun_theme.combat = 20; dun_theme.magic = 20; dun_theme.tools = 20; /* Put some objects/gold in the dungeon */ alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3)); alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3)); /* Put some invisible walls in the dungeon for nightmare mode */ if (ironman_nightmare) { alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_INVIS, randnor(DUN_AMT_INVIS, 3)); } if (empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > p_ptr->depth))) { /* Lite the cave */ for (y = min_hgt; y < max_hgt; y++) { for (x = min_hgt; x < max_wid; x++) { cave[y][x].info |= (CAVE_GLOW); } } } /* Determine the character location */ if (!new_player_spot()) return FALSE; return TRUE; }
extern void get_chamber_monsters(int y1, int x1, int y2, int x2) { bool dummy; int i, y, x; s16b monsters_left, depth; char symbol; /* Description of monsters in room */ char *name; /* Get a legal depth. */ depth = p_ptr->danger + randint0(11) - 5; if (depth > 60) depth = 60; if (depth < 5) depth = 5; /* Choose a monster type, using that depth. */ symbol = mon_symbol_at_depth[depth / 5 - 1][randint0(13)]; /* Allow (slightly) tougher monsters. */ depth = p_ptr->danger + (p_ptr->danger < 60 ? p_ptr->danger / 12 : 5); /* Set monster generation restrictions. Describe the monsters. */ name = mon_restrict(symbol, (byte) depth, &dummy, TRUE); /* A default description probably means trouble, so stop. */ if (streq(name, "misc") || !name[0]) return; /* Build the monster probability table. */ if (!get_mon_num(depth)) return; /* No normal monsters. */ generate_mark(y1, x1, y2, x2, CAVE_TEMP); /* Usually, we want 35 monsters. */ monsters_left = 35; /* Fewer monsters near the surface. */ if (p_ptr->danger < 45) monsters_left = 5 + 2 * p_ptr->danger / 3; /* More monsters of kinds that tend to be weak. */ if (strstr("abciBCFKRS", d_char_req)) monsters_left += 15; /* Place the monsters. */ for (i = 0; i < 300; i++) { /* Check for early completion. */ if (!monsters_left) break; /* Pick a random in-room square. */ y = y1 + randint0(1 + ABS(y2 - y1)); x = x1 + randint0(1 + ABS(x2 - x1)); /* Require a floor square with no monster in it already. */ if (!cave_naked_bold(y, x)) continue; /* Place a single monster. Sleeping 2/3rds of the time. */ place_monster_aux(y, x, get_mon_num_quick(depth), (randint0(3) != 0), FALSE); /* One less monster to place. */ monsters_left--; } /* Remove our restrictions. */ (void) mon_restrict('\0', (byte) depth, &dummy, FALSE); /* Describe */ if (OPT(cheat_room)) { /* Room type */ msg("Room of chambers (%s)", name); } }
/** * To avoid rebuilding the monster list too often (which can quickly * get expensive), we handle monsters of a specified race separately. */ extern void get_vault_monsters(char racial_symbol[], byte vault_type, const char *data, int y1, int y2, int x1, int x2) { int i, y, x, temp; const char *t; for (i = 0; racial_symbol[i] != '\0'; i++) { /* Require correct race, allow uniques. */ allow_unique = TRUE; sprintf(d_char_req, "%c", racial_symbol[i]); d_attr_req[0] = 0; d_attr_req[1] = 0; d_attr_req[2] = 0; d_attr_req[3] = 0; racial_flag_mask = 0; rsf_wipe(breath_flag_mask); /* Determine level of monster */ if (vault_type == 0) temp = p_ptr->danger + 3; else if (vault_type == 7) temp = p_ptr->danger; else if (vault_type == 8) temp = p_ptr->danger + 3; else if (vault_type == 9) temp = p_ptr->danger + 6; else if (vault_type == 12) temp = p_ptr->danger + 3; else if (vault_type == 13) temp = p_ptr->danger + 6; else if ((vault_type > 13) && (vault_type % 2)) temp = p_ptr->danger + 4; else temp = p_ptr->danger; /* Apply our restrictions */ get_mon_num_hook = mon_select; /* Prepare allocation table */ get_mon_num_prep(); /* Build the monster probability table. */ if (!get_mon_num(temp)) continue; /* Place the monsters */ for (t = data, y = y1; y <= y2; y++) { for (x = x1; x <= x2; x++, t++) { if (*t == racial_symbol[i]) { /* Place a monster */ place_monster_aux(y, x, get_mon_num_quick(temp), FALSE, FALSE); } } } } /* Clear any current monster restrictions. */ if (get_mon_num_hook) { get_mon_num_hook = NULL; get_mon_num_prep(); } }
/** * Handle player hitting a real trap. Rewritten in Oangband to allow a * greater variety of traps, with effects controlled by dungeon level. * To allow a trap to choose one of a variety of effects consistantly, * the quick RNG is often used, and xy coordinates input as a seed value. */ extern void hit_trap(int y, int x) { int i, j, k, num; int dam = 0; int nastyness, selection; feature_type *f_ptr = &f_info[cave_feat[y][x]]; cptr name = f_ptr->name; /* Use the "simple" RNG to insure that traps are consistant. */ Rand_quick = TRUE; /* Use the coordinates of the trap to seed the RNG. */ Rand_value = y * x; /* Disturb the player */ disturb(0, 0); /* Analyze XXX XXX XXX */ switch (cave_feat[y][x]) { /* trap door. */ case FEAT_TRAP_HEAD + 0x00: { Rand_quick = FALSE; /* Paranoia -NRM- */ if (((stage_map[p_ptr->stage][STAGE_TYPE] == CAVE) || (stage_map[p_ptr->stage][STAGE_TYPE] == VALLEY)) && (!stage_map[p_ptr->stage][DOWN])) { cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); msg_print("The trap fails!"); break; } msg_print("You fall through a trap door!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently down to the next level."); } else { dam = damroll(2, 8); take_hit(dam, name); } /* Remember where we came from */ p_ptr->last_stage = p_ptr->stage; if (!stage_map[p_ptr->stage][DOWN]) { /* Set the ways forward and back */ stage_map[255][UP] = p_ptr->stage; stage_map[p_ptr->stage][DOWN] = 255; stage_map[255][DEPTH] = p_ptr->depth + 1; } /* New stage */ p_ptr->stage = stage_map[p_ptr->stage][DOWN]; /* New depth */ p_ptr->depth = stage_map[p_ptr->stage][DEPTH]; /* Leaving */ p_ptr->leaving = TRUE; Rand_quick = TRUE; break; } /* pits. */ case FEAT_TRAP_HEAD + 0x01: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); if (randint1(20) == 1) nastyness += 20; else if (randint1(5) == 1) nastyness += 10; /* Player is now in pit. */ monster_swap(p_ptr->py, p_ptr->px, y, x); /* Center on player. */ y = p_ptr->py; x = p_ptr->px; /* pit of daggers. */ if ((nastyness > 80) && (randint1(3) != 3)) { msg_print("You fall into a pit of daggers!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the floor of the pit."); msg_print("You carefully avoid setting off the daggers."); } else { /* a trap of morgul. */ if (randint1(6) == 1) { Rand_quick = FALSE; msg_print ("A single coldly gleaming dagger pierces you deeply!"); msg_print ("You feel a deadly chill slowly withering your soul."); /* activate the Black Breath. */ p_ptr->black_breath = TRUE; /* lots of damage. */ dam = damroll(20, 15); /* undead may be attracted. */ if (randint1(2) == 1) { msg_print ("Undead suddenly appear and call you to them!"); k = randint1(3) + 2; for (i = 0; i < k; i++) { summon_specific(y, x, FALSE, p_ptr->depth, SUMMON_UNDEAD); } } /* morgul-traps are one-time only. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); Rand_quick = TRUE; } else { Rand_quick = FALSE; /* activate the ordinary daggers. */ msg_print("Daggers pierce you everywhere!"); k = randint1(10) + 5; for (i = 0; i < k; i++) { dam += damroll(3, 4); } Rand_quick = TRUE; } /* cut the player. */ (void) inc_timed(TMD_CUT, randint1(dam), TRUE); /* Take the damage. */ take_hit(dam, name); } } /* poisoned spiked pit. */ else if ((nastyness > 55) && (randint1(3) != 3)) { msg_print("You fall into a spiked pit!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the floor of the pit."); msg_print("You carefully avoid touching the spikes."); } else { Rand_quick = FALSE; /* Base damage */ dam = damroll(2, 6); /* Extra spike damage */ if (randint0(100) < 85) { bool was_poisoned; msg_print("You are impaled on poisonous spikes!"); dam = dam * (randint1(6) + 3); (void) inc_timed(TMD_CUT, randint1(dam), TRUE); was_poisoned = pois_hit(dam); if (!was_poisoned) msg_print("The poison does not affect you!"); } /* Take the damage */ take_hit(dam, name); Rand_quick = TRUE; } } /* spiked pit. */ else if ((nastyness > 30) && (randint1(3) != 3)) { msg_print("You fall into a spiked pit!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the floor of the pit."); msg_print("You carefully avoid touching the spikes."); } else { Rand_quick = FALSE; /* Base damage */ dam = damroll(2, 6); /* Extra spike damage */ if (randint0(100) < 85) { msg_print("You are impaled!"); dam = dam * (2 + randint1(4)); (void) inc_timed(TMD_CUT, randint1(dam), TRUE); } /* Take the damage */ take_hit(dam, name); Rand_quick = TRUE; } } /* ordinary pit in all other cases. */ else { msg_print("You fall into a pit!"); if (p_ptr->state.ffall) { notice_obj(OF_FEATHER, 0); msg_print("You float gently to the bottom of the pit."); } else { Rand_quick = FALSE; dam = damroll(2, 6); take_hit(dam, name); Rand_quick = TRUE; } } break; } /* stat-reducing dart traps. */ case FEAT_TRAP_HEAD + 0x02: { /* decide if the dart hits. */ if (check_trap_hit(50 + p_ptr->depth)) { /* select a stat to drain. */ selection = randint0(6); Rand_quick = FALSE; msg_print("A small dart hits you!"); dam = damroll(1, 4); take_hit(dam, name); /* Determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); /* decide how much to drain the stat by. */ if ((nastyness > 50) && (randint1(3) == 1)) { num = randint1(4); } else num = 1; /* drain the stat. */ for (i = 0; i < num; i++) { (void) do_dec_stat(selection); } Rand_quick = TRUE; } else { msg_print("A small dart barely misses you."); } break; } /* discolored spots. */ case FEAT_TRAP_HEAD + 0x03: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); if (randint1(5) == 1) nastyness += 10; /* pick a elemental attack type. */ selection = randint1(4); /* electicity trap. */ if (selection == 1) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("You are struck by lightning!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You get zapped!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; elec_dam(dam, "an electricity trap"); Rand_quick = TRUE; } /* frost trap. */ if (selection == 2) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("You are lost within a blizzard!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You are coated in frost!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; cold_dam(dam, "a frost trap"); Rand_quick = TRUE; } /* fire trap. */ if (selection == 3) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("You are enveloped in a column of fire!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You are surrounded by flames!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; fire_dam(dam, "a fire trap"); Rand_quick = TRUE; } /* acid trap. */ if (selection == 4) { if ((nastyness >= 50) && (randint1(2) == 1)) { Rand_quick = FALSE; msg_print("A cauldron of acid is tipped over your head!"); dam = damroll(6, 30); Rand_quick = TRUE; } else { Rand_quick = FALSE; msg_print("You are splashed with acid!"); dam = damroll(4, 8); Rand_quick = TRUE; } Rand_quick = FALSE; acid_dam(dam, "an acid trap"); Rand_quick = TRUE; } break; } /* gas traps. */ case FEAT_TRAP_HEAD + 0x04: { selection = randint1(4); /* blinding trap. */ if (selection == 1) { msg_print("You are surrounded by a black gas!"); if (!p_ptr->state.no_blind) { Rand_quick = FALSE; (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE); Rand_quick = TRUE; } } else notice_obj(OF_SEEING, 0); /* confusing trap. */ if (selection == 2) { msg_print ("You are surrounded by a gas of scintillating colors!"); if (!p_resist_good(P_RES_CONFU)) { Rand_quick = FALSE; (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE); Rand_quick = TRUE; } else notice_other(IF_RES_CONFU, 0); } /* poisoning trap. */ if (selection == 3) { msg_print("You are surrounded by a pungent green gas!"); Rand_quick = FALSE; pois_hit(25); Rand_quick = TRUE; } /* sleeping trap. */ if (selection == 4) { msg_print("You are surrounded by a strange white mist!"); if (!p_ptr->state.free_act) { (void) inc_timed(TMD_PARALYZED, randint0(10) + 5, TRUE); } else notice_obj(OF_FREE_ACT, 0); } break; } /* summoning traps. */ case FEAT_TRAP_HEAD + 0x05: { sound(MSG_SUM_MONSTER); /* sometimes summon thieves. */ if ((p_ptr->depth > 8) && (randint1(5) == 1)) { msg_print("You have aroused a den of thieves!"); Rand_quick = FALSE; num = 2 + randint1(3); for (i = 0; i < num; i++) { (void) summon_specific(y, x, FALSE, p_ptr->depth, SUMMON_THIEF); } Rand_quick = TRUE; } /* sometimes summon a nasty unique. */ else if (randint1(8) == 1) { msg_print("You are enveloped in a cloud of smoke!"); Rand_quick = FALSE; (void) summon_specific(y, x, FALSE, p_ptr->depth + 5, SUMMON_UNIQUE); Rand_quick = TRUE; } /* otherwise, the ordinary summon monsters. */ else { msg_print("You are enveloped in a cloud of smoke!"); Rand_quick = FALSE; num = 2 + randint1(3); for (i = 0; i < num; i++) { (void) summon_specific(y, x, FALSE, p_ptr->depth, 0); } Rand_quick = TRUE; } /* these are all one-time traps. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); break; } /* dungeon alteration traps. */ case FEAT_TRAP_HEAD + 0x06: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint1(p_ptr->depth); if (randint1(5) == 1) nastyness += 10; /* make room for alterations. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); /* Everything truely random from here on. */ Rand_quick = FALSE; /* dungeon destruction trap. */ if ((nastyness > 60) && (randint1(12) == 1)) { msg_print ("A ear-splitting howl shatters your mind as the dungeon is smashed by hammer blows!"); (void) destroy_level(FALSE); /* the player is hard-hit. */ (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE); (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE); (void) inc_timed(TMD_STUN, randint1(50) + 50, TRUE); dam = damroll(15, 15); take_hit(dam, name); } /* earthquake trap. */ else if ((nastyness > 20) && (randint1(4) == 1)) { msg_print("A tremor shakes the earth around you"); earthquake(y, x, 10, FALSE); } /* falling rock trap. */ else if ((nastyness > 4) && (randint1(2) == 1)) { msg_print("A rock falls on your head."); dam = damroll(2, 10); take_hit(dam, name); (void) inc_timed(TMD_STUN, randint1(10) + 10, TRUE); } /* a few pebbles. */ else { msg_print("A bunch of pebbles rain down on you."); dam = damroll(1, 8); take_hit(dam, name); } Rand_quick = TRUE; break; } /* various char and equipment-alteration traps, lumped together to * avoid any one effect being too common (some of them can be rather * nasty). */ case FEAT_TRAP_HEAD + 0x07: { /* determine how dangerous the trap is allowed to be. */ nastyness = randint0(100); /* these are all one-time traps. */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); /* Everything truely random from here on. */ Rand_quick = FALSE; /* trap of drain wands. */ if (nastyness < 15) { /* Hold the object information. */ object_type *o_ptr; /* Find an item */ for (i = 0; i < 20; i++) { /* Pick an item */ i = randint0(INVEN_PACK - p_ptr->pack_size_reduce); /* Obtain the item */ o_ptr = &p_ptr->inventory[i]; /* use "num" to decide if a item can be uncharged. By * default, assume it can't. */ num = 0; /* Skip non-objects */ if (!o_ptr->k_idx) continue; /* Drain charged wands/staffs/rods */ if ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_ROD)) { /* case of charged wands/staffs. */ if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) && (o_ptr->pval)) num = 1; /* case of charged rods. */ if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout < randcalc(o_ptr->time, 0, MINIMISE))) num = 1; if (num == 1) { /* Message */ msg_print("Energy drains from your pack!"); /* Uncharge */ if ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) o_ptr->pval = 0; if (o_ptr->tval == TV_ROD) o_ptr->timeout = randcalc(o_ptr->time, 0, RANDOMISE) * o_ptr->number * 2; /* Combine / Reorder the pack */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* not more than one inventory slot effected. */ break; } else continue; } } } /* trap of forgetting. */ else if (nastyness < 35) { if (check_save(100)) { msg_print("You hang on to your memories!"); } else if (lose_all_info()) { msg_print("Your memories fade away."); } } /* trap of alter reality. */ else if (nastyness < 50) { if (OPT(adult_ironman)) msg_print("Nothing happens."); else { msg_print("The world changes!"); /* Leaving */ p_ptr->leaving = TRUE; } } /* trap of remold player. */ else if (nastyness < 75) { int max1, cur1, max2, cur2, ii, jj; msg_print("You feel yourself being twisted by wild magic!"); if (check_save(100)) { msg_print("You resist the effects!"); } else { msg_print("Your body starts to scramble..."); /* Pick a pair of stats */ ii = randint0(6); for (jj = ii; jj == ii; jj = randint0(6)) /* loop */ ; max1 = p_ptr->stat_max[ii]; cur1 = p_ptr->stat_cur[ii]; max2 = p_ptr->stat_max[jj]; cur2 = p_ptr->stat_cur[jj]; p_ptr->stat_max[ii] = max2; p_ptr->stat_cur[ii] = cur2; p_ptr->stat_max[jj] = max1; p_ptr->stat_cur[jj] = cur1; p_ptr->update |= (PU_BONUS); } } /* time ball trap. */ else if (nastyness < 90) { msg_print("You feel time itself assault you!"); /* Target the player with a radius 0 ball attack. */ fire_meteor(0, GF_TIME, p_ptr->py, p_ptr->px, 75, 0, TRUE); } /* trap of bugs gone berserk. */ else { /* explain what the dickens is going on. */ msg_print("GRUESOME Gnawing Bugs leap out at you!"); if (!p_resist_good(P_RES_CONFU)) { (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE); } else notice_other(IF_RES_CONFU, 0); if (!p_resist_good(P_RES_CHAOS)) { (void) inc_timed(TMD_IMAGE, randint1(40), TRUE); } else notice_other(IF_RES_CHAOS, 0); /* XXX (hard coded) summon 3-6 bugs. */ k = randint1(4) + 2; for (i = 0; i < k; ++i) { /* Look for a location */ for (j = 0; j < 20; ++j) { /* Pick a (scattered) distance. */ int d = (j / 10) + randint1(3); /* Pick a location */ scatter(&y, &x, y, x, d, 0); /* Require passable terrain */ if (!cave_passable_bold(y, x)) continue; /* Hack -- no summon on glyph of warding */ if (cave_feat[y][x] == FEAT_RUNE_PROTECT) continue; /* Okay */ break; } /* Attempt to place the awake bug */ place_monster_aux(y, x, 453, FALSE, TRUE); } /* herald the arrival of bugs. */ msg_print("AAAAAAAHHHH! THEY'RE EVERYWHERE!"); } Rand_quick = TRUE; break; } /* teleport trap */ case FEAT_TRAP_HEAD + 0x08: { if (stage_map[p_ptr->stage][STAGE_TYPE] >= CAVE) msg_print("You teleport across the dungeon."); else msg_print("You teleport across the wilderness."); Rand_quick = FALSE; teleport_player(250, FALSE); Rand_quick = TRUE; break; } /* murder holes. */ case FEAT_TRAP_HEAD + 0x09: { /* hold the object info. */ object_type *o_ptr; object_type object_type_body; /* hold the missile type and name. */ int sval = 0; int tval = 0; cptr missile_name = ""; /* Determine the missile type and base damage. */ if (randint1(3) == 1) { if (p_ptr->depth < 40) { missile_name = "shot"; dam = damroll(2, 3); tval = TV_SHOT; sval = SV_AMMO_NORMAL; } else { missile_name = "seeker shot"; dam = damroll(3, 7); tval = TV_SHOT; sval = SV_AMMO_HEAVY; } } else if (randint1(2) == 1) { if (p_ptr->depth < 55) { missile_name = "arrow"; dam = damroll(2, 4); tval = TV_ARROW; sval = SV_AMMO_NORMAL; } else { missile_name = "seeker arrow"; dam = damroll(3, 9); tval = TV_ARROW; sval = SV_AMMO_HEAVY; } } else { if (p_ptr->depth < 65) { missile_name = "bolt"; dam = damroll(2, 5); tval = TV_BOLT; sval = SV_AMMO_NORMAL; } else { missile_name = "seeker bolt"; dam = damroll(3, 11); tval = TV_BOLT; sval = SV_AMMO_HEAVY; } } /* determine if the missile hits. */ if (check_trap_hit(75 + p_ptr->depth)) { msg_format("A %s hits you from above.", missile_name); Rand_quick = FALSE; /* critical hits. */ if (randint1(2) == 1) { msg_print("It was well-aimed!"); dam *= 1 + randint1(2); } if (randint1(2) == 1) { msg_print("It gouges you!"); dam = 3 * dam / 2; /* cut the player. */ (void) inc_timed(TMD_CUT, randint1(dam), TRUE); } Rand_quick = TRUE; take_hit(dam, name); } /* Explain what just happened. */ else msg_format("A %s wizzes by your head.", missile_name); /* these will eventually run out of ammo. */ Rand_quick = FALSE; if (randint0(8) == 0) { cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_FLOOR); } Rand_quick = TRUE; /* Get local object */ o_ptr = &object_type_body; /* Make a missile, identify it, and drop it near the player. */ object_prep(o_ptr, lookup_kind(tval, sval), MINIMISE); object_aware(o_ptr); object_known(o_ptr); drop_near(o_ptr, -1, y, x, TRUE); break; } /* falling tree branch */ case FEAT_TRAP_HEAD + 0x0A: { /* determine if the missile hits. */ if (check_trap_hit(75 + p_ptr->depth)) { /* Take damage */ dam = damroll(3, 5); msg_print("A branch hits you from above."); Rand_quick = FALSE; /* critical hits. */ if (randint1(2) == 1) { msg_print("It was heavy!"); dam = 3 * dam / 2; /* stun the player. */ (void) inc_timed(TMD_STUN, randint1(dam), TRUE); } Rand_quick = TRUE; take_hit(dam, name); } /* Explain what just happened. */ else msg_print("A falling branch just misses you."); /* No more */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_TREE); break; } /* falling tree branch */ case FEAT_TRAP_HEAD + 0x0B: { /* determine if the missile hits. */ if (check_trap_hit(75 + p_ptr->depth)) { /* Take damage */ dam = damroll(3, 5); msg_print("A branch hits you from above."); Rand_quick = FALSE; /* critical hits. */ if (randint1(2) == 1) { msg_print("It was heavy!"); dam = 3 * dam / 2; /* stun the player. */ (void) inc_timed(TMD_STUN, randint1(dam), TRUE); } Rand_quick = TRUE; take_hit(dam, name); } /* Explain what just happened. */ else msg_print("A falling branch just misses you."); /* No more */ cave_info[y][x] &= ~(CAVE_MARK); cave_set_feat(y, x, FEAT_TREE2); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0C: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0D: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0E: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } /* undefined trap. */ case FEAT_TRAP_HEAD + 0x0F: { msg_print("A dagger is thrown at you from the shadows!"); dam = damroll(3, 4); take_hit(dam, name); break; } } /* Revert to usage of the complex RNG. */ Rand_quick = FALSE; }
/* Place quest monsters */ bool place_quest_monsters(void) { int i; /* Handle the quest monster placements */ for (i = 0; i < max_quests; i++) { monster_race *r_ptr; u32b mode; int j; if (quest[i].status != QUEST_STATUS_TAKEN || (quest[i].type != QUEST_TYPE_KILL_LEVEL && quest[i].type != QUEST_TYPE_RANDOM) || quest[i].level != dun_level || dungeon_type != quest[i].dungeon || (quest[i].flags & QUEST_FLAG_PRESET)) { /* Ignore it */ continue; } r_ptr = &r_info[quest[i].r_idx]; /* Hack -- "unique" monsters must be "unique" */ if ((r_ptr->flags1 & RF1_UNIQUE) && (r_ptr->cur_num >= r_ptr->max_num)) continue; mode = (PM_NO_KAGE | PM_NO_PET); if (!(r_ptr->flags1 & RF1_FRIENDS)) mode |= PM_ALLOW_GROUP; for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++) { int k; for (k = 0; k < SAFE_MAX_ATTEMPTS; k++) { int x, y; int l; /* Find an empty grid */ for (l = SAFE_MAX_ATTEMPTS; l > 0; l--) { cave_type *c_ptr; feature_type *f_ptr; y = randint0(cur_hgt); x = randint0(cur_wid); c_ptr = &cave[y][x]; f_ptr = &f_info[c_ptr->feat]; if (!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) continue; if (!monster_can_enter(y, x, r_ptr, 0)) continue; if (distance(y, x, py, px) < 10) continue; if (c_ptr->info & CAVE_ICKY) continue; else break; } /* Failed to place */ if (!l) return FALSE; /* Try to place the monster */ if (place_monster_aux(0, y, x, quest[i].r_idx, mode)) { /* Success */ break; } else { /* Failure - Try again */ continue; } } /* Failed to place */ if (k == SAFE_MAX_ATTEMPTS) return FALSE; } } return TRUE; }
// Select a monster from a list and place it in the dungeon. MakeMonsterDialog::MakeMonsterDialog(void) { int i; QPointer<QVBoxLayout> vlay = new QVBoxLayout; mon_choice = new QComboBox; int y, x; QPointer<QLabel> mon_label = new QLabel(QString("<b><big>Please select a monster:</big></b>")); mon_label->setAlignment(Qt::AlignCenter); vlay->addWidget(mon_label); vlay->addStretch(); connect(mon_choice, SIGNAL(currentIndexChanged(int)), this, SLOT(update_mon_choice(int))); QPointer<QPushButton> close_button = new QPushButton(tr("&Close")); connect(close_button, SIGNAL(clicked()), this, SLOT(close())); int count = 0; mon_num = 0; for (i = 1; i < z_info->r_max; i++) { monster_race *r_ptr = &r_info[i]; /* Skip "empty" items */ if (r_ptr->r_name_full.isEmpty()) continue; // Skip player_ghost templates if (r_ptr->flags2 & (RF2_PLAYER_GHOST)) continue; mon_choice->addItem(QString("%1") .arg(i)); mon_choice->setItemText(count++, get_mon_display_name(i)); } vlay->addWidget(mon_choice); vlay->addStretch(); vlay->addWidget(close_button); setLayout(vlay); setWindowTitle(tr("Make Monster")); this->exec(); // find the monster count = 0; for (i = 1; i < z_info->r_max; i++) { monster_race *r_ptr = &r_info[i]; /* Skip "empty" items */ if (r_ptr->r_name_full.isEmpty()) continue; // Skip player_ghost templates if (r_ptr->flags2 & (RF2_PLAYER_GHOST)) continue; // Found the match if (count == mon_num) break; count++; } /* Try 10 times */ for (int k = 0; k < 10; k++) { int d = 2; /* Pick a location */ scatter(&y, &x, p_ptr->py, p_ptr->px, d, 0); /* Require empty grids */ if (!cave_empty_bold(y, x)) continue; /* Place it (allow groups) */ if (place_monster_aux(y, x, i, (MPLACE_GROUP | MPLACE_OVERRIDE | MPLACE_SLEEP))) break; } }