OSDN Git Service

Merge pull request #1585 from habu1010/feature/defeat-c-make-inventory-list
[hengbandforosx/hengbandosx.git] / src / birth / game-play-initializer.cpp
1 #include "birth/game-play-initializer.h"
2 #include "dungeon/dungeon.h"
3 #include "dungeon/quest.h"
4 #include "floor/floor-util.h"
5 #include "game-option/birth-options.h"
6 #include "game-option/cheat-options.h"
7 #include "info-reader/fixed-map-parser.h"
8 #include "inventory/inventory-slot-types.h"
9 #include "market/arena.h"
10 #include "monster-race/monster-race.h"
11 #include "monster-race/race-flags1.h"
12 #include "monster-race/race-flags7.h"
13 #include "object/object-kind.h"
14 #include "pet/pet-util.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/floor-type-definition.h"
20 #include "system/monster-race-definition.h"
21 #include "system/player-type-definition.h"
22 #include "world/world.h"
23
24 /*!
25  * @brief ベースアイテム構造体の鑑定済みフラグをリセットする。
26  * @details
27  * 不具合対策で0からリセットする(セーブは0から)
28  */
29 static void k_info_reset(void)
30 {
31     for (auto &k_ref : k_info) {
32         k_ref.tried = false;
33         k_ref.aware = false;
34     }
35 }
36
37 /*!
38  * @brief プレイヤー構造体の内容を初期値で消去する(名前を除く) / Clear all the global "character" data (without name)
39  * @param player_ptr プレイヤーへの参照ポインタ
40  * @details 少し長いが、これ1つで処理が完結しているので分割は見送る
41  */
42 void player_wipe_without_name(player_type *player_ptr)
43 {
44     player_type tmp;
45
46 #ifdef SET_UID
47     int uid = player_ptr->player_uid;
48 #endif
49     COPY(&tmp, player_ptr, player_type);
50     if (player_ptr->last_message)
51         string_free(player_ptr->last_message);
52
53     (void)WIPE(player_ptr, player_type);
54
55     // TODO: キャラ作成からゲーム開始までに  current_floor_ptr を参照しなければならない処理は今後整理して外す。
56     player_ptr->current_floor_ptr = &floor_info;
57     //! @todo std::make_shared の配列対応版は C++20 から
58     player_ptr->inventory_list = std::shared_ptr<object_type[]>{ new object_type[INVEN_TOTAL] };
59     for (int i = 0; i < 4; i++)
60         strcpy(player_ptr->history[i], "");
61
62     for (int i = 0; i < max_q_idx; i++) {
63         quest_type *const q_ptr = &quest[i];
64         q_ptr->status = QUEST_STATUS_UNTAKEN;
65         q_ptr->cur_num = 0;
66         q_ptr->max_num = 0;
67         q_ptr->type = 0;
68         q_ptr->level = 0;
69         q_ptr->r_idx = 0;
70         q_ptr->complev = 0;
71         q_ptr->comptime = 0;
72     }
73
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();
78
79     for (auto &a_ref : a_info) {
80         a_ref.cur_num = 0;
81     }
82
83     k_info_reset();
84     for (auto &r_ref : r_info) {
85         if (r_ref.idx == 0) {
86             continue;
87         }
88         r_ref.cur_num = 0;
89         r_ref.max_num = 100;
90         if (r_ref.flags1 & RF1_UNIQUE)
91             r_ref.max_num = 1;
92         else if (r_ref.flags7 & RF7_NAZGUL)
93             r_ref.max_num = MAX_NAZGUL_NUM;
94
95         r_ref.r_pkills = 0;
96         r_ref.r_akills = 0;
97     }
98
99     player_ptr->food = PY_FOOD_FULL - 1;
100     if (player_ptr->pclass == CLASS_SORCERER) {
101         player_ptr->spell_learned1 = player_ptr->spell_learned2 = 0xffffffffL;
102         player_ptr->spell_worked1 = player_ptr->spell_worked2 = 0xffffffffL;
103     } else {
104         player_ptr->spell_learned1 = player_ptr->spell_learned2 = 0L;
105         player_ptr->spell_worked1 = player_ptr->spell_worked2 = 0L;
106     }
107
108     player_ptr->spell_forgotten1 = player_ptr->spell_forgotten2 = 0L;
109     for (int i = 0; i < 64; i++)
110         player_ptr->spell_order[i] = 99;
111
112     player_ptr->learned_spells = 0;
113     player_ptr->add_spells = 0;
114     player_ptr->knowledge = 0;
115     player_ptr->mutant_regenerate_mod = 100;
116
117     cheat_peek = false;
118     cheat_hear = false;
119     cheat_room = false;
120     cheat_xtra = false;
121     cheat_know = false;
122     cheat_live = false;
123     cheat_save = false;
124     cheat_diary_output = false;
125     cheat_turn = false;
126     cheat_immortal = false;
127
128     w_ptr->total_winner = false;
129     player_ptr->timewalk = false;
130     player_ptr->panic_save = 0;
131
132     w_ptr->noscore = 0;
133     w_ptr->wizard = false;
134     player_ptr->wait_report_score = false;
135     player_ptr->pet_follow_distance = PET_FOLLOW_DIST;
136     player_ptr->pet_extra_flags = (PF_TELEPORT | PF_ATTACK_SPELL | PF_SUMMON_SPELL);
137
138     for (const auto &d_ref : d_info)
139         max_dlv[d_ref.idx] = 0;
140
141     player_ptr->visit = 1;
142     player_ptr->wild_mode = false;
143
144     for (int i = 0; i < MAX_SPELLS; i++) {
145         player_ptr->magic_num1[i] = 0;
146         player_ptr->magic_num2[i] = 0;
147     }
148
149     player_ptr->max_plv = player_ptr->lev = 1;
150     player_ptr->arena_number = 0;
151     player_ptr->current_floor_ptr->inside_arena = false;
152     player_ptr->current_floor_ptr->inside_quest = 0;
153     for (int i = 0; i < MAX_MANE; i++) {
154         player_ptr->mane_spell[i] = RF_ABILITY::MAX;
155         player_ptr->mane_dam[i] = 0;
156     }
157
158     player_ptr->mane_num = 0;
159     player_ptr->exit_bldg = true;
160     player_ptr->today_mon = 0;
161     update_gambling_monsters(player_ptr);
162     player_ptr->muta.clear();
163
164     for (int i = 0; i < 8; i++)
165         player_ptr->virtues[i] = 0;
166
167     player_ptr->dungeon_idx = 0;
168     if (vanilla_town || ironman_downward) {
169         player_ptr->recall_dungeon = DUNGEON_ANGBAND;
170     } else {
171         player_ptr->recall_dungeon = DUNGEON_GALGALS;
172     }
173
174     memcpy(player_ptr->name, tmp.name, sizeof(tmp.name));
175
176 #ifdef SET_UID
177     player_ptr->player_uid = uid;
178 #endif
179 }
180
181 /*!
182  * @brief ダンジョン内部のクエストを初期化する / Initialize random quests and final quests
183  * @param player_ptr プレイヤーへの参照ポインタ
184  */
185 void init_dungeon_quests(player_type *player_ptr)
186 {
187     int number_of_quests = MAX_RANDOM_QUEST - MIN_RANDOM_QUEST + 1;
188     init_flags = INIT_ASSIGN;
189     floor_type *floor_ptr = player_ptr->current_floor_ptr;
190     floor_ptr->inside_quest = MIN_RANDOM_QUEST;
191     parse_fixed_map(player_ptr, "q_info.txt", 0, 0, 0, 0);
192     floor_ptr->inside_quest = 0;
193     for (int i = MIN_RANDOM_QUEST + number_of_quests - 1; i >= MIN_RANDOM_QUEST; i--) {
194         quest_type *q_ptr = &quest[i];
195         monster_race *quest_r_ptr;
196         q_ptr->status = QUEST_STATUS_TAKEN;
197         determine_random_questor(player_ptr, q_ptr);
198         quest_r_ptr = &r_info[q_ptr->r_idx];
199         quest_r_ptr->flags1 |= RF1_QUESTOR;
200         q_ptr->max_num = 1;
201     }
202
203     init_flags = INIT_ASSIGN;
204     floor_ptr->inside_quest = QUEST_OBERON;
205     parse_fixed_map(player_ptr, "q_info.txt", 0, 0, 0, 0);
206     quest[QUEST_OBERON].status = QUEST_STATUS_TAKEN;
207
208     floor_ptr->inside_quest = QUEST_SERPENT;
209     parse_fixed_map(player_ptr, "q_info.txt", 0, 0, 0, 0);
210     quest[QUEST_SERPENT].status = QUEST_STATUS_TAKEN;
211     floor_ptr->inside_quest = 0;
212 }
213
214 /*!
215  * @brief ゲームターンを初期化する / Reset turn
216  * @param player_ptr プレイヤーへの参照ポインタ
217  * @details アンデッド系種族は開始時刻を夜からにする / Undead start just sunset
218  * @details
219  */
220 void init_turn(player_type *player_ptr)
221 {
222     if (player_race_life(player_ptr) == PlayerRaceLife::UNDEAD) {
223         w_ptr->game_turn = (TURNS_PER_TICK * 3 * TOWN_DAWN) / 4 + 1;
224         w_ptr->game_turn_limit = TURNS_PER_TICK * TOWN_DAWN * MAX_DAYS + TURNS_PER_TICK * TOWN_DAWN * 3 / 4;
225     } else {
226         w_ptr->game_turn = 1;
227         w_ptr->game_turn_limit = TURNS_PER_TICK * TOWN_DAWN * (MAX_DAYS - 1) + TURNS_PER_TICK * TOWN_DAWN * 3 / 4;
228     }
229
230     w_ptr->dungeon_turn = 1;
231     w_ptr->dungeon_turn_limit = TURNS_PER_TICK * TOWN_DAWN * (MAX_DAYS - 1) + TURNS_PER_TICK * TOWN_DAWN * 3 / 4;
232 }