/*! * @brief 現在のフロアを離れるに伴って行なわれる保存処理 * / Maintain quest monsters, mark next floor_id at stairs, save current floor, and prepare to enter next floor. * @return なし */ void leave_floor(void) { cave_type *c_ptr = NULL; feature_type *f_ptr; saved_floor_type *sf_ptr; int quest_r_idx = 0; DUNGEON_IDX i; /* Preserve pets and prepare to take these to next floor */ preserve_pet(); /* Remove all mirrors without explosion */ remove_all_mirrors(FALSE); if (p_ptr->special_defense & NINJA_S_STEALTH) set_superstealth(FALSE); /* New floor is not yet prepared */ new_floor_id = 0; /* Temporary get a floor_id (for Arena) */ if (!p_ptr->floor_id && (change_floor_mode & CFM_SAVE_FLOORS) && !(change_floor_mode & CFM_NO_RETURN)) { /* Get temporal floor_id */ p_ptr->floor_id = get_new_floor_id(); } /* Search the quest monster index */ for (i = 0; i < max_q_idx; i++) { 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)) { quest_r_idx = quest[i].r_idx; } } /* Maintain quest monsters */ for (i = 1; i < m_max; i++) { monster_race *r_ptr; monster_type *m_ptr = &m_list[i]; /* Skip dead monsters */ if (!m_ptr->r_idx) continue; /* Only maintain quest monsters */ if (quest_r_idx != m_ptr->r_idx) continue; /* Extract real monster race */ r_ptr = real_r_ptr(m_ptr); /* Ignore unique monsters */ if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) continue; /* Delete non-unique quest monsters */ delete_monster_idx(i); } /* Check if there is a same item */ for (i = 0; i < INVEN_PACK; i++) { object_type *o_ptr = &inventory[i]; /* Skip dead objects */ if (!o_ptr->k_idx) continue; /* Delete old memorized location of the artifact */ if (object_is_fixed_artifact(o_ptr)) { a_info[o_ptr->name1].floor_id = 0; } } /* Extract current floor info or NULL */ sf_ptr = get_sf_ptr(p_ptr->floor_id); /* Choose random stairs */ if ((change_floor_mode & CFM_RAND_CONNECT) && p_ptr->floor_id) { locate_connected_stairs(sf_ptr); } /* Extract new dungeon level */ if (change_floor_mode & CFM_SAVE_FLOORS) { /* Extract stair position */ c_ptr = &cave[p_ptr->y][p_ptr->x]; f_ptr = &f_info[c_ptr->feat]; /* Get back to old saved floor? */ if (c_ptr->special && !have_flag(f_ptr->flags, FF_SPECIAL) && get_sf_ptr(c_ptr->special)) { /* Saved floor is exist. Use it. */ new_floor_id = c_ptr->special; } /* Mark shaft up/down */ if (have_flag(f_ptr->flags, FF_STAIRS) && have_flag(f_ptr->flags, FF_SHAFT)) { prepare_change_floor_mode(CFM_SHAFT); } } /* Climb up/down some sort of stairs */ if (change_floor_mode & (CFM_DOWN | CFM_UP)) { int move_num = 0; /* Extract level movement number */ if (change_floor_mode & CFM_DOWN) move_num = 1; else if (change_floor_mode & CFM_UP) move_num = -1; /* Shafts are deeper than normal stairs */ if (change_floor_mode & CFM_SHAFT) move_num += SGN(move_num); /* Get out from or Enter the dungeon */ if (change_floor_mode & CFM_DOWN) { if (!dun_level) move_num = d_info[dungeon_type].mindepth; } else if (change_floor_mode & CFM_UP) { if (dun_level + move_num < d_info[dungeon_type].mindepth) move_num = -dun_level; } dun_level += move_num; } /* Leaving the dungeon to town */ if (!dun_level && dungeon_type) { p_ptr->leaving_dungeon = TRUE; if (!vanilla_town && !lite_town) { p_ptr->wilderness_y = d_info[dungeon_type].dy; p_ptr->wilderness_x = d_info[dungeon_type].dx; } p_ptr->recall_dungeon = dungeon_type; dungeon_type = 0; /* Reach to the surface -- Clear all saved floors */ change_floor_mode &= ~CFM_SAVE_FLOORS; } /* Kill some old saved floors */ if (!(change_floor_mode & CFM_SAVE_FLOORS)) { /* Kill all saved floors */ for (i = 0; i < MAX_SAVED_FLOORS; i++) kill_saved_floor(&saved_floors[i]); /* Reset visit_mark count */ latest_visit_mark = 1; } else if (change_floor_mode & CFM_NO_RETURN) { /* Kill current floor */ kill_saved_floor(sf_ptr); } /* No current floor -- Left/Enter dungeon etc... */ if (!p_ptr->floor_id) { /* No longer need to save current floor */ return; } /* Mark next floor_id on the previous floor */ if (!new_floor_id) { /* Get new id */ new_floor_id = get_new_floor_id(); /* Connect from here */ if (c_ptr && !feat_uses_special(c_ptr->feat)) { c_ptr->special = new_floor_id; } } /* Fix connection -- level teleportation or trap door */ if (change_floor_mode & CFM_RAND_CONNECT) { if (change_floor_mode & CFM_UP) sf_ptr->upper_floor_id = new_floor_id; else if (change_floor_mode & CFM_DOWN) sf_ptr->lower_floor_id = new_floor_id; } /* If you can return, you need to save previous floor */ if ((change_floor_mode & CFM_SAVE_FLOORS) && !(change_floor_mode & CFM_NO_RETURN)) { /* Get out of the my way! */ get_out_monster(); /* Record the last visit turn of current floor */ sf_ptr->last_visit = turn; /* Forget the lite */ forget_lite(); /* Forget the view */ forget_view(); /* Forget the view */ clear_mon_lite(); /* Save current floor */ if (!save_floor(sf_ptr, 0)) { /* Save failed -- No return */ prepare_change_floor_mode(CFM_NO_RETURN); /* Kill current floor */ kill_saved_floor(get_sf_ptr(p_ptr->floor_id)); } } }
/*! * @brief 任意のダンジョン及び階層に飛ぶ / * Go to any level * @return なし */ static void do_cmd_wiz_jump(void) { /* Ask for level */ if (command_arg <= 0) { char ppp[80]; char tmp_val[160]; int tmp_dungeon_type; /* Prompt */ sprintf(ppp, "Jump which dungeon : "); /* Default */ sprintf(tmp_val, "%d", dungeon_type); /* Ask for a level */ if (!get_string(ppp, tmp_val, 2)) return; tmp_dungeon_type = atoi(tmp_val); if (!d_info[tmp_dungeon_type].maxdepth || (tmp_dungeon_type > max_d_idx)) tmp_dungeon_type = DUNGEON_ANGBAND; /* Prompt */ sprintf(ppp, "Jump to level (0, %d-%d): ", d_info[tmp_dungeon_type].mindepth, d_info[tmp_dungeon_type].maxdepth); /* Default */ sprintf(tmp_val, "%d", dun_level); /* Ask for a level */ if (!get_string(ppp, tmp_val, 10)) return; /* Extract request */ command_arg = atoi(tmp_val); dungeon_type = tmp_dungeon_type; } /* Paranoia */ if (command_arg < d_info[dungeon_type].mindepth) command_arg = 0; /* Paranoia */ if (command_arg > d_info[dungeon_type].maxdepth) command_arg = d_info[dungeon_type].maxdepth; /* Accept request */ msg_format("You jump to dungeon level %d.", command_arg); if (autosave_l) do_cmd_save_game(TRUE); /* Change level */ dun_level = command_arg; prepare_change_floor_mode(CFM_RAND_PLACE); if (!dun_level) dungeon_type = 0; p_ptr->inside_arena = FALSE; p_ptr->wild_mode = FALSE; leave_quest_check(); if (record_stair) do_cmd_write_nikki(NIKKI_WIZ_TELE,0,NULL); p_ptr->inside_quest = 0; p_ptr->energy_use = 0; /* Prevent energy_need from being too lower than 0 */ p_ptr->energy_need = 0; /* * Clear all saved floors * and create a first saved floor */ prepare_change_floor_mode(CFM_FIRST_FLOOR); /* Leaving */ p_ptr->leaving = TRUE; }
/*! * @brief 新フロアに移動元フロアに繋がる階段を配置する / Virtually teleport onto the stairs that is connecting between two floors. * @param sf_ptr 移動元の保存フロア構造体参照ポインタ * @return なし */ static void locate_connected_stairs(saved_floor_type *sf_ptr) { int x, y, sx = 0, sy = 0; int x_table[20]; int y_table[20]; int num = 0; int i; /* Search usable stairs */ for (y = 0; y < cur_hgt; y++) { for (x = 0; x < cur_wid; x++) { cave_type *c_ptr = &cave[y][x]; feature_type *f_ptr = &f_info[c_ptr->feat]; bool ok = FALSE; if (change_floor_mode & CFM_UP) { if (have_flag(f_ptr->flags, FF_LESS) && have_flag(f_ptr->flags, FF_STAIRS) && !have_flag(f_ptr->flags, FF_SPECIAL)) { ok = TRUE; /* Found fixed stairs? */ if (c_ptr->special && c_ptr->special == sf_ptr->upper_floor_id) { sx = x; sy = y; } } } else if (change_floor_mode & CFM_DOWN) { if (have_flag(f_ptr->flags, FF_MORE) && have_flag(f_ptr->flags, FF_STAIRS) && !have_flag(f_ptr->flags, FF_SPECIAL)) { ok = TRUE; /* Found fixed stairs */ if (c_ptr->special && c_ptr->special == sf_ptr->lower_floor_id) { sx = x; sy = y; } } } else { if (have_flag(f_ptr->flags, FF_BLDG)) { ok = TRUE; } } if (ok && (num < 20)) { x_table[num] = x; y_table[num] = y; num++; } } } if (sx) { /* Already fixed */ p_ptr->y = sy; p_ptr->x = sx; } else if (!num) { /* No stairs found! -- No return */ prepare_change_floor_mode(CFM_RAND_PLACE | CFM_NO_RETURN); /* Mega Hack -- It's not the stairs you enter. Disable it. */ if (!feat_uses_special(cave[p_ptr->y][p_ptr->x].feat)) cave[p_ptr->y][p_ptr->x].special = 0; } else { /* Choose random one */ i = randint0(num); /* Point stair location */ p_ptr->y = y_table[i]; p_ptr->x = x_table[i]; } }