1 #include "birth/game-play-initializer.h"
2 #include "dungeon/quest.h"
3 #include "floor/floor-util.h"
4 #include "game-option/birth-options.h"
5 #include "game-option/cheat-options.h"
6 #include "info-reader/fixed-map-parser.h"
7 #include "inventory/inventory-slot-types.h"
8 #include "market/arena.h"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-flags1.h"
11 #include "monster-race/race-flags7.h"
12 #include "pet/pet-util.h"
13 #include "player-base/player-class.h"
14 #include "player-base/player-race.h"
15 #include "player-info/race-info.h"
16 #include "player-info/race-types.h"
17 #include "player/digestion-processor.h"
18 #include "system/artifact-type-definition.h"
19 #include "system/baseitem-info.h"
20 #include "system/dungeon-info.h"
21 #include "system/floor-type-definition.h"
22 #include "system/item-entity.h"
23 #include "system/monster-race-info.h"
24 #include "system/player-type-definition.h"
25 #include "util/enum-range.h"
26 #include "util/string-processor.h"
27 #include "world/world.h"
32 * @brief ベースアイテム構造体の鑑定済みフラグをリセットする。
34 * 不具合対策で0からリセットする(セーブは0から)
36 static void reset_baseitem_idenditication_flags()
38 for (auto &baseitem : baseitems_info) {
39 baseitem.tried = false;
40 baseitem.aware = false;
45 * @brief プレイヤー構造体の内容を初期値で消去する(名前を除く) / Clear all the global "character" data (without name)
46 * @param player_ptr プレイヤーへの参照ポインタ
47 * @details 少し長いが、これ1つで処理が完結しているので分割は見送る
49 void player_wipe_without_name(PlayerType *player_ptr)
51 const std::string backup_name = player_ptr->name;
54 // TODO: キャラ作成からゲーム開始までに current_floor_ptr を参照しなければならない処理は今後整理して外す。
55 player_ptr->current_floor_ptr = &floor_info;
56 //! @todo std::make_shared の配列対応版は C++20 から
57 player_ptr->inventory_list = std::shared_ptr<ItemEntity[]>{ new ItemEntity[INVEN_TOTAL] };
58 for (int i = 0; i < 4; i++) {
59 strcpy(player_ptr->history[i], "");
62 auto &quest_list = QuestList::get_instance();
63 for (auto &[q_idx, quest] : quest_list) {
64 quest.status = QuestStatusType::UNTAKEN;
67 quest.type = QuestKindType::NONE;
69 quest.r_idx = MonsterRace::empty_id();
74 player_ptr->inven_cnt = 0;
75 player_ptr->equip_cnt = 0;
76 for (int i = 0; i < INVEN_TOTAL; i++) {
77 (&player_ptr->inventory_list[i])->wipe();
80 for (auto &[a_idx, artifact] : artifacts_info) {
81 artifact.is_generated = false;
84 reset_baseitem_idenditication_flags();
85 for (auto &[r_idx, r_ref] : monraces_info) {
86 if (!MonsterRace(r_ref.idx).is_valid()) {
90 r_ref.max_num = MAX_MONSTER_NUM;
91 if (r_ref.kind_flags.has(MonsterKindType::UNIQUE)) {
92 r_ref.max_num = MAX_UNIQUE_NUM;
93 } else if (r_ref.population_flags.has(MonsterPopulationType::NAZGUL)) {
94 r_ref.max_num = MAX_NAZGUL_NUM;
101 player_ptr->food = PY_FOOD_FULL - 1;
102 if (PlayerClass(player_ptr).equals(PlayerClassType::SORCERER)) {
103 player_ptr->spell_learned1 = player_ptr->spell_learned2 = 0xffffffffL;
104 player_ptr->spell_worked1 = player_ptr->spell_worked2 = 0xffffffffL;
106 player_ptr->spell_learned1 = player_ptr->spell_learned2 = 0L;
107 player_ptr->spell_worked1 = player_ptr->spell_worked2 = 0L;
110 player_ptr->spell_forgotten1 = player_ptr->spell_forgotten2 = 0L;
111 for (int i = 0; i < 64; i++) {
112 player_ptr->spell_order[i] = 99;
115 player_ptr->learned_spells = 0;
116 player_ptr->add_spells = 0;
117 player_ptr->knowledge = 0;
118 player_ptr->mutant_regenerate_mod = 100;
127 cheat_diary_output = false;
129 cheat_immortal = false;
131 w_ptr->total_winner = false;
132 player_ptr->timewalk = false;
133 player_ptr->panic_save = 0;
136 w_ptr->wizard = false;
137 player_ptr->wait_report_score = false;
138 player_ptr->pet_follow_distance = PET_FOLLOW_DIST;
139 player_ptr->pet_extra_flags = (PF_TELEPORT | PF_ATTACK_SPELL | PF_SUMMON_SPELL);
141 for (const auto &d_ref : dungeons_info) {
142 max_dlv[d_ref.idx] = 0;
145 player_ptr->visit = 1;
146 player_ptr->wild_mode = false;
148 player_ptr->max_plv = player_ptr->lev = 1;
149 player_ptr->arena_number = 0;
150 w_ptr->set_arena(true);
151 player_ptr->knows_daily_bounty = false;
152 update_gambling_monsters(player_ptr);
153 player_ptr->muta.clear();
155 for (int i = 0; i < 8; i++) {
156 player_ptr->virtues[i] = 0;
159 if (vanilla_town || ironman_downward) {
160 player_ptr->recall_dungeon = DUNGEON_ANGBAND;
162 player_ptr->recall_dungeon = DUNGEON_GALGALS;
165 std::copy_n(backup_name.begin(), backup_name.length(), player_ptr->name);
169 * @brief ダンジョン内部のクエストを初期化する / Initialize random quests and final quests
170 * @param player_ptr プレイヤーへの参照ポインタ
172 void init_dungeon_quests(PlayerType *player_ptr)
174 init_flags = INIT_ASSIGN;
175 auto *floor_ptr = player_ptr->current_floor_ptr;
176 auto &quest_list = QuestList::get_instance();
177 floor_ptr->quest_number = QuestId::RANDOM_QUEST1;
178 parse_fixed_map(player_ptr, QUEST_DEFINITION_LIST, 0, 0, 0, 0);
179 floor_ptr->quest_number = QuestId::NONE;
180 for (auto q_idx : EnumRange(QuestId::RANDOM_QUEST1, QuestId::RANDOM_QUEST10)) {
181 auto *q_ptr = &quest_list[q_idx];
182 MonsterRaceInfo *quest_r_ptr;
183 q_ptr->status = QuestStatusType::TAKEN;
184 determine_random_questor(player_ptr, q_ptr);
185 quest_r_ptr = &monraces_info[q_ptr->r_idx];
186 quest_r_ptr->misc_flags.set(MonsterMiscType::QUESTOR);
190 init_flags = INIT_ASSIGN;
191 floor_ptr->quest_number = QuestId::OBERON;
192 parse_fixed_map(player_ptr, QUEST_DEFINITION_LIST, 0, 0, 0, 0);
193 quest_list[QuestId::OBERON].status = QuestStatusType::TAKEN;
195 floor_ptr->quest_number = QuestId::SERPENT;
196 parse_fixed_map(player_ptr, QUEST_DEFINITION_LIST, 0, 0, 0, 0);
197 quest_list[QuestId::SERPENT].status = QuestStatusType::TAKEN;
198 floor_ptr->quest_number = QuestId::NONE;
202 * @brief ゲームターンを初期化する / Reset turn
203 * @param player_ptr プレイヤーへの参照ポインタ
204 * @details アンデッド系種族は開始時刻を夜からにする / Undead start just sunset
207 void init_turn(PlayerType *player_ptr)
209 if (PlayerRace(player_ptr).life() == PlayerRaceLifeType::UNDEAD) {
210 w_ptr->game_turn = (TURNS_PER_TICK * 3 * TOWN_DAWN) / 4 + 1;
211 w_ptr->game_turn_limit = TURNS_PER_TICK * TOWN_DAWN * MAX_DAYS + TURNS_PER_TICK * TOWN_DAWN * 3 / 4;
213 w_ptr->game_turn = 1;
214 w_ptr->game_turn_limit = TURNS_PER_TICK * TOWN_DAWN * (MAX_DAYS - 1) + TURNS_PER_TICK * TOWN_DAWN * 3 / 4;
217 w_ptr->dungeon_turn = 1;
218 w_ptr->dungeon_turn_limit = TURNS_PER_TICK * TOWN_DAWN * (MAX_DAYS - 1) + TURNS_PER_TICK * TOWN_DAWN * 3 / 4;