OSDN Git Service

[Refactor] #37353 externs.h から util.h への宣言移動。
[hengband/hengband.git] / src / monster1.c
index b8be3f5..04a84b0 100644 (file)
  */
 
 #include "angband.h"
+#include "util.h"
+
 #include "cmd-pet.h"
-#include "monsterrace-hook.h"
+#include "floor.h"
 #include "objectkind-hook.h"
-#include "projection.h"
 #include "monster.h"
+#include "monster-spell.h"
+#include "monsterrace-hook.h"
+#include "spells-summon.h"
+#include "patron.h"
+#include "quest.h"
+#include "artifact.h"
+#include "avatar.h"
+#include "wild.h"
+#include "spells.h"
 
 
 /*
@@ -61,17 +71,9 @@ static bool know_armour(MONRACE_IDX r_idx)
     bool known = (r_ptr->r_cast_spell == MAX_UCHAR)? TRUE: FALSE;
 
        if (cheat_know || known) return (TRUE);
-
-       /* Normal monsters */
        if (kills > 304 / (4 + level)) return (TRUE);
-
-       /* Skip non-uniques */
        if (!(r_ptr->flags1 & RF1_UNIQUE)) return (FALSE);
-
-       /* Unique monsters */
        if (kills > 304 / (38 + (5 * level) / 4)) return (TRUE);
-
-       /* Assume false */
        return (FALSE);
 }
 
@@ -102,14 +104,8 @@ static bool know_damage(MONRACE_IDX r_idx, int i)
        s32b d = d1 * d2;
 
        if (d >= ((4+level)*MAX_UCHAR)/80) d = ((4+level)*MAX_UCHAR-1)/80;
-
-       /* Normal monsters */
        if ((4 + level) * a > 80 * d) return (TRUE);
-
-       /* Skip non-uniques */
        if (!(r_ptr->flags1 & RF1_UNIQUE)) return (FALSE);
-
-       /* Unique monsters */
        if ((4 + level) * (2 * a) > 80 * d) return (TRUE);
 
        /* Assume false */
@@ -421,8 +417,6 @@ static void roff_aux(MONRACE_IDX r_idx, BIT_FLAGS mode)
                /* Start a new line */
                hooked_roff("\n");
        }
-
-       /* Normal monsters */
        else
        {
                /* Killed some this life */
@@ -546,7 +540,6 @@ static void roff_aux(MONRACE_IDX r_idx, BIT_FLAGS mode)
                        if (speed != 110) hooked_roff(_("、かつ", ", and"));
                }
 
-               /* Speed */
                if (speed > 110)
                {
                        if (speed > 139) hook_c_roff(TERM_RED, _("信じ難いほど", " incredibly"));
@@ -2130,7 +2123,7 @@ void output_monster_spoiler(MONRACE_IDX r_idx, void (*roff_func)(TERM_COLOR attr
  */
 monsterrace_hook_type get_monster_hook(void)
 {
-       if (!dun_level && !p_ptr->inside_quest)
+       if (!current_floor_ptr->dun_level && !p_ptr->inside_quest)
        {
                switch (wilderness[p_ptr->wilderness_y][p_ptr->wilderness_x].terrain)
                {
@@ -2169,7 +2162,7 @@ monsterrace_hook_type get_monster_hook(void)
  */
 monsterrace_hook_type get_monster_hook2(POSITION y, POSITION x)
 {
-       feature_type *f_ptr = &f_info[cave[y][x].feat];
+       feature_type *f_ptr = &f_info[current_floor_ptr->grid_array[y][x].feat];
 
        /* Set the monster list */
 
@@ -2215,9 +2208,6 @@ void set_friendly(monster_type *m_ptr)
  */
 void set_pet(monster_type *m_ptr)
 {
-       if (!is_pet(m_ptr)) check_pets_num_and_align(m_ptr, TRUE);
-
-       /* Check for quest completion */
        check_quest_completion(m_ptr);
 
        m_ptr->smart |= SM_PET;
@@ -2234,9 +2224,6 @@ void set_pet(monster_type *m_ptr)
 void set_hostile(monster_type *m_ptr)
 {
        if (p_ptr->inside_battle) return;
-
-       if (is_pet(m_ptr)) check_pets_num_and_align(m_ptr, FALSE);
-
        m_ptr->smart &= ~SM_PET;
        m_ptr->smart &= ~SM_FRIENDLY;
 }
@@ -2366,13 +2353,13 @@ bool monster_can_cross_terrain(FEAT_IDX feat, monster_race *r_ptr, BIT_FLAGS16 m
  */
 bool monster_can_enter(POSITION y, POSITION x, monster_race *r_ptr, BIT_FLAGS16 mode)
 {
-       cave_type *c_ptr = &cave[y][x];
+       grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
 
        /* Player or other monster */
        if (player_bold(y, x)) return FALSE;
-       if (c_ptr->m_idx) return FALSE;
+       if (g_ptr->m_idx) return FALSE;
 
-       return monster_can_cross_terrain(c_ptr->feat, r_ptr, mode);
+       return monster_can_cross_terrain(g_ptr->feat, r_ptr, mode);
 }
 
 
@@ -2527,7 +2514,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
        int dump_gold = 0;
        int number = 0;
 
-       monster_type *m_ptr = &m_list[m_idx];
+       monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
        monster_race *r_ptr = &r_info[m_ptr->r_idx];
 
        bool visible = ((m_ptr->ml && !p_ptr->image) || (r_ptr->flags1 & RF1_UNIQUE));
@@ -2546,12 +2533,11 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                && !p_ptr->inside_battle && !is_pet(m_ptr);
 
        /* The caster is dead? */
-       if (world_monster && world_monster == m_idx) world_monster = 0;
+       if (current_world_ptr->timewalk_m_idx && current_world_ptr->timewalk_m_idx == m_idx) current_world_ptr->timewalk_m_idx = 0;
 
        /* Notice changes in view */
        if (r_ptr->flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
        {
-               /* Update some things */
                p_ptr->update |= (PU_MON_LITE);
        }
 
@@ -2588,7 +2574,6 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                r_ptr = &r_info[m_ptr->r_idx];
        }
 
-       /* Check for quest completion */
        check_quest_completion(m_ptr);
 
        /* Handle the possibility of player vanquishing arena combatant -KMW- */
@@ -2611,7 +2596,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
 
                        /* Prepare to make a prize */
                        object_prep(q_ptr, lookup_kind(arena_info[p_ptr->arena_number].tval, arena_info[p_ptr->arena_number].sval));
-                       apply_magic(q_ptr, object_level, AM_NO_FIXED_ART);
+                       apply_magic(q_ptr, current_floor_ptr->object_level, AM_NO_FIXED_ART);
                        (void)drop_near(q_ptr, -1, y, x);
                }
 
@@ -2621,8 +2606,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                {
                        GAME_TEXT m_name[MAX_NLEN];
 
-                       /* Extract monster name */
-                       monster_desc(m_name, m_ptr, MD_IGNORE_HALLU | MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
+                       monster_desc(m_name, m_ptr, MD_WRONGDOER_NAME);
 
                        do_cmd_write_nikki(NIKKI_ARENA, p_ptr->arena_number, m_name);
                }
@@ -2671,7 +2655,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                /* Prepare to make an object */
                object_prep(q_ptr, lookup_kind(TV_CORPSE, (corpse ? SV_CORPSE : SV_SKELETON)));
 
-               apply_magic(q_ptr, object_level, AM_NO_FIXED_ART);
+               apply_magic(q_ptr, current_floor_ptr->object_level, AM_NO_FIXED_ART);
 
                q_ptr->pval = m_ptr->r_idx;
                (void)drop_near(q_ptr, -1, y, x);
@@ -2718,19 +2702,19 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                        /* Prepare to make a Blade of Chaos */
                        object_prep(q_ptr, lookup_kind(TV_SWORD, SV_BLADE_OF_CHAOS));
 
-                       apply_magic(q_ptr, object_level, AM_NO_FIXED_ART | mo_mode);
+                       apply_magic(q_ptr, current_floor_ptr->object_level, AM_NO_FIXED_ART | mo_mode);
                        (void)drop_near(q_ptr, -1, y, x);
                }
                break;
 
        case MON_RAAL:
-               if (drop_chosen_item && (dun_level > 9))
+               if (drop_chosen_item && (current_floor_ptr->dun_level > 9))
                {
                        q_ptr = &forge;
                        object_wipe(q_ptr);
 
                        /* Activate restriction */
-                       if ((dun_level > 49) && one_in_(5))
+                       if ((current_floor_ptr->dun_level > 49) && one_in_(5))
                                get_obj_num_hook = kind_is_good_book;
                        else
                                get_obj_num_hook = kind_is_book;
@@ -2811,7 +2795,6 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                                a_ptr = &a_info[a_idx];
                        } while (a_ptr->cur_num);
 
-                       /* Create the artifact */
                        if (create_named_art(a_idx, y, x))
                        {
                                a_ptr->cur_num = 1;
@@ -2870,7 +2853,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                        /* Prepare to make a Can of Toys */
                        object_prep(q_ptr, lookup_kind(TV_CHEST, SV_CHEST_KANDUME));
 
-                       apply_magic(q_ptr, object_level, AM_NO_FIXED_ART);
+                       apply_magic(q_ptr, current_floor_ptr->object_level, AM_NO_FIXED_ART);
                        (void)drop_near(q_ptr, -1, y, x);
                }
                break;
@@ -2888,7 +2871,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                switch (r_ptr->d_char)
                {
                case '(':
-                       if (dun_level > 0)
+                       if (current_floor_ptr->dun_level > 0)
                        {
                                q_ptr = &forge;
                                object_wipe(q_ptr);
@@ -2903,7 +2886,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                        break;
 
                case '/':
-                       if (dun_level > 4)
+                       if (current_floor_ptr->dun_level > 4)
                        {
                                q_ptr = &forge;
                                object_wipe(q_ptr);
@@ -2918,7 +2901,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                        break;
 
                case '[':
-                       if (dun_level > 19)
+                       if (current_floor_ptr->dun_level > 19)
                        {
                                q_ptr = &forge;
                                object_wipe(q_ptr);
@@ -2933,7 +2916,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                        break;
 
                case '\\':
-                       if (dun_level > 4)
+                       if (current_floor_ptr->dun_level > 4)
                        {
                                q_ptr = &forge;
                                object_wipe(q_ptr);
@@ -2969,7 +2952,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
        if (drop_chosen_item)
        {
                ARTIFACT_IDX a_idx = 0;
-               int chance = 0;
+               PERCENTAGE chance = 0;
 
                for (i = 0; i < 4; i++)
                {
@@ -2984,7 +2967,6 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
 
                        if (!a_ptr->cur_num)
                        {
-                               /* Create the artifact */
                                if (create_named_art(a_idx, y, x))
                                {
                                        a_ptr->cur_num = 1;
@@ -2996,19 +2978,18 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                        }
                }
 
-               if ((r_ptr->flags7 & RF7_GUARDIAN) && (d_info[dungeon_type].final_guardian == m_ptr->r_idx))
+               if ((r_ptr->flags7 & RF7_GUARDIAN) && (d_info[p_ptr->dungeon_idx].final_guardian == m_ptr->r_idx))
                {
-                       KIND_OBJECT_IDX k_idx = d_info[dungeon_type].final_object ? d_info[dungeon_type].final_object
+                       KIND_OBJECT_IDX k_idx = d_info[p_ptr->dungeon_idx].final_object ? d_info[p_ptr->dungeon_idx].final_object
                                : lookup_kind(TV_SCROLL, SV_SCROLL_ACQUIREMENT);
 
-                       if (d_info[dungeon_type].final_artifact)
+                       if (d_info[p_ptr->dungeon_idx].final_artifact)
                        {
-                               a_idx = d_info[dungeon_type].final_artifact;
+                               a_idx = d_info[p_ptr->dungeon_idx].final_artifact;
                                artifact_type *a_ptr = &a_info[a_idx];
 
                                if (!a_ptr->cur_num)
                                {
-                                       /* Create the artifact */
                                        if (create_named_art(a_idx, y, x))
                                        {
                                                a_ptr->cur_num = 1;
@@ -3019,7 +3000,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                                        else if (!preserve_mode) a_ptr->cur_num = 1;
 
                                        /* Prevent rewarding both artifact and "default" object */
-                                       if (!d_info[dungeon_type].final_object) k_idx = 0;
+                                       if (!d_info[p_ptr->dungeon_idx].final_object) k_idx = 0;
                                }
                        }
 
@@ -3030,10 +3011,10 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                                /* Prepare to make a reward */
                                object_prep(q_ptr, k_idx);
 
-                               apply_magic(q_ptr, object_level, AM_NO_FIXED_ART | AM_GOOD);
+                               apply_magic(q_ptr, current_floor_ptr->object_level, AM_NO_FIXED_ART | AM_GOOD);
                                (void)drop_near(q_ptr, -1, y, x);
                        }
-                       msg_format(_("あなたは%sを制覇した!", "You have conquered %s!"), d_name + d_info[dungeon_type].name);
+                       msg_format(_("あなたは%sを制覇した!", "You have conquered %s!"), d_name + d_info[p_ptr->dungeon_idx].name);
                }
        }
 
@@ -3059,7 +3040,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
        coin_type = force_coin;
 
        /* Average dungeon and monster levels */
-       object_level = (dun_level + r_ptr->level) / 2;
+       current_floor_ptr->object_level = (current_floor_ptr->dun_level + r_ptr->level) / 2;
 
        /* Drop some objects */
        for (j = 0; j < number; j++)
@@ -3067,28 +3048,21 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                q_ptr = &forge;
                object_wipe(q_ptr);
 
-               /* Make Gold */
                if (do_gold && (!do_item || (randint0(100) < 50)))
                {
-                       /* Make some gold */
                        if (!make_gold(q_ptr)) continue;
-
                        dump_gold++;
                }
-
-               /* Make Object */
                else
                {
-                       /* Make an object */
                        if (!make_object(q_ptr, mo_mode)) continue;
-
                        dump_item++;
                }
                (void)drop_near(q_ptr, -1, y, x);
        }
 
        /* Reset the object level */
-       object_level = base_level;
+       current_floor_ptr->object_level = current_floor_ptr->base_level;
 
        /* Reset "coin" type */
        coin_type = 0;
@@ -3118,11 +3092,7 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
 
                do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("見事に変愚蛮怒の勝利者となった!", "become *WINNER* of Hengband finely!"));
 
-               if ((p_ptr->pclass == CLASS_CHAOS_WARRIOR) || (p_ptr->muta2 & MUT2_CHAOS_GIFT))
-               {
-                       msg_format(_("%sからの声が響いた。", "The voice of %s booms out:"), chaos_patrons[p_ptr->chaos_patron]);
-                       msg_print(_("『よくやった、定命の者よ!』", "'Thou art donst well, mortal!'"));
-               }
+               admire_from_patron(p_ptr);
 
                /* Congratulations */
                msg_print(_("*** おめでとう ***", "*** CONGRATULATIONS ***"));
@@ -3130,3 +3100,116 @@ void monster_death(MONSTER_IDX m_idx, bool drop_item)
                msg_print(_("準備が整ったら引退(自殺コマンド)しても結構です。", "You may retire (commit suicide) when you are ready."));
        }
 }
+
+/*!
+ * @brief モンスターを撃破した際の述語メッセージを返す /
+ * Return monster death string
+ * @param r_ptr 撃破されたモンスターの種族情報を持つ構造体の参照ポインタ
+ * @return 撃破されたモンスターの述語
+ */
+concptr extract_note_dies(MONRACE_IDX r_idx)
+{
+       monster_race *r_ptr = &r_info[r_idx];
+       /* Some monsters get "destroyed" */
+       if (!monster_living(r_idx))
+       {
+               int i;
+
+               for (i = 0; i < 4; i++)
+               {
+                       if (r_ptr->blow[i].method == RBM_EXPLODE)
+                       {
+                               return _("は爆発して粉々になった。", " explodes into tiny shreds.");
+                       }
+               }
+               return _("を倒した。", " is destroyed.");
+       }
+
+       return _("は死んだ。", " dies.");
+}
+
+/*
+ * Monster health description
+ */
+concptr look_mon_desc(monster_type *m_ptr, BIT_FLAGS mode)
+{
+       monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
+       bool living;
+       int perc;
+       concptr desc;
+       concptr attitude;
+       concptr clone;
+
+       /* Determine if the monster is "living" */
+       living = monster_living(m_ptr->ap_r_idx);
+
+       /* Calculate a health "percentage" */
+       perc = m_ptr->maxhp > 0 ? 100L * m_ptr->hp / m_ptr->maxhp : 0;
+
+       /* Healthy monsters */
+       if (m_ptr->hp >= m_ptr->maxhp)
+       {
+               desc = living ? _("無傷", "unhurt") : _("無ダメージ", "undamaged");
+       }
+
+       else if (perc >= 60)
+       {
+               desc = living ? _("軽傷", "somewhat wounded") : _("小ダメージ", "somewhat damaged");
+       }
+
+       else if (perc >= 25)
+       {
+               desc = living ? _("負傷", "wounded") : _("中ダメージ", "damaged");
+       }
+
+       else if (perc >= 10)
+       {
+               desc = living ? _("重傷", "badly wounded") : _("大ダメージ", "badly damaged");
+       }
+
+       else
+       {
+               desc = living ? _("半死半生", "almost dead") : _("倒れかけ", "almost destroyed");
+       }
+
+       /* Need attitude information? */
+       if (!(mode & 0x01))
+       {
+               /* Full information is not needed */
+               attitude = "";
+       }
+       else if (is_pet(m_ptr))
+       {
+               attitude = _(", ペット", ", pet");
+       }
+       else if (is_friendly(m_ptr))
+       {
+               attitude = _(", 友好的", ", friendly");
+       }
+       else
+       {
+               attitude = _("", "");
+       }
+
+       /* Clone monster? */
+       if (m_ptr->smart & SM_CLONED)
+       {
+               clone = ", clone";
+       }
+       else
+       {
+               clone = "";
+       }
+
+       /* Display monster's level --- idea borrowed from ToME */
+       if (ap_r_ptr->r_tkills && !(m_ptr->mflag2 & MFLAG2_KAGE))
+       {
+               return format(_("レベル%d, %s%s%s", "Level %d, %s%s%s"), ap_r_ptr->level, desc, attitude, clone);
+       }
+       else
+       {
+               return format(_("レベル???, %s%s%s", "Level ???, %s%s%s"), desc, attitude, clone);
+       }
+
+}
+