OSDN Git Service

モンスターの一時属性を含めた敵対属性の処理を関数にまとめて整理した.
authornothere <nothere@0568b783-4c39-0410-ac80-bf13821ea2a2>
Sun, 6 Jul 2003 16:24:37 +0000 (16:24 +0000)
committernothere <nothere@0568b783-4c39-0410-ac80-bf13821ea2a2>
Sun, 6 Jul 2003 16:24:37 +0000 (16:24 +0000)
この過程で, 以下の修正や変更を含む.
* モンスター魔法 "死者復活" の使用判定で, 敵対属性の死体しか周囲にな
  い場合は死者復活を使用しないようにした. また, この判定はモンスター
  対モンスターにも適用される.
* 善良かつ邪悪のモンスターが別の善良かつ邪悪のモンスターを召喚できな
  かったバグを修正.

src/externs.h
src/melee2.c
src/monster1.c
src/monster2.c
src/mspells1.c
src/mspells2.c
src/rooms.c

index 80e4b4d..d23adf1 100644 (file)
@@ -841,6 +841,7 @@ extern void anger_monster(monster_type *m_ptr);
 extern bool monster_can_cross_terrain(byte feat, monster_race *r_ptr);
 extern bool monster_can_enter(int y, int x, monster_race *r_ptr);
 extern bool are_enemies(monster_type *m_ptr1, monster_type *m_ptr2);
+extern bool monster_has_hostile_align(monster_type *m_ptr, int pa_good, int pa_evil, monster_race *r_ptr);
 extern bool monster_living(monster_race *r_ptr);
 extern bool no_questor_or_bounty_uniques(int r_idx);
 
@@ -1367,6 +1368,7 @@ extern int spell_exp_level(int spell_exp);
 /* mspells1.c */
 extern bool clean_shot(int y1, int x1, int y2, int x2, bool friend);
 extern bool summon_possible(int y1, int x1);
+extern bool raise_possible(monster_type *m_ptr);
 extern bool spell_is_inate(u16b spell);
 
 /* mspells2.c */
index 97daa5e..7197553 100644 (file)
@@ -2470,8 +2470,7 @@ msg_print("
        /* Paranoia... no pet uniques outside wizard mode -- TY */
        if (is_pet(m_ptr) &&
            ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) &&
-             ((p_ptr->align > 9 && (r_ptr->flags3 & RF3_EVIL)) ||
-             (p_ptr->align < -9 && (r_ptr->flags3 & RF3_GOOD))))
+             monster_has_hostile_align(NULL, 10, -10, r_ptr))
             || (r_ptr->flagsr & RFR_RES_ALL)))
        {
                gets_angry = TRUE;
index 3d20dc0..cb57e0b 100644 (file)
@@ -3607,6 +3607,22 @@ bool monster_can_enter(int y, int x, monster_race *r_ptr)
 }
 
 
+/*
+ * Check if this monster has "hostile" alignment (aux)
+ */
+static bool check_hostile_align(byte sub_align1, byte sub_align2)
+{
+       if (sub_align1 != sub_align2)
+       {
+               if (((sub_align1 & SUB_ALIGN_EVIL) && (sub_align2 & SUB_ALIGN_GOOD)) ||
+                       ((sub_align1 & SUB_ALIGN_GOOD) && (sub_align2 & SUB_ALIGN_EVIL)))
+                       return TRUE;
+       }
+
+       /* Non-hostile alignment */
+       return FALSE;
+}
+
 
 /*
  * Check if two monsters are enemies
@@ -3629,15 +3645,9 @@ bool are_enemies(monster_type *m_ptr, monster_type *n_ptr)
        }
 
        /* Friendly vs. opposite aligned normal or pet */
-       if (m_ptr->sub_align != n_ptr->sub_align)
+       if (check_hostile_align(m_ptr->sub_align, n_ptr->sub_align))
        {
-               if (((m_ptr->sub_align & SUB_ALIGN_EVIL) &&
-                         (n_ptr->sub_align & SUB_ALIGN_GOOD)) ||
-                        ((m_ptr->sub_align & SUB_ALIGN_GOOD) &&
-                         (n_ptr->sub_align & SUB_ALIGN_EVIL)))
-               {
-                       if (!(m_ptr->mflag2 & MFLAG2_CHAMELEON) || !(n_ptr->mflag2 & MFLAG2_CHAMELEON)) return TRUE;
-               }
+               if (!(m_ptr->mflag2 & MFLAG2_CHAMELEON) || !(n_ptr->mflag2 & MFLAG2_CHAMELEON)) return TRUE;
        }
 
        /* Hostile vs. non-hostile */
@@ -3652,6 +3662,36 @@ bool are_enemies(monster_type *m_ptr, monster_type *n_ptr)
 
 
 /*
+ * Check if this monster race has "hostile" alignment
+ * If user is player, m_ptr == NULL.
+ */
+bool monster_has_hostile_align(monster_type *m_ptr, int pa_good, int pa_evil, monster_race *r_ptr)
+{
+       byte sub_align1 = SUB_ALIGN_NEUTRAL;
+       byte sub_align2 = SUB_ALIGN_NEUTRAL;
+
+       if (m_ptr) /* For a monster */
+       {
+               sub_align1 = m_ptr->sub_align;
+       }
+       else /* For player */
+       {
+               if (p_ptr->align >= pa_good) sub_align1 |= SUB_ALIGN_GOOD;
+               if (p_ptr->align <= pa_evil) sub_align1 |= SUB_ALIGN_EVIL;
+       }
+
+       /* Racial alignment flags */
+       if (r_ptr->flags3 & RF3_EVIL) sub_align2 |= SUB_ALIGN_EVIL;
+       if (r_ptr->flags3 & RF3_GOOD) sub_align2 |= SUB_ALIGN_GOOD;
+
+       if (check_hostile_align(sub_align1, sub_align2)) return TRUE;
+
+       /* Non-hostile alignment */
+       return FALSE;
+}
+
+
+/*
  * Is the monster "alive"?
  *
  * Used to determine the message to print for a killed monster.
index efb8945..78a78d9 100644 (file)
@@ -2719,17 +2719,13 @@ static bool monster_hook_chameleon_lord(int r_idx)
        /* Not born */
        if (!(old_r_ptr->flags7 & RF7_CHAMELEON))
        {
-               if ((m_ptr->sub_align & SUB_ALIGN_EVIL) && (r_ptr->flags3 & RF3_GOOD)) return FALSE;
-               if ((m_ptr->sub_align & SUB_ALIGN_GOOD) && (r_ptr->flags3 & RF3_EVIL)) return FALSE;
+               if (monster_has_hostile_align(m_ptr, 0, 0, r_ptr)) return FALSE;
        }
 
        /* Born now */
        else if (summon_specific_who > 0)
        {
-               monster_type *sm_ptr = &m_list[summon_specific_who];
-
-               if ((sm_ptr->sub_align & SUB_ALIGN_EVIL) && (r_ptr->flags3 & RF3_GOOD)) return FALSE;
-               if ((sm_ptr->sub_align & SUB_ALIGN_GOOD) && (r_ptr->flags3 & RF3_EVIL)) return FALSE;
+               if (monster_has_hostile_align(&m_list[summon_specific_who], 0, 0, r_ptr)) return FALSE;
        }
 
        return TRUE;
@@ -2761,10 +2757,7 @@ static bool monster_hook_chameleon(int r_idx)
        /* Born now */
        else if (summon_specific_who > 0)
        {
-               monster_type *sm_ptr = &m_list[summon_specific_who];
-
-               if ((sm_ptr->sub_align & SUB_ALIGN_EVIL) && (r_ptr->flags3 & RF3_GOOD)) return FALSE;
-               if ((sm_ptr->sub_align & SUB_ALIGN_GOOD) && (r_ptr->flags3 & RF3_EVIL)) return FALSE;
+               if (monster_has_hostile_align(&m_list[summon_specific_who], 0, 0, r_ptr)) return FALSE;
        }
 
        return (*(get_monster_hook()))(r_idx);
@@ -3202,11 +3195,7 @@ msg_print("
        else if ((r_ptr->flags7 & RF7_FRIENDLY) ||
                 (mode & PM_FORCE_FRIENDLY) || is_friendly_idx(who))
        {
-               if (!(p_ptr->align >= 0 && (r_ptr->flags3 & RF3_EVIL)) &&
-                   !(p_ptr->align < 0 && (r_ptr->flags3 & RF3_GOOD)))
-               {
-                       set_friendly(m_ptr);
-               }
+               if (!monster_has_hostile_align(NULL, 0, -1, r_ptr)) set_friendly(m_ptr);
        }
 
        /* Assume no sleeping */
@@ -3603,15 +3592,11 @@ static bool place_monster_okay(int r_idx)
        if (place_monster_idx == r_idx) return (FALSE);
 
        /* Skip different alignment */
-       if (((m_ptr->sub_align & SUB_ALIGN_EVIL) && (z_ptr->flags3 & RF3_GOOD)) ||
-           ((m_ptr->sub_align & SUB_ALIGN_GOOD) && (z_ptr->flags3 & RF3_EVIL)))
-               return FALSE;
+       if (monster_has_hostile_align(m_ptr, 0, 0, z_ptr)) return FALSE;
 
        if (r_ptr->flags7 & RF7_FRIENDLY)
        {
-               if (((p_ptr->align < 0) && (z_ptr->flags3 & RF3_GOOD)) ||
-                   ((p_ptr->align > 0) && (z_ptr->flags3 & RF3_EVIL)))
-                       return FALSE;
+               if (monster_has_hostile_align(NULL, 1, -1, z_ptr)) return FALSE;
        }
 
        if ((r_ptr->flags7 & RF7_CHAMELEON) && !(z_ptr->flags7 & RF7_CHAMELEON))
@@ -3939,31 +3924,18 @@ static bool summon_specific_okay(int r_idx)
                /* Do not summon enemies */
 
                /* Friendly vs. opposite aligned normal or pet */
-               if (((r_ptr->flags3 & RF3_EVIL) &&
-                         (m_ptr->sub_align & SUB_ALIGN_GOOD)) ||
-                        ((r_ptr->flags3 & RF3_GOOD) &&
-                         (m_ptr->sub_align & SUB_ALIGN_EVIL)))
-               {
-                       return FALSE;
-               }
+               if (monster_has_hostile_align(m_ptr, 0, 0, r_ptr)) return FALSE;
 
                /* Hostile vs. non-hostile */
-               if (is_hostile(m_ptr) != summon_specific_hostile)
-               {
-                       return FALSE;
-               }
+               if (is_hostile(m_ptr) != summon_specific_hostile) return FALSE;
        }
        /* Use the player's alignment */
        else if (summon_specific_who < 0)
        {
                /* Do not summon enemies of the pets */
-               if ((p_ptr->align < -9) && (r_ptr->flags3 & RF3_GOOD))
-               {
-                       if (!one_in_((0-p_ptr->align)/2+1)) return FALSE;
-               }
-               else if ((p_ptr->align > 9) && (r_ptr->flags3 & RF3_EVIL))
+               if (monster_has_hostile_align(NULL, 10, -10, r_ptr))
                {
-                       if (!one_in_(p_ptr->align/2+1)) return FALSE;
+                       if (!one_in_(ABS(p_ptr->align) / 2 + 1)) return FALSE;
                }
        }
 
@@ -3974,8 +3946,7 @@ static bool summon_specific_okay(int r_idx)
 
        if ((summon_specific_who < 0) &&
            ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) &&
-           (((p_ptr->align > 9) && (r_ptr->flags3 & RF3_EVIL)) ||
-            ((p_ptr->align < -9) && (r_ptr->flags3 & RF3_GOOD))))
+           monster_has_hostile_align(NULL, 10, -10, r_ptr))
                return FALSE;
 
        if ((r_ptr->flags7 & RF7_CHAMELEON) && (d_info[dungeon_type].flags1 & DF1_CHAMELEON)) return TRUE;
index ad0189d..fd18ed2 100644 (file)
@@ -386,9 +386,11 @@ bool summon_possible(int y1, int x1)
 }
 
 
-static bool raise_possible(int y, int x)
+bool raise_possible(monster_type *m_ptr)
 {
        int xx, yy;
+       int y = m_ptr->fy;
+       int x = m_ptr->fx;
        s16b this_o_idx, next_o_idx = 0;
        cave_type *c_ptr;
 
@@ -411,7 +413,9 @@ static bool raise_possible(int y, int x)
 
                                /* Known to be worthless? */
                                if (o_ptr->tval == TV_CORPSE)
-                                       return TRUE;
+                               {
+                                       if (!monster_has_hostile_align(m_ptr, 0, 0, &r_info[o_ptr->pval])) return TRUE;
+                               }
                        }
                }
        }
@@ -1090,7 +1094,7 @@ static int choose_attack_spell(int m_idx, byte spells[], byte num)
        }
 
        /* Raise-dead if possible (sometimes) */
-       if (raise_num && (randint0(100) < 40) && raise_possible(m_ptr->fy, m_ptr->fx))
+       if (raise_num && (randint0(100) < 40))
        {
                /* Choose raise-dead spell */
                return (raise[randint0(raise_num)]);
@@ -1477,6 +1481,13 @@ bool make_attack_spell(int m_idx)
                        f6 &= ~(RF6_SUMMON_MASK);
                }
 
+               /* Check for a possible raise dead */
+               if ((f6 & RF6_RAISE_DEAD) && !raise_possible(m_ptr))
+               {
+                       /* Remove raise dead spell */
+                       f6 &= ~(RF6_RAISE_DEAD);
+               }
+
                /* No spells left */
                if (!f4 && !f5 && !f6) return (FALSE);
        }
index 09686f9..ef707fd 100644 (file)
@@ -477,6 +477,13 @@ bool monst_spell_monst(int m_idx)
                        f5 &= ~(RF5_SUMMON_MASK);
                        f6 &= ~(RF6_SUMMON_MASK);
                }
+
+               /* Check for a possible raise dead */
+               if ((f6 & RF6_RAISE_DEAD) && !raise_possible(m_ptr))
+               {
+                       /* Remove raise dead spell */
+                       f6 &= ~(RF6_RAISE_DEAD);
+               }
        }
 
        if (r_ptr->flags2 & RF2_SMART)
index 2f66208..c5ae47c 100644 (file)
@@ -1927,7 +1927,7 @@ static void build_type5(int by0, int bx0, bool pit)
        int i;
        nest_mon_info_type nest_mon_info[NUM_NEST_MON_TYPE];
 
-       int align = 0;
+       monster_type align;
 
        cave_type *c_ptr;
 
@@ -2031,22 +2031,22 @@ static void build_type5(int by0, int bx0, bool pit)
        /* Prepare allocation table */
        get_mon_num_prep(n_ptr->hook_func, NULL);
 
+       align.sub_align = SUB_ALIGN_NEUTRAL;
+
        /* Pick some monster types */
        for (i = 0; i < NUM_NEST_MON_TYPE; i++)
        {
                int r_idx = 0, attempts = 100;
+               monster_race *r_ptr = NULL;
 
                while (attempts--)
                {
                        /* Get a (hard) monster type */
                        r_idx = get_mon_num(dun_level + 10);
+                       r_ptr = &r_info[r_idx];
 
                        /* Decline incorrect alignment */
-                       if (((align < 0) && (r_info[r_idx].flags3 & RF3_GOOD)) ||
-                                ((align > 0) && (r_info[r_idx].flags3 & RF3_EVIL)))
-                       {
-                               continue;
-                       }
+                       if (monster_has_hostile_align(&align, 0, 0, r_ptr)) continue;
 
                        /* Accept this monster */
                        break;
@@ -2056,8 +2056,8 @@ static void build_type5(int by0, int bx0, bool pit)
                if (!r_idx || !attempts) return;
 
                /* Note the alignment */
-               if (r_info[r_idx].flags3 & RF3_GOOD) align++;
-               else if (r_info[r_idx].flags3 & RF3_EVIL) align--;
+               if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL;
+               if (r_ptr->flags3 & RF3_GOOD) align.sub_align |= SUB_ALIGN_GOOD;
 
                nest_mon_info[i].r_idx = r_idx;
                nest_mon_info[i].used = FALSE;
@@ -2164,7 +2164,7 @@ static void build_type6(int by0, int bx0, bool nest)
 
        int what[16];
 
-       int align = 0;
+       monster_type align;
 
        cave_type *c_ptr;
 
@@ -2265,22 +2265,22 @@ static void build_type6(int by0, int bx0, bool nest)
        /* Prepare allocation table */
        get_mon_num_prep(n_ptr->hook_func, NULL);
 
+       align.sub_align = SUB_ALIGN_NEUTRAL;
+
        /* Pick some monster types */
        for (i = 0; i < 16; i++)
        {
                int r_idx = 0, attempts = 100;
+               monster_race *r_ptr = NULL;
 
                while (attempts--)
                {
                        /* Get a (hard) monster type */
                        r_idx = get_mon_num(dun_level + 10);
+                       r_ptr = &r_info[r_idx];
 
                        /* Decline incorrect alignment */
-                       if (((align < 0) && (r_info[r_idx].flags3 & RF3_GOOD)) ||
-                                ((align > 0) && (r_info[r_idx].flags3 & RF3_EVIL)))
-                       {
-                               continue;
-                       }
+                       if (monster_has_hostile_align(&align, 0, 0, r_ptr)) continue;
 
                        /* Accept this monster */
                        break;
@@ -2290,8 +2290,8 @@ static void build_type6(int by0, int bx0, bool nest)
                if (!r_idx || !attempts) return;
 
                /* Note the alignment */
-               if (r_info[r_idx].flags3 & RF3_GOOD) align++;
-               else if (r_info[r_idx].flags3 & RF3_EVIL) align--;
+               if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL;
+               if (r_ptr->flags3 & RF3_GOOD) align.sub_align |= SUB_ALIGN_GOOD;
 
                what[i] = r_idx;
        }
@@ -5423,7 +5423,7 @@ static void build_type13(int by0, int bx0)
 
        int what[16];
 
-       int align = 0;
+       monster_type align;
 
        cave_type *c_ptr;
 
@@ -5547,22 +5547,22 @@ static void build_type13(int by0, int bx0)
        /* Prepare allocation table */
        get_mon_num_prep(n_ptr->hook_func, vault_aux_trapped_pit);
 
+       align.sub_align = SUB_ALIGN_NEUTRAL;
+
        /* Pick some monster types */
        for (i = 0; i < 16; i++)
        {
                int r_idx = 0, attempts = 100;
+               monster_race *r_ptr = NULL;
 
                while (attempts--)
                {
                        /* Get a (hard) monster type */
                        r_idx = get_mon_num(dun_level + 0);
+                       r_ptr = &r_info[r_idx];
 
                        /* Decline incorrect alignment */
-                       if (((align < 0) && (r_info[r_idx].flags3 & RF3_GOOD)) ||
-                                ((align > 0) && (r_info[r_idx].flags3 & RF3_EVIL)))
-                       {
-                               continue;
-                       }
+                       if (monster_has_hostile_align(&align, 0, 0, r_ptr)) continue;
 
                        /* Accept this monster */
                        break;
@@ -5572,8 +5572,8 @@ static void build_type13(int by0, int bx0)
                if (!r_idx || !attempts) return;
 
                /* Note the alignment */
-               if (r_info[r_idx].flags3 & RF3_GOOD) align++;
-               else if (r_info[r_idx].flags3 & RF3_EVIL) align--;
+               if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL;
+               if (r_ptr->flags3 & RF3_GOOD) align.sub_align |= SUB_ALIGN_GOOD;
 
                what[i] = r_idx;
        }