OSDN Git Service

破邪。まだ作ってる途中。
[hengbandforosx/hengbandosx.git] / src / monster2.c
index 50bd0a5..7b9f883 100644 (file)
@@ -844,6 +844,17 @@ static bool summon_specific_aux(int r_idx)
                        okay = (r_ptr->flags7 & RF7_GUARDIAN);
                        break;
                }
+
+               case SUMMON_KNIGHTS:
+               {
+                       okay = ((r_idx == MON_NOV_PALADIN) ||
+                               (r_idx == MON_NOV_PALADIN_G) ||
+                               (r_idx == MON_PALADIN) ||
+                               (r_idx == MON_W_KNIGHT) ||
+                               (r_idx == MON_ULTRA_PALADIN) ||
+                               (r_idx == MON_KNI_TEMPLAR));
+                       break;
+               }
        }
 
        /* Result */
@@ -1236,10 +1247,10 @@ s16b get_mon_num(int level)
 
        if (level > MAX_DEPTH - 1) level = MAX_DEPTH - 1;
 
-       if ((dungeon_turn > hoge*10000L) && !level)
+       if ((dungeon_turn > hoge*(TURNS_PER_TICK*500L)) && !level)
        {
-               pls_kakuritu = MAX(2, NASTY_MON-((dungeon_turn/50000L-hoge/10)));
-               pls_level = MIN(8,3 + dungeon_turn/400000L-hoge/40);
+               pls_kakuritu = MAX(2, NASTY_MON-((dungeon_turn/(TURNS_PER_TICK*2500L)-hoge/10)));
+               pls_level = MIN(8,3 + dungeon_turn/(TURNS_PER_TICK*20000L)-hoge/40);
        }
        else
        {
@@ -1449,7 +1460,7 @@ s16b get_mon_num(int level)
  *   0x40 --> Assume the monster is hidden
  *   0x80 --> Assume the monster is visible
  *  0x100 --> Chameleon's true name
- *  0x200 --> Ignore hallucination
+ *  0x200 --> Ignore hallucination, and penetrate shape change
  *
  * Useful Modes:
  *   0x00 --> Full nominative name ("the kobold") or "it"
@@ -1470,8 +1481,7 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode)
        bool            seen, pron;
        bool            named = FALSE;
 
-       if (m_ptr->mflag2 & MFLAG_KAGE) r_ptr = &r_info[MON_KAGE];
-       else r_ptr = &r_info[m_ptr->r_idx];
+       r_ptr = &r_info[m_ptr->ap_r_idx];
 
        if ((mode & 0x100) && (m_ptr->mflag2 & MFLAG_CHAMELEON))
        {
@@ -1635,6 +1645,27 @@ if (!get_rnd_line("silly_j.txt", m_ptr->r_idx, silly_name))
        /* Handle all other visible monster requests */
        else
        {
+               /* Tanuki? */
+               if (is_pet(m_ptr) && m_ptr->ap_r_idx != m_ptr->r_idx)
+               {
+#ifdef JP
+                               char *t;
+                               strcpy(buf, name);
+                               t = buf;
+                               while(strncmp(t, "¡Ù", 2) && *t) t++;
+                               if (*t)
+                               {
+                                       *t = '\0';
+                                       (void)sprintf(desc, "%s¡©¡Ù", buf);
+                               }
+                               else
+                                       (void)sprintf(desc, "%s¡©", name);
+#else
+                               (void)sprintf(desc, "%s?", name);
+#endif
+               }
+               else
+
                /* It could be a Unique */
                if ((r_ptr->flags1 & RF1_UNIQUE) && !(p_ptr->image && !(mode & 0x200)))
                {
@@ -1680,16 +1711,6 @@ if (!get_rnd_line("silly_j.txt", m_ptr->r_idx, silly_name))
 #endif
 
                        (void)strcat(desc, name);
-
-                       if (m_ptr->nickname)
-                       {
-#ifdef JP
-                               sprintf(buf,"¡Ö%s¡×",quark_str(m_ptr->nickname));
-#else
-                               sprintf(buf," called %s",quark_str(m_ptr->nickname));
-#endif
-                               strcat(desc,buf);
-                       }
                }
 
                /* It could be a normal, definite, monster */
@@ -1711,45 +1732,57 @@ if (!get_rnd_line("silly_j.txt", m_ptr->r_idx, silly_name))
 #endif
 
                        (void)strcat(desc, name);
+               }
 
-                       if (m_ptr->nickname)
-                       {
+               if (m_ptr->nickname)
+               {
 #ifdef JP
-                               sprintf(buf,"¡Ö%s¡×",quark_str(m_ptr->nickname));
+                       sprintf(buf,"¡Ö%s¡×",quark_str(m_ptr->nickname));
 #else
-                               sprintf(buf," called %s",quark_str(m_ptr->nickname));
+                       sprintf(buf," called %s",quark_str(m_ptr->nickname));
 #endif
-                               strcat(desc,buf);
-                       }
+                       strcat(desc,buf);
+               }
 
-                       if ((m_ptr->fy == py) && (m_ptr->fx == px))
+               if ((m_ptr->fy == py) && (m_ptr->fx == px))
+               {
 #ifdef JP
-                               strcat(desc,"(¾èÇÏÃæ)");
+                       strcat(desc,"(¾èÇÏÃæ)");
 #else
-                               strcat(desc,"(riding)");
+                       strcat(desc,"(riding)");
 #endif
-                       if ((mode & 0x200) && (m_ptr->mflag2 & MFLAG_CHAMELEON))
+               }
+
+               if ((mode & 0x200) && (m_ptr->mflag2 & MFLAG_CHAMELEON))
+               {
+                       if (r_ptr->flags1 & RF1_UNIQUE)
                        {
-                               if (r_ptr->flags1 & RF1_UNIQUE)
 #ifdef JP
-                                       strcat(desc,"(¥«¥á¥ì¥ª¥ó¤Î²¦)");
+                               strcat(desc,"(¥«¥á¥ì¥ª¥ó¤Î²¦)");
 #else
-                                       strcat(desc,"(Chameleon Lord)");
+                               strcat(desc,"(Chameleon Lord)");
 #endif
-                               else
+                       }
+                       else
+                       {
 #ifdef JP
-                                       strcat(desc,"(¥«¥á¥ì¥ª¥ó)");
+                               strcat(desc,"(¥«¥á¥ì¥ª¥ó)");
 #else
-                                       strcat(desc,"(Chameleon)");
+                               strcat(desc,"(Chameleon)");
 #endif
                        }
                }
 
+               if ((mode & 0x200) && m_ptr->ap_r_idx != m_ptr->r_idx)
+               {
+                       strcat(desc, format("(%s)", r_name + r_info[m_ptr->r_idx].name));
+               }
+
                /* Handle the Possessive as a special afterthought */
                if (mode & 0x02)
                {
                        /* XXX Check for trailing "s" */
-
+                       
                        /* Simply append "apostrophe" and "s" */
 #ifdef JP
                        (void)strcat(desc, "¤Î");
@@ -2347,9 +2380,10 @@ void update_mon(int m_idx, bool full)
                        if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
 
                        /* Hack -- Count "fresh" sightings */
-                       if ((m_ptr->mflag2 & MFLAG_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
+                       if ((m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
                                r_info[MON_KAGE].r_sights++;
-                       else if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
+                       else if (m_ptr->ap_r_idx == m_ptr->r_idx && 
+                                r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
 
                        /* Eldritch Horror */
                        if (r_ptr->flags2 & RF2_ELDRITCH_HORROR)
@@ -2535,6 +2569,7 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
        }
 
        m_ptr->r_idx = r_idx;
+       m_ptr->ap_r_idx = r_idx;
        update_mon(m_idx, FALSE);
        lite_spot(m_ptr->fy, m_ptr->fx);
        if (born) return;
@@ -2583,6 +2618,28 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
        m_ptr->hp = (long)(m_ptr->hp * m_ptr->max_maxhp) / oldmaxhp;
 }
 
+/*
+ *  Set initial racial appearance of a monster
+ */
+static int initial_r_appearance(int r_idx)
+{
+       int ap_r_idx;
+       int min = MIN(base_level-5, 50);
+
+       if (!(r_info[r_idx].flags7 & RF7_TANUKI))
+               return r_idx;
+
+       get_mon_num_prep(monster_hook_chameleon, NULL);
+
+       while (1)
+       {
+               ap_r_idx = get_mon_num(base_level + 10);
+               if (r_info[ap_r_idx].flags7 & RF7_AQUATIC) continue;
+               if (r_info[ap_r_idx].level >= min) break;
+       }
+       return ap_r_idx;
+}
+
 
 /*
  * Attempt to place a monster of the given race at the given location.
@@ -2603,7 +2660,7 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
  * This is the only function which may place a monster in the dungeon,
  * except for the savefile loading code.
  */
-bool place_monster_one(int y, int x, int r_idx, bool slp, bool friendly, bool pet, bool no_pet)
+bool place_monster_one(int who, int y, int x, int r_idx, bool slp, bool friendly, bool pet, bool no_pet)
 {
        int                     i;
        int rune_dam = 0;
@@ -2729,8 +2786,6 @@ msg_print("
 
                        /* Break the rune */
                        c_ptr->feat = floor_type[randint0(100)];
-                       c_ptr->info &= ~(CAVE_MASK);
-                       c_ptr->info |= CAVE_FLOOR;
 
                        /* Notice */
                        note_spot(y, x);
@@ -2800,6 +2855,17 @@ msg_print("
 
        /* Save the race */
        m_ptr->r_idx = r_idx;
+       m_ptr->ap_r_idx = initial_r_appearance(r_idx);
+
+       /* Sub-alignment of a monster */
+       if ((who > 0) && !(r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)))
+               m_ptr->sub_align = m_list[who].sub_align;
+       else
+       {
+               m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
+               if (r_ptr->flags3 & RF3_EVIL) m_ptr->sub_align |= SUB_ALIGN_EVIL;
+               if (r_ptr->flags3 & RF3_GOOD) m_ptr->sub_align |= SUB_ALIGN_GOOD;
+       }
 
        /* Place the monster at the location */
        m_ptr->fy = y;
@@ -2831,7 +2897,12 @@ msg_print("
                m_ptr->mflag2 |= MFLAG_CHAMELEON;
                rating++;
        }
-       else if (is_kage) m_ptr->mflag2 |= MFLAG_KAGE;
+       else if (is_kage)
+       {
+               m_ptr->ap_r_idx = MON_KAGE;
+               m_ptr->mflag2 |= MFLAG_KAGE;
+       }
+
        if (no_pet) m_ptr->mflag2 |= MFLAG_NOPET;
 
        /* Not visible */
@@ -2903,15 +2974,19 @@ msg_print("
          }
        }
 
+       if (summon_specific_type == SUMMON_KNIGHTS) m_ptr->fast = 100;
+
        if (m_ptr->mspeed > 199) m_ptr->mspeed = 199;
 
        /* Give a random starting energy */
-       m_ptr->energy = (byte)randint0(100);
-
-       /* Nightmare monsters are more prepared */
-       if (ironman_nightmare)
+       if (!ironman_nightmare)
+       {
+               m_ptr->energy_need = ENERGY_NEED() - (s16b)randint0(100);
+       }
+       else
        {
-               m_ptr->energy *= 2;
+               /* Nightmare monsters are more prepared */
+               m_ptr->energy_need = ENERGY_NEED() - (s16b)randint0(100) * 2;
        }
 
        /* Force monster to wait for player, unless in Nightmare mode */
@@ -3036,8 +3111,6 @@ msg_print("
 
                /* Break the rune */
                c_ptr->feat = floor_type[randint0(100)];
-               c_ptr->info &= ~(CAVE_MASK);
-               c_ptr->info |= CAVE_FLOOR;
                note_spot(y, x);
                lite_spot(y, x);
        }
@@ -3130,7 +3203,7 @@ static bool mon_scatter(int *yp, int *xp, int y, int x, int max_dist)
 /*
  * Attempt to place a "group" of monsters around the given location
  */
-static bool place_monster_group(int y, int x, int r_idx, bool slp, bool friendly, bool pet, bool no_pet)
+static bool place_monster_group(int who, int y, int x, int r_idx, bool slp, bool friendly, bool pet, bool no_pet)
 {
        monster_race *r_ptr = &r_info[r_idx];
 
@@ -3199,7 +3272,7 @@ static bool place_monster_group(int y, int x, int r_idx, bool slp, bool friendly
                        if (!cave_empty_bold2(my, mx)) continue;
 
                        /* Attempt to place another monster */
-                       if (place_monster_one(my, mx, r_idx, slp, friendly, pet, no_pet))
+                       if (place_monster_one(who, my, mx, r_idx, slp, friendly, pet, no_pet))
                        {
                                /* Add it to the "hack" set */
                                hack_y[hack_n] = my;
@@ -3222,6 +3295,7 @@ static bool place_monster_group(int y, int x, int r_idx, bool slp, bool friendly
  * Hack -- help pick an escort type
  */
 static int place_monster_idx = 0;
+static int place_monster_m_idx = 0;
 
 /*
  * Hack -- help pick an escort type
@@ -3229,6 +3303,7 @@ static int place_monster_idx = 0;
 static bool place_monster_okay(int r_idx)
 {
        monster_race *r_ptr = &r_info[place_monster_idx];
+       monster_type *m_ptr = &m_list[place_monster_m_idx];
 
        monster_race *z_ptr = &r_info[r_idx];
 
@@ -3248,8 +3323,8 @@ static bool place_monster_okay(int r_idx)
        if (place_monster_idx == r_idx) return (FALSE);
 
        /* Skip different alignment */
-       if (((r_ptr->flags3 & RF3_EVIL) && (z_ptr->flags3 & RF3_GOOD)) ||
-           ((r_ptr->flags3 & RF3_GOOD) && (z_ptr->flags3 & RF3_EVIL)))
+       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 (r_ptr->flags7 & RF7_FRIENDLY)
@@ -3285,7 +3360,7 @@ static bool place_monster_okay(int r_idx)
  * Note the use of the new "monster allocation table" code to restrict
  * the "get_mon_num()" function to "legal" escort types.
  */
-bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp, bool friendly, bool pet, bool no_kage, bool no_pet)
+bool place_monster_aux(int who, int y, int x, int r_idx, bool slp, bool grp, bool friendly, bool pet, bool no_kage, bool no_pet)
 {
        int             i;
        monster_race    *r_ptr = &r_info[r_idx];
@@ -3294,18 +3369,19 @@ bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp, bool friendl
        else is_kage = FALSE;
 
        /* Place one monster, or fail */
-       if (!place_monster_one(y, x, r_idx, slp, friendly, pet, no_pet)) return (FALSE);
+       if (!place_monster_one(who, y, x, r_idx, slp, friendly, pet, no_pet)) return (FALSE);
 
 
        /* Require the "group" flag */
        if (!grp) return (TRUE);
+       place_monster_m_idx = hack_m_idx_ii;
 
 
        /* Friends for certain monsters */
        if (r_ptr->flags1 & (RF1_FRIENDS))
        {
                /* Attempt to place a group */
-               (void)place_monster_group(y, x, r_idx, slp, friendly, pet, no_pet);
+               (void)place_monster_group(who, y, x, r_idx, slp, friendly, pet, no_pet);
        }
 
 
@@ -3336,14 +3412,14 @@ bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp, bool friendl
                        if (!z) break;
 
                        /* Place a single escort */
-                       (void)place_monster_one(ny, nx, z, slp, friendly, pet, no_pet);
+                       (void)place_monster_one(place_monster_m_idx, ny, nx, z, slp, friendly, pet, no_pet);
 
                        /* Place a "group" of escorts if needed */
                        if ((r_info[z].flags1 & RF1_FRIENDS) ||
                            (r_ptr->flags1 & RF1_ESCORTS))
                        {
                                /* Place a group of monsters */
-                               (void)place_monster_group(ny, nx, z, slp, friendly, pet, no_pet);
+                               (void)place_monster_group(place_monster_m_idx, ny, nx, z, slp, friendly, pet, no_pet);
                        }
                }
        }
@@ -3372,7 +3448,7 @@ bool place_monster(int y, int x, bool slp, bool grp)
        if (!r_idx) return (FALSE);
 
        /* Attempt to place the monster */
-       if (place_monster_aux(y, x, r_idx, slp, grp, FALSE, FALSE, FALSE, FALSE)) return (TRUE);
+       if (place_monster_aux(0, y, x, r_idx, slp, grp, FALSE, FALSE, FALSE, FALSE)) return (TRUE);
 
        /* Oops */
        return (FALSE);
@@ -3418,7 +3494,7 @@ bool alloc_horde(int y, int x)
        while (--attempts)
        {
                /* Attempt to place the monster */
-               if (place_monster_aux(y, x, r_idx, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)) break;
+               if (place_monster_aux(0, y, x, r_idx, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)) break;
        }
 
        if (attempts < 1) {horde_align = 0;return FALSE;}
@@ -3479,7 +3555,7 @@ bool alloc_monster(int dis, bool slp)
                         if (cave_empty_bold2(oy, ox) && monster_can_cross_terrain(cave[oy][ox].feat, &r_info[guardian]))
                        {
                                /* Place the guardian */
-                               if (place_monster_aux(oy, ox, guardian, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE)) break;
+                               if (place_monster_aux(0, oy, ox, guardian, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE)) break;
                        }
                         /* One less try */
                         try--;
@@ -3570,15 +3646,14 @@ static bool summon_specific_okay(int r_idx)
        if (summon_specific_who > 0)
        {
                monster_type *m_ptr = &m_list[summon_specific_who];
-               monster_race *s_ptr = &r_info[m_ptr->r_idx];
 
                /* Do not summon enemies */
 
                /* Friendly vs. opposite aligned normal or pet */
                if (((r_ptr->flags3 & RF3_EVIL) &&
-                         (s_ptr->flags3 & RF3_GOOD)) ||
+                         (m_ptr->sub_align & SUB_ALIGN_GOOD)) ||
                         ((r_ptr->flags3 & RF3_GOOD) &&
-                         (s_ptr->flags3 & RF3_EVIL)))
+                         (m_ptr->sub_align & SUB_ALIGN_EVIL)))
                {
                        return FALSE;
                }
@@ -3684,7 +3759,7 @@ bool summon_specific(int who, int y1, int x1, int lev, int type, bool group, boo
        if ((type == SUMMON_BLUE_HORROR) || (type == SUMMON_DAWN)) no_kage = TRUE;
 
        /* Attempt to place the monster (awake, allow groups) */
-       if (!place_monster_aux(y, x, r_idx, FALSE, group, friendly, pet, no_kage, no_pet))
+       if (!place_monster_aux(who, y, x, r_idx, FALSE, group, friendly, pet, no_kage, no_pet))
        {
                summon_specific_type = 0;
                return (FALSE);
@@ -3696,7 +3771,7 @@ bool summon_specific(int who, int y1, int x1, int lev, int type, bool group, boo
 }
 
 /* A "dangerous" function, creates a pet of the specified type */
-bool summon_named_creature (int oy, int ox, int r_idx, bool slp, bool group_ok, bool friendly, bool pet)
+bool summon_named_creature (int who, int oy, int ox, int r_idx, bool slp, bool group_ok, bool friendly, bool pet)
 {
        int x, y;
 
@@ -3711,7 +3786,7 @@ bool summon_named_creature (int oy, int ox, int r_idx, bool slp, bool group_ok,
        if (!mon_scatter(&y, &x, oy, ox, 2)) return FALSE;
 
        /* Place it (allow groups) */
-       return place_monster_aux(y, x, r_idx, slp, group_ok, friendly, pet, TRUE, FALSE);
+       return place_monster_aux(who, y, x, r_idx, slp, group_ok, friendly, pet, TRUE, FALSE);
 }
 
 
@@ -3730,7 +3805,7 @@ bool multiply_monster(int m_idx, bool clone, bool friendly, bool pet)
                return FALSE;
 
        /* Create a new monster (awake, no groups) */
-       if (!place_monster_aux(y, x, m_ptr->r_idx, FALSE, FALSE, friendly, pet, TRUE, (bool)(m_ptr->mflag2 & MFLAG_NOPET)))
+       if (!place_monster_aux(m_idx, y, x, m_ptr->r_idx, FALSE, FALSE, friendly, pet, TRUE, (bool)(m_ptr->mflag2 & MFLAG_NOPET)))
                return FALSE;
 
        if (clone)