OSDN Git Service

Merge pull request #1363 from backwardsEric/Pakuman-English
[hengbandforosx/hengbandosx.git] / src / monster-floor / monster-death.cpp
1 #include "monster-floor/monster-death.h"
2 #include "artifact/fixed-art-generator.h"
3 #include "cmd-building/cmd-building.h"
4 #include "core/player-redraw-types.h"
5 #include "core/player-update-types.h"
6 #include "dungeon/dungeon.h"
7 #include "dungeon/quest-completion-checker.h"
8 #include "effect/effect-characteristics.h"
9 #include "effect/effect-processor.h"
10 #include "floor/floor-object.h"
11 #include "game-option/birth-options.h"
12 #include "game-option/play-record-options.h"
13 #include "io/write-diary.h"
14 #include "lore/lore-store.h"
15 #include "main/music-definitions-table.h"
16 #include "main/sound-of-music.h"
17 #include "market/arena-info-table.h"
18 #include "monster-floor/monster-death-util.h"
19 #include "monster-floor/monster-object.h"
20 #include "monster-floor/special-death-switcher.h"
21 #include "monster-race/monster-race-hook.h"
22 #include "monster-race/monster-race.h"
23 #include "monster-race/race-flags1.h"
24 #include "monster-race/race-flags2.h"
25 #include "monster-race/race-flags7.h"
26 #include "monster-race/race-flags9.h"
27 #include "monster-race/race-indice-types.h"
28 #include "monster/monster-describer.h"
29 #include "monster/monster-description-types.h"
30 #include "monster/monster-flag-types.h"
31 #include "monster/monster-info.h"
32 #include "monster/monster-list.h"
33 #include "object-enchant/apply-magic.h"
34 #include "object-enchant/item-apply-magic.h"
35 #include "object/object-kind-hook.h"
36 #include "pet/pet-fall-off.h"
37 #include "player/patron.h"
38 #include "sv-definition/sv-other-types.h"
39 #include "sv-definition/sv-scroll-types.h"
40 #include "system/artifact-type-definition.h"
41 #include "system/building-type-definition.h"
42 #include "system/floor-type-definition.h"
43 #include "system/monster-race-definition.h"
44 #include "system/monster-type-definition.h"
45 #include "system/player-type-definition.h"
46 #include "system/system-variables.h"
47 #include "util/bit-flags-calculator.h"
48 #include "view/display-messages.h"
49 #include "world/world.h"
50
51 static void write_pet_death(player_type *player_ptr, monster_death_type *md_ptr)
52 {
53     md_ptr->md_y = md_ptr->m_ptr->fy;
54     md_ptr->md_x = md_ptr->m_ptr->fx;
55     if (record_named_pet && is_pet(md_ptr->m_ptr) && md_ptr->m_ptr->nickname) {
56         GAME_TEXT m_name[MAX_NLEN];
57         monster_desc(player_ptr, m_name, md_ptr->m_ptr, MD_INDEF_VISIBLE);
58         exe_write_diary(player_ptr, DIARY_NAMED_PET, 3, m_name);
59     }
60 }
61
62 static void on_dead_explosion(player_type *player_ptr, monster_death_type *md_ptr)
63 {
64     for (int i = 0; i < 4; i++) {
65         if (md_ptr->r_ptr->blow[i].method != RBM_EXPLODE)
66             continue;
67
68         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
69         EFFECT_ID typ = mbe_info[md_ptr->r_ptr->blow[i].effect].explode_type;
70         DICE_NUMBER d_dice = md_ptr->r_ptr->blow[i].d_dice;
71         DICE_SID d_side = md_ptr->r_ptr->blow[i].d_side;
72         HIT_POINT damage = damroll(d_dice, d_side);
73         (void)project(player_ptr, md_ptr->m_idx, 3, md_ptr->md_y, md_ptr->md_x, damage, typ, flg);
74         break;
75     }
76 }
77
78 static void on_defeat_arena_monster(player_type *player_ptr, monster_death_type *md_ptr)
79 {
80     floor_type *floor_ptr = player_ptr->current_floor_ptr;
81     if (!floor_ptr->inside_arena || is_pet(md_ptr->m_ptr))
82         return;
83
84     player_ptr->exit_bldg = true;
85     if (player_ptr->arena_number > MAX_ARENA_MONS)
86         msg_print(_("素晴らしい!君こそ真の勝利者だ。", "You are a Genuine Champion!"));
87     else
88         msg_print(_("勝利!チャンピオンへの道を進んでいる。", "Victorious! You're on your way to becoming Champion."));
89
90     if (arena_info[player_ptr->arena_number].tval) {
91         object_type forge;
92         object_type *q_ptr = &forge;
93         q_ptr->prep(player_ptr, lookup_kind(arena_info[player_ptr->arena_number].tval, arena_info[player_ptr->arena_number].sval));
94         apply_magic_to_object(player_ptr, q_ptr, floor_ptr->object_level, AM_NO_FIXED_ART);
95         (void)drop_near(player_ptr, q_ptr, -1, md_ptr->md_y, md_ptr->md_x);
96     }
97
98     if (player_ptr->arena_number > MAX_ARENA_MONS)
99         player_ptr->arena_number++;
100
101     player_ptr->arena_number++;
102     if (!record_arena)
103         return;
104
105     GAME_TEXT m_name[MAX_NLEN];
106     monster_desc(player_ptr, m_name, md_ptr->m_ptr, MD_WRONGDOER_NAME);
107     exe_write_diary(player_ptr, DIARY_ARENA, player_ptr->arena_number, m_name);
108 }
109
110 static void drop_corpse(player_type *player_ptr, monster_death_type *md_ptr)
111 {
112     floor_type *floor_ptr = player_ptr->current_floor_ptr;
113     bool is_drop_corpse = one_in_(md_ptr->r_ptr->flags1 & RF1_UNIQUE ? 1 : 4);
114     is_drop_corpse &= (md_ptr->r_ptr->flags9 & (RF9_DROP_CORPSE | RF9_DROP_SKELETON)) != 0;
115     is_drop_corpse &= !(floor_ptr->inside_arena || player_ptr->phase_out || md_ptr->cloned
116         || ((md_ptr->m_ptr->r_idx == current_world_ptr->today_mon) && is_pet(md_ptr->m_ptr)));
117     if (!is_drop_corpse)
118         return;
119
120     bool corpse = false;
121     if (!(md_ptr->r_ptr->flags9 & RF9_DROP_SKELETON))
122         corpse = true;
123     else if ((md_ptr->r_ptr->flags9 & RF9_DROP_CORPSE) && (md_ptr->r_ptr->flags1 & RF1_UNIQUE))
124         corpse = true;
125     else if (md_ptr->r_ptr->flags9 & RF9_DROP_CORPSE) {
126         if ((0 - ((md_ptr->m_ptr->maxhp) / 4)) > md_ptr->m_ptr->hp) {
127             if (one_in_(5))
128                 corpse = true;
129         } else {
130             if (!one_in_(5))
131                 corpse = true;
132         }
133     }
134
135     object_type forge;
136     object_type *q_ptr = &forge;
137     q_ptr->prep(player_ptr, lookup_kind(TV_CORPSE, (corpse ? SV_CORPSE : SV_SKELETON)));
138     apply_magic_to_object(player_ptr, q_ptr, floor_ptr->object_level, AM_NO_FIXED_ART);
139     q_ptr->pval = md_ptr->m_ptr->r_idx;
140     (void)drop_near(player_ptr, q_ptr, -1, md_ptr->md_y, md_ptr->md_x);
141 }
142
143 /*!
144  * @brief アーティファクトのドロップ判定処理
145  * @param player_ptr プレーヤーへの参照ポインタ
146  * @param md_ptr モンスター死亡構造体への参照ポインタ
147  * @return 何かドロップするなら1以上、何もドロップしないなら0
148  */
149 static ARTIFACT_IDX drop_artifact_index(player_type *player_ptr, monster_death_type *md_ptr)
150 {
151     ARTIFACT_IDX a_idx = 0;
152     PERCENTAGE chance = 0;
153     for (int i = 0; i < 4; i++) {
154         if (!md_ptr->r_ptr->artifact_id[i])
155             break;
156
157         a_idx = md_ptr->r_ptr->artifact_id[i];
158         chance = md_ptr->r_ptr->artifact_percent[i];
159         if ((randint0(100) >= chance) && !current_world_ptr->wizard)
160             continue;
161
162         artifact_type *a_ptr = &a_info[a_idx];
163         if (a_ptr->cur_num == 1)
164             continue;
165
166         if (create_named_art(player_ptr, a_idx, md_ptr->md_y, md_ptr->md_x)) {
167             a_ptr->cur_num = 1;
168             if (current_world_ptr->character_dungeon)
169                 a_ptr->floor_id = player_ptr->floor_id;
170
171             break;
172         }
173
174         if (!preserve_mode) {
175             a_ptr->cur_num = 1;
176             break;
177         }
178     }
179
180     return a_idx;
181 }
182
183 static KIND_OBJECT_IDX drop_dungeon_final_artifact(player_type *player_ptr, monster_death_type *md_ptr, ARTIFACT_IDX a_idx)
184 {
185     KIND_OBJECT_IDX k_idx
186         = d_info[player_ptr->dungeon_idx].final_object != 0 ? d_info[player_ptr->dungeon_idx].final_object : lookup_kind(TV_SCROLL, SV_SCROLL_ACQUIREMENT);
187     if (d_info[player_ptr->dungeon_idx].final_artifact == 0)
188         return k_idx;
189
190     a_idx = d_info[player_ptr->dungeon_idx].final_artifact;
191     artifact_type *a_ptr = &a_info[a_idx];
192     if (a_ptr->cur_num == 1)
193         return k_idx;
194     if (create_named_art(player_ptr, a_idx, md_ptr->md_y, md_ptr->md_x)) {
195         a_ptr->cur_num = 1;
196         if (current_world_ptr->character_dungeon)
197             a_ptr->floor_id = player_ptr->floor_id;
198     } else if (!preserve_mode) {
199         a_ptr->cur_num = 1;
200     }
201
202     return d_info[player_ptr->dungeon_idx].final_object ? k_idx : 0;
203 }
204
205 static void drop_artifact(player_type *player_ptr, monster_death_type *md_ptr)
206 {
207     if (!md_ptr->drop_chosen_item)
208         return;
209
210     ARTIFACT_IDX a_idx = drop_artifact_index(player_ptr, md_ptr);
211     if (((md_ptr->r_ptr->flags7 & RF7_GUARDIAN) == 0) || (d_info[player_ptr->dungeon_idx].final_guardian != md_ptr->m_ptr->r_idx))
212         return;
213
214     KIND_OBJECT_IDX k_idx = drop_dungeon_final_artifact(player_ptr, md_ptr, a_idx);
215     if (k_idx != 0) {
216         object_type forge;
217         object_type *q_ptr = &forge;
218         q_ptr->prep(player_ptr, k_idx);
219         apply_magic_to_object(player_ptr, q_ptr, player_ptr->current_floor_ptr->object_level, AM_NO_FIXED_ART | AM_GOOD);
220         (void)drop_near(player_ptr, q_ptr, -1, md_ptr->md_y, md_ptr->md_x);
221     }
222
223     msg_format(_("あなたは%sを制覇した!", "You have conquered %s!"), d_info[player_ptr->dungeon_idx].name.c_str());
224 }
225
226 static void decide_drop_quality(monster_death_type *md_ptr)
227 {
228     md_ptr->mo_mode = 0L;
229     if (md_ptr->r_ptr->flags1 & RF1_DROP_GOOD)
230         md_ptr->mo_mode |= AM_GOOD;
231
232     if (md_ptr->r_ptr->flags1 & RF1_DROP_GREAT)
233         md_ptr->mo_mode |= (AM_GOOD | AM_GREAT);
234 }
235
236 static int decide_drop_numbers(player_type *player_ptr, monster_death_type *md_ptr, const bool drop_item)
237 {
238     int drop_numbers = 0;
239     if ((md_ptr->r_ptr->flags1 & RF1_DROP_60) && (randint0(100) < 60))
240         drop_numbers++;
241
242     if ((md_ptr->r_ptr->flags1 & RF1_DROP_90) && (randint0(100) < 90))
243         drop_numbers++;
244
245     if (md_ptr->r_ptr->flags1 & RF1_DROP_1D2)
246         drop_numbers += damroll(1, 2);
247
248     if (md_ptr->r_ptr->flags1 & RF1_DROP_2D2)
249         drop_numbers += damroll(2, 2);
250
251     if (md_ptr->r_ptr->flags1 & RF1_DROP_3D2)
252         drop_numbers += damroll(3, 2);
253
254     if (md_ptr->r_ptr->flags1 & RF1_DROP_4D2)
255         drop_numbers += damroll(4, 2);
256
257     if (md_ptr->cloned && !(md_ptr->r_ptr->flags1 & RF1_UNIQUE))
258         drop_numbers = 0;
259
260     if (is_pet(md_ptr->m_ptr) || player_ptr->phase_out || player_ptr->current_floor_ptr->inside_arena)
261         drop_numbers = 0;
262
263     if (!drop_item && (md_ptr->r_ptr->d_char != '$'))
264         drop_numbers = 0;
265
266     if ((md_ptr->r_ptr->flags2 & (RF2_MULTIPLY)) && (md_ptr->r_ptr->r_akills > 1024))
267         drop_numbers = 0;
268
269     return drop_numbers;
270 }
271
272 static void drop_items_golds(player_type *player_ptr, monster_death_type *md_ptr, int drop_numbers)
273 {
274     int dump_item = 0;
275     int dump_gold = 0;
276     for (int i = 0; i < drop_numbers; i++) {
277         object_type forge;
278         object_type *q_ptr = &forge;
279         q_ptr->wipe();
280         if (md_ptr->do_gold && (!md_ptr->do_item || (randint0(100) < 50))) {
281             if (!make_gold(player_ptr, q_ptr))
282                 continue;
283
284             dump_gold++;
285         } else {
286             if (!make_object(player_ptr, q_ptr, md_ptr->mo_mode))
287                 continue;
288
289             dump_item++;
290         }
291
292         (void)drop_near(player_ptr, q_ptr, -1, md_ptr->md_y, md_ptr->md_x);
293     }
294
295     floor_type *floor_ptr = player_ptr->current_floor_ptr;
296     floor_ptr->object_level = floor_ptr->base_level;
297     coin_type = 0;
298     bool visible = (md_ptr->m_ptr->ml && !player_ptr->image) || ((md_ptr->r_ptr->flags1 & RF1_UNIQUE) != 0);
299     if (visible && (dump_item || dump_gold))
300         lore_treasure(player_ptr, md_ptr->m_idx, dump_item, dump_gold);
301 }
302
303 /*!
304  * @brief 最終ボス(混沌のサーペント)を倒したときの処理
305  * @param player_ptr プレイヤー情報への参照ポインタ
306  */
307 static void on_defeat_last_boss(player_type *player_ptr)
308 {
309     current_world_ptr->total_winner = true;
310     add_winner_class(player_ptr->pclass);
311     player_ptr->redraw |= PR_TITLE;
312     play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_FINAL_QUEST_CLEAR);
313     exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, _("見事に変愚蛮怒の勝利者となった!", "finally became *WINNER* of Hengband!"));
314     admire_from_patron(player_ptr);
315     msg_print(_("*** おめでとう ***", "*** CONGRATULATIONS ***"));
316     msg_print(_("あなたはゲームをコンプリートしました。", "You have won the game!"));
317     msg_print(_("準備が整ったら引退(自殺コマンド)しても結構です。", "You may retire (commit suicide) when you are ready."));
318 }
319
320 /*!
321  * @brief モンスターが死亡した時の処理 /
322  * Handle the "death" of a monster.
323  * @param m_idx 死亡したモンスターのID
324  * @param drop_item TRUEならばモンスターのドロップ処理を行う
325  * @return 撃破されたモンスターの述語
326  * @details
327  * <pre>
328  * Disperse treasures centered at the monster location based on the
329  * various flags contained in the monster flags fields.
330  * Check for "Quest" completion when a quest monster is killed.
331  * Note that only the player can induce "monster_death()" on Uniques.
332  * Thus (for now) all Quest monsters should be Uniques.
333  * Note that monsters can now carry objects, and when a monster dies,
334  * it drops all of its objects, which may disappear in crowded rooms.
335  * </pre>
336  */
337 void monster_death(player_type *player_ptr, MONSTER_IDX m_idx, bool drop_item)
338 {
339     monster_death_type tmp_md;
340     monster_death_type *md_ptr = initialize_monster_death_type(player_ptr, &tmp_md, m_idx, drop_item);
341     if (current_world_ptr->timewalk_m_idx && current_world_ptr->timewalk_m_idx == m_idx)
342         current_world_ptr->timewalk_m_idx = 0;
343
344     // プレイヤーしかユニークを倒せないのでここで時間を記録
345     if (any_bits(md_ptr->r_ptr->flags1, RF1_UNIQUE) && md_ptr->m_ptr->mflag2.has_not(MFLAG2::CLONED)) {
346         update_playtime();
347         md_ptr->r_ptr->defeat_time = current_world_ptr->play_time;
348         md_ptr->r_ptr->defeat_level = player_ptr->lev;
349     }
350
351     if (md_ptr->r_ptr->flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
352         player_ptr->update |= PU_MON_LITE;
353
354     write_pet_death(player_ptr, md_ptr);
355     on_dead_explosion(player_ptr, md_ptr);
356     if (md_ptr->m_ptr->mflag2.has(MFLAG2::CHAMELEON)) {
357         choose_new_monster(player_ptr, m_idx, true, MON_CHAMELEON);
358         md_ptr->r_ptr = &r_info[md_ptr->m_ptr->r_idx];
359     }
360
361     check_quest_completion(player_ptr, md_ptr->m_ptr);
362     on_defeat_arena_monster(player_ptr, md_ptr);
363     if (m_idx == player_ptr->riding && process_fall_off_horse(player_ptr, -1, false))
364         msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
365
366     drop_corpse(player_ptr, md_ptr);
367     monster_drop_carried_objects(player_ptr, md_ptr->m_ptr);
368     decide_drop_quality(md_ptr);
369     switch_special_death(player_ptr, md_ptr);
370     drop_artifact(player_ptr, md_ptr);
371     int drop_numbers = decide_drop_numbers(player_ptr, md_ptr, drop_item);
372     coin_type = md_ptr->force_coin;
373     floor_type *floor_ptr = player_ptr->current_floor_ptr;
374     floor_ptr->object_level = (floor_ptr->dun_level + md_ptr->r_ptr->level) / 2;
375     drop_items_golds(player_ptr, md_ptr, drop_numbers);
376     if (((md_ptr->r_ptr->flags1 & RF1_QUESTOR) == 0) || player_ptr->phase_out || (md_ptr->m_ptr->r_idx != MON_SERPENT) || md_ptr->cloned)
377         return;
378
379     on_defeat_last_boss(player_ptr);
380 }
381
382 /*!
383  * @brief モンスターを撃破した際の述語メッセージを返す /
384  * Return monster death string
385  * @param r_ptr 撃破されたモンスターの種族情報を持つ構造体の参照ポインタ
386  * @return 撃破されたモンスターの述語
387  */
388 concptr extract_note_dies(MONRACE_IDX r_idx)
389 {
390     monster_race *r_ptr = &r_info[r_idx];
391     if (monster_living(r_idx))
392         return _("は死んだ。", " dies.");
393
394     for (int i = 0; i < 4; i++)
395         if (r_ptr->blow[i].method == RBM_EXPLODE)
396             return _("は爆発して粉々になった。", " explodes into tiny shreds.");
397
398     return _("を倒した。", " is destroyed.");
399 }