OSDN Git Service

破邪。まだ作ってる途中。
[hengbandforosx/hengbandosx.git] / src / monster2.c
index 9797b54..7b9f883 100644 (file)
@@ -153,6 +153,23 @@ cptr funny_comments[MAX_SAN_COMMENT] =
 
 
 /*
+ * Set the target of counter attack
+ */
+void set_target(monster_type *m_ptr, int y, int x)
+{
+       m_ptr->target_y = y;
+       m_ptr->target_x = x;
+}
+
+/*
+ * Reset the target of counter attack
+ */
+void reset_target(monster_type *m_ptr)
+{
+       set_target(m_ptr, 0, 0);
+}
+
+/*
  * Delete a monster by index.
  *
  * When a monster is deleted, all of its objects are deleted.
@@ -174,7 +191,17 @@ void delete_monster_idx(int i)
 
 
        /* Hack -- Reduce the racial counter */
-       r_ptr->cur_num--;
+       if (m_ptr->mflag2 & MFLAG_CHAMELEON)
+       {
+               if (r_ptr->flags1 & RF1_UNIQUE)
+                       r_info[MON_CHAMELEON_K].cur_num--;
+               else
+                       r_info[MON_CHAMELEON].cur_num--;
+       }
+       else
+       {
+               r_ptr->cur_num--;
+       }
 
        /* Hack -- count the number of "reproducers" */
        if (r_ptr->flags2 & (RF2_MULTIPLY)) num_repro--;
@@ -372,7 +399,7 @@ void compact_monsters(int size)
                        if (r_ptr->flags1 & (RF1_UNIQUE)) chance = 100;
 
                        /* All monsters get a saving throw */
-                       if (rand_int(100) < chance) continue;
+                       if (randint0(100) < chance) continue;
 
                        /* Delete the monster */
                        delete_monster_idx(i);
@@ -441,7 +468,15 @@ void wipe_m_list(void)
                /* Mega-Hack -- preserve Unique's XXX XXX XXX */
 
                /* Hack -- Reduce the racial counter */
-               r_ptr->cur_num--;
+               if (m_ptr->mflag2 & MFLAG_CHAMELEON)
+               {
+                       if (r_ptr->flags1 & RF1_UNIQUE)
+                               r_info[MON_CHAMELEON_K].cur_num = 0;
+                       else
+                               r_info[MON_CHAMELEON].cur_num = 0;
+               }
+               else
+                       r_ptr->cur_num = 0;
 
                /* Monster is gone */
                cave[m_ptr->fy][m_ptr->fx].m_idx = 0;
@@ -554,7 +589,7 @@ static bool summon_unique_okay = FALSE;
 static bool summon_specific_aux(int r_idx)
 {
        monster_race *r_ptr = &r_info[r_idx];
-       bool okay = FALSE;
+       int okay = FALSE;
 
        /* Check our requirements */
        switch (summon_specific_type)
@@ -591,19 +626,19 @@ static bool summon_specific_aux(int r_idx)
 
                case SUMMON_DEMON:
                {
-                       okay = (bool)(r_ptr->flags3 & RF3_DEMON);
+                       okay = (r_ptr->flags3 & RF3_DEMON);
                        break;
                }
 
                case SUMMON_UNDEAD:
                {
-                       okay = (bool)(r_ptr->flags3 & RF3_UNDEAD);
+                       okay = (r_ptr->flags3 & RF3_UNDEAD);
                        break;
                }
 
                case SUMMON_DRAGON:
                {
-                       okay = (bool)(r_ptr->flags3 & RF3_DRAGON);
+                       okay = (r_ptr->flags3 & RF3_DRAGON);
                        break;
                }
 
@@ -708,7 +743,7 @@ static bool summon_specific_aux(int r_idx)
 
                case SUMMON_ANIMAL:
                {
-                       okay = (bool)(r_ptr->flags3 & (RF3_ANIMAL));
+                       okay = (r_ptr->flags3 & (RF3_ANIMAL));
                        break;
                }
 
@@ -803,10 +838,28 @@ static bool summon_specific_aux(int r_idx)
                        okay = (r_idx == MON_LOUSE);
                        break;
                }
+
+               case SUMMON_GUARDIANS:
+               {
+                       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 */
-       return (okay);
+       /* Since okay is int, "return (okay);" is not correct. */
+       return (bool)(okay ? TRUE : FALSE);
 }
 
 
@@ -1073,29 +1126,43 @@ errr get_mon_num_prep(monster_hook_type monster_hook,
        /* Scan the allocation table */
        for (i = 0; i < alloc_race_size; i++)
        {
+               monster_race    *r_ptr;
+               
                /* Get the entry */
                alloc_entry *entry = &alloc_race_table[i];
 
-               /* Accept monsters which pass the restriction, if any */
-               if ((!get_mon_num_hook || (*get_mon_num_hook)(entry->index)) &&
-                       (!get_mon_num2_hook || (*get_mon_num2_hook)(entry->index)))
+               entry->prob2 = 0;
+               r_ptr = &r_info[entry->index];
+
+               /* Skip monsters which don't pass the restriction */
+               if ((get_mon_num_hook && !((*get_mon_num_hook)(entry->index))) ||
+                   (get_mon_num2_hook && !((*get_mon_num2_hook)(entry->index))))
+                       continue;
+
+               if (!p_ptr->inside_battle && !chameleon_change &&
+                   summon_specific_type != SUMMON_GUARDIANS)
                {
-                       /* Accept this monster */
-                       entry->prob2 = entry->prob1;
+                       /* Hack -- don't create questors */
+                       if (r_ptr->flags1 & RF1_QUESTOR)
+                               continue;
 
-                       if (dun_level && (!p_ptr->inside_quest || p_ptr->inside_quest < MIN_RANDOM_QUEST) && !restrict_monster_to_dungeon(entry->index) && !p_ptr->inside_battle)
-                       {
-                               int hoge = entry->prob2 * d_info[dungeon_type].special_div;
-                               entry->prob2 = hoge / 64;
-                               if (rand_int(64) < (hoge & 0x3f)) entry->prob2++;
-                       }
+                       if (r_ptr->flags7 & RF7_GUARDIAN)
+                               continue;
+               
+                       /* Depth Monsters never appear out of depth */
+                       if ((r_ptr->flags1 & (RF1_FORCE_DEPTH)) &&
+                           (r_ptr->level > dun_level))
+                               continue;
                }
 
-               /* Do not use this monster */
-               else
+               /* Accept this monster */
+               entry->prob2 = entry->prob1;
+
+               if (dun_level && (!p_ptr->inside_quest || p_ptr->inside_quest < MIN_RANDOM_QUEST) && !restrict_monster_to_dungeon(entry->index) && !p_ptr->inside_battle)
                {
-                       /* Decline this monster */
-                       entry->prob2 = 0;
+                       int hoge = entry->prob2 * d_info[dungeon_type].special_div;
+                       entry->prob2 = hoge / 64;
+                       if (randint0(64) < (hoge & 0x3f)) entry->prob2++;
                }
        }
 
@@ -1180,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
        {
@@ -1203,15 +1270,15 @@ s16b get_mon_num(int level)
        if ((level > 0) && !p_ptr->inside_battle && !(d_info[dungeon_type].flags1 & DF1_BEGINNER))
        {
                /* Nightmare mode allows more out-of depth monsters */
-               if (ironman_nightmare && !rand_int(pls_kakuritu))
+               if (ironman_nightmare && !randint0(pls_kakuritu))
                {
                        /* What a bizarre calculation */
-                       level = 1 + (level * MAX_DEPTH / randint(MAX_DEPTH));
+                       level = 1 + (level * MAX_DEPTH / randint1(MAX_DEPTH));
                }
                else
                {
                        /* Occasional "nasty" monster */
-                       if (!rand_int(pls_kakuritu))
+                       if (!randint0(pls_kakuritu))
                        {
                                /* Pick a level bonus */
                                int d = MIN(5, level/10) + pls_level;
@@ -1221,7 +1288,7 @@ s16b get_mon_num(int level)
                        }
 
                        /* Occasional "nasty" monster */
-                       if (!rand_int(pls_kakuritu))
+                       if (!randint0(pls_kakuritu))
                        {
                                /* Pick a level bonus */
                                int d = MIN(5, level/10) + pls_level;
@@ -1254,61 +1321,24 @@ s16b get_mon_num(int level)
                if (!p_ptr->inside_battle && !chameleon_change)
                {
                        /* Hack -- "unique" monsters must be "unique" */
-                       if (((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flags7 & (RF7_UNIQUE_7))) &&
+                       if (((r_ptr->flags1 & (RF1_UNIQUE)) ||
+                            (r_ptr->flags7 & (RF7_UNIQUE_7))) &&
                            (r_ptr->cur_num >= r_ptr->max_num))
                        {
                                continue;
                        }
 
-                       if (r_ptr->flags7 & (RF7_UNIQUE2))
-                       {
-                               int j;
-                               bool fail = FALSE;
-                               for (j = m_max -1; j >=1; j--)
-                               {
-                                       if(m_list[j].r_idx == r_idx)
-                                       {
-                                               fail = TRUE;
-                                               break;
-                                       }
-                               }
-                               if (fail) continue;
-                       }
-
-                       if (r_idx == MON_BANORLUPART)
-                       {
-                               int j;
-                               bool fail = FALSE;
-                               for (j = m_max -1; j >=1; j--)
-                               {
-                                       if((m_list[j].r_idx == MON_BANOR) ||(m_list[j].r_idx == MON_LUPART))
-                                       {
-                                               fail = TRUE;
-                                               break;
-                                       }
-                               }
-                               if (fail) continue;
-                       }
-
-                       /* Hack -- don't create questors */
-                       if (r_ptr->flags1 & RF1_QUESTOR)
-                       {
-                               continue;
-                       }
-
-                       if (r_ptr->flags7 & RF7_GUARDIAN)
+                       if ((r_ptr->flags7 & (RF7_UNIQUE2)) &&
+                           (r_ptr->cur_num >= 1))
                        {
                                continue;
                        }
 
-                       /* Depth Monsters never appear out of depth */
-                       if ((r_ptr->flags1 & (RF1_FORCE_DEPTH)) && (r_ptr->level > dun_level))
+                       if (r_idx == MON_BANORLUPART)
                        {
-                               continue;
+                               if (r_info[MON_BANOR].cur_num > 0) continue;
+                               if (r_info[MON_LUPART].cur_num > 0) continue;
                        }
-
-                       /* Some dungeon types restrict the possible monsters */
-/*                     if(!restrict_monster_to_dungeon(r_ptr) && dun_level) continue; */
                }
 
                /* Accept */
@@ -1323,7 +1353,7 @@ s16b get_mon_num(int level)
 
 
        /* Pick a monster */
-       value = rand_int(total);
+       value = randint0(total);
 
        /* Find the monster */
        for (i = 0; i < alloc_race_size; i++)
@@ -1337,7 +1367,7 @@ s16b get_mon_num(int level)
 
 
        /* Power boost */
-       p = rand_int(100);
+       p = randint0(100);
 
        /* Try for a "harder" monster once (50%) or twice (10%) */
        if (p < 60)
@@ -1346,7 +1376,7 @@ s16b get_mon_num(int level)
                j = i;
 
                /* Pick a monster */
-               value = rand_int(total);
+               value = randint0(total);
 
                /* Find the monster */
                for (i = 0; i < alloc_race_size; i++)
@@ -1369,7 +1399,7 @@ s16b get_mon_num(int level)
                j = i;
 
                /* Pick a monster */
-               value = rand_int(total);
+               value = randint0(total);
 
                /* Find the monster */
                for (i = 0; i < alloc_race_size; i++)
@@ -1429,6 +1459,8 @@ s16b get_mon_num(int level)
  *   0x20 --> Pronominalize visible monsters
  *   0x40 --> Assume the monster is hidden
  *   0x80 --> Assume the monster is visible
+ *  0x100 --> Chameleon's true name
+ *  0x200 --> Ignore hallucination, and penetrate shape change
  *
  * Useful Modes:
  *   0x00 --> Full nominative name ("the kobold") or "it"
@@ -1449,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))
        {
@@ -1460,9 +1491,9 @@ void monster_desc(char *desc, monster_type *m_ptr, int mode)
        else name = (r_name + r_ptr->name);
 
        /* Are we hallucinating? (Idea from Nethack...) */
-       if (p_ptr->image)
+       if (p_ptr->image && !(mode & 0x200))
        {
-               if (randint(2) == 1)
+               if (one_in_(2))
                {
 #ifdef JP
 if (!get_rnd_line("silly_j.txt", m_ptr->r_idx, silly_name))
@@ -1479,7 +1510,7 @@ if (!get_rnd_line("silly_j.txt", m_ptr->r_idx, silly_name))
 
                        do
                        {
-                               hallu_race = &r_info[randint(max_r_idx - 1)];
+                               hallu_race = &r_info[randint1(max_r_idx - 1)];
                        }
                        while (hallu_race->flags1 & RF1_UNIQUE);
 
@@ -1614,8 +1645,29 @@ 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)
+               if ((r_ptr->flags1 & RF1_UNIQUE) && !(p_ptr->image && !(mode & 0x200)))
                {
                        /* Start with the name (thus nominative and objective) */
                        if ((m_ptr->mflag2 & MFLAG_CHAMELEON) && !(mode & 0x100))
@@ -1659,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 */
@@ -1690,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, "¤Î");
@@ -1840,7 +1894,7 @@ void sanity_blast(monster_type *m_ptr, bool necro)
                if (is_pet(m_ptr))
                        return; /* Pet eldritch horrors are safe most of the time */
 
-               if (randint(100) > power) return;
+               if (randint1(100) > power) return;
 
                if (saving_throw(p_ptr->skill_sav - power))
                {
@@ -1856,12 +1910,12 @@ msg_format("%s%s
                        msg_format("You behold the %s visage of %s!",
 #endif
 
-                               funny_desc[rand_int(MAX_SAN_FUNNY)], m_name);
+                               funny_desc[randint0(MAX_SAN_FUNNY)], m_name);
 
-                       if (randint(3) == 1)
+                       if (one_in_(3))
                        {
-                               msg_print(funny_comments[rand_int(MAX_SAN_COMMENT)]);
-                               p_ptr->image = p_ptr->image + randint(r_ptr->level);
+                               msg_print(funny_comments[randint0(MAX_SAN_COMMENT)]);
+                               p_ptr->image = p_ptr->image + randint1(r_ptr->level);
                        }
 
                        return; /* Never mind; we can't see it clearly enough */
@@ -1874,7 +1928,7 @@ msg_format("%s%s
                msg_format("You behold the %s visage of %s!",
 #endif
 
-                       horror_desc[rand_int(MAX_SAN_HORROR)], m_name);
+                       horror_desc[randint0(MAX_SAN_HORROR)], m_name);
 
                r_ptr->r_flags2 |= RF2_ELDRITCH_HORROR;
 
@@ -1904,11 +1958,11 @@ msg_print("
        {
                if (!p_ptr->resist_conf)
                {
-                       (void)set_confused(p_ptr->confused + rand_int(4) + 4);
+                       (void)set_confused(p_ptr->confused + randint0(4) + 4);
                }
                if (!p_ptr->resist_chaos && one_in_(3))
                {
-                       (void)set_image(p_ptr->image + rand_int(250) + 150);
+                       (void)set_image(p_ptr->image + randint0(250) + 150);
                }
                return;
        }
@@ -1924,19 +1978,19 @@ msg_print("
        {
                if (!p_ptr->resist_conf)
                {
-                       (void)set_confused(p_ptr->confused + rand_int(4) + 4);
+                       (void)set_confused(p_ptr->confused + randint0(4) + 4);
                }
                if (!p_ptr->free_act)
                {
-                       (void)set_paralyzed(p_ptr->paralyzed + rand_int(4) + 4);
+                       (void)set_paralyzed(p_ptr->paralyzed + randint0(4) + 4);
                }
-               while (rand_int(100) > p_ptr->skill_sav)
+               while (randint0(100) > p_ptr->skill_sav)
                        (void)do_dec_stat(A_INT);
-               while (rand_int(100) > p_ptr->skill_sav)
+               while (randint0(100) > p_ptr->skill_sav)
                        (void)do_dec_stat(A_WIS);
                if (!p_ptr->resist_chaos)
                {
-                       (void)set_image(p_ptr->image + rand_int(250) + 150);
+                       (void)set_image(p_ptr->image + randint0(250) + 150);
                }
                return;
        }
@@ -1970,7 +2024,7 @@ msg_print("
 
        while (!happened)
        {
-               switch (randint(21))
+               switch (randint1(21))
                {
                        case 1:
                                if (!(p_ptr->muta3 & MUT3_MORONIC) && one_in_(5))
@@ -2326,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)
@@ -2430,6 +2485,35 @@ void update_monsters(bool full)
 }
 
 
+static bool monster_hook_chameleon_lord(int r_idx)
+{
+       monster_race *r_ptr = &r_info[r_idx];
+
+       if (!(r_ptr->flags1 & (RF1_UNIQUE))) return FALSE;
+       if (r_ptr->flags7 & (RF7_FRIENDLY | RF7_CHAMELEON)) return FALSE;
+
+       if (ABS(r_ptr->level - r_info[MON_CHAMELEON_K].level) > 5) return FALSE;
+
+       if ((r_ptr->blow[0].method == RBM_EXPLODE) || (r_ptr->blow[1].method == RBM_EXPLODE) || (r_ptr->blow[2].method == RBM_EXPLODE) || (r_ptr->blow[3].method == RBM_EXPLODE))
+               return FALSE;
+
+       return TRUE;
+}
+
+static bool monster_hook_chameleon(int r_idx)
+{
+       monster_race *r_ptr = &r_info[r_idx];
+
+       if (r_ptr->flags1 & (RF1_UNIQUE)) return FALSE;
+       if (r_ptr->flags2 & RF2_MULTIPLY) return FALSE;
+       if (r_ptr->flags7 & (RF7_FRIENDLY | RF7_CHAMELEON)) return FALSE;
+       
+       if ((r_ptr->blow[0].method == RBM_EXPLODE) || (r_ptr->blow[1].method == RBM_EXPLODE) || (r_ptr->blow[2].method == RBM_EXPLODE) || (r_ptr->blow[3].method == RBM_EXPLODE))
+               return FALSE;
+
+       return (*(get_monster_hook()))(r_idx);
+}
+
 
 void choose_new_monster(int m_idx, bool born, int r_idx)
 {
@@ -2441,7 +2525,8 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
        int old_r_idx = m_ptr->r_idx;
        bool old_unique = FALSE;
 
-       if (r_info[m_ptr->r_idx].flags1 & RF1_UNIQUE) old_unique = TRUE;
+       if (r_info[m_ptr->r_idx].flags1 & RF1_UNIQUE)
+               old_unique = TRUE;
        if (old_unique && (r_idx == MON_CHAMELEON)) r_idx = MON_CHAMELEON_K;
        r_ptr = &r_info[r_idx];
 
@@ -2450,23 +2535,26 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
        if (!r_idx)
        {
                chameleon_change = TRUE;
-               get_mon_num_prep(get_monster_hook(), NULL);
+               if (old_unique)
+                       get_mon_num_prep(monster_hook_chameleon_lord, NULL);
+               else
+                       get_mon_num_prep(monster_hook_chameleon, NULL);
+
                while (attempt--)
                {
                        int level;
 
-                       if (!dun_level) level = wilderness[p_ptr->wilderness_y][p_ptr->wilderness_x].level;
-                       else level = dun_level;
-                       if (d_info[dungeon_type].flags1 & DF1_CHAMELEON) level+= 2+randint(3);
+                       if (old_unique)
+                               level = r_info[MON_CHAMELEON_K].level;
+                       else if (!dun_level)
+                               level = wilderness[p_ptr->wilderness_y][p_ptr->wilderness_x].level;
+                       else
+                               level = dun_level;
+
+                       if (d_info[dungeon_type].flags1 & DF1_CHAMELEON) level+= 2+randint1(3);
                        r_idx = get_mon_num(level);
                        r_ptr = &r_info[r_idx];
-                       if ((old_unique && !(r_ptr->flags1 & RF1_UNIQUE)) || (!old_unique && (r_ptr->flags1 & RF1_UNIQUE))) continue;
-                       if (old_unique)
-                       {
-                               if (ABS(r_ptr->level - r_info[MON_CHAMELEON_K].level) > 5) continue;
-                               if ((r_ptr->blow[0].method == RBM_EXPLODE) || (r_ptr->blow[1].method == RBM_EXPLODE) || (r_ptr->blow[2].method == RBM_EXPLODE) || (r_ptr->blow[3].method == RBM_EXPLODE)) continue;
-                       }
-                       if ((r_ptr->flags2 & RF2_MULTIPLY) || (r_ptr->flags7 & (RF7_UNIQUE_7 | RF7_GUARDIAN | RF7_FRIENDLY | RF7_UNIQUE2 | RF7_CHAMELEON))) continue;
+
                        if (!monster_can_cross_terrain(cave[m_ptr->fy][m_ptr->fx].feat, r_ptr)) continue;
                        if (!born && !old_unique)
                        {
@@ -2474,10 +2562,6 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
                                if ((r_info[old_r_idx].flags3 & RF3_EVIL) && !(r_ptr->flags3 & RF3_EVIL)) continue;
                                if (!(r_info[old_r_idx].flags3 & (RF3_GOOD | RF3_EVIL)) && (r_ptr->flags3 & (RF3_GOOD | RF3_EVIL))) continue;
                        }
-                       if (born && !old_unique && summon_specific_type)
-                       {
-                               if (!summon_specific_aux(r_idx)) continue;
-                       }
                        break;
                }
                chameleon_change = FALSE;
@@ -2485,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;
@@ -2510,7 +2595,7 @@ void choose_new_monster(int m_idx, bool born, int r_idx)
        m_ptr->mspeed = r_ptr->speed;
        /* Hack -- small racial variety */
        /* Allow some small variation per monster */
-       if(rand_int(4) == 1){
+       if(one_in_(4)){
                i = extract_energy[r_ptr->speed] / 3;
                if (i) m_ptr->mspeed += rand_spread(0, i);
        }
@@ -2533,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.
@@ -2553,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;
@@ -2604,51 +2711,34 @@ bool place_monster_one(int y, int x, int r_idx, bool slp, bool friendly, bool pe
 
        if (!p_ptr->inside_battle)
        {
-       /* Hack -- "unique" monsters must be "unique" */
-       if (((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flags7 & (RF7_UNIQUE_7))) &&
-                (r_ptr->cur_num >= r_ptr->max_num))
-       {
-               /* Cannot create */
-               return (FALSE);
-       }
-
-       if (r_ptr->flags7 & (RF7_UNIQUE2))
-       {
-               int j;
-               bool fail = FALSE;
-               for (j = m_max -1; j >=1; j--)
+               /* Hack -- "unique" monsters must be "unique" */
+               if (((r_ptr->flags1 & (RF1_UNIQUE)) ||
+                    (r_ptr->flags7 & (RF7_UNIQUE_7))) &&
+                   (r_ptr->cur_num >= r_ptr->max_num))
                {
-                       if(m_list[j].r_idx == r_idx)
-                       {
-                               fail = TRUE;
-                               break;
-                       }
+                       /* Cannot create */
+                       return (FALSE);
                }
-               if (fail) return (FALSE);
-       }
-
-       if (r_idx == MON_BANORLUPART)
-       {
-               int j;
-               bool fail = FALSE;
-               for (j = m_max -1; j >=1; j--)
+               
+               if ((r_ptr->flags7 & (RF7_UNIQUE2)) &&
+                   (r_ptr->cur_num >= 1))
                {
-                       if((m_list[j].r_idx == MON_BANOR) ||(m_list[j].r_idx == MON_LUPART))
-                       {
-                               fail = TRUE;
-                               break;
-                       }
+                       return (FALSE);
                }
-               if (fail) return (FALSE);
-       }
 
-       /* Depth monsters may NOT be created out of depth, unless in Nightmare mode */
-       if ((r_ptr->flags1 & (RF1_FORCE_DEPTH)) && (dun_level < r_ptr->level) &&
-                (!ironman_nightmare || (r_ptr->flags1 & (RF1_QUESTOR))))
-       {
-               /* Cannot create */
-               return (FALSE);
-       }
+               if (r_idx == MON_BANORLUPART)
+               {
+                       if (r_info[MON_BANOR].cur_num > 0) return FALSE;
+                       if (r_info[MON_LUPART].cur_num > 0) return FALSE;
+               }
+               
+               /* Depth monsters may NOT be created out of depth, unless in Nightmare mode */
+               if ((r_ptr->flags1 & (RF1_FORCE_DEPTH)) && (dun_level < r_ptr->level) &&
+                   (!ironman_nightmare || (r_ptr->flags1 & (RF1_QUESTOR))))
+               {
+                       /* Cannot create */
+                       return (FALSE);
+               }
        }
 
        if(quest_number(dun_level))
@@ -2678,7 +2768,7 @@ bool place_monster_one(int y, int x, int r_idx, bool slp, bool friendly, bool pe
 
        if (c_ptr->feat == FEAT_GLYPH)
        {
-               if (randint(BREAK_GLYPH) < (r_ptr->level+20))
+               if (randint1(BREAK_GLYPH) < (r_ptr->level+20))
                {
                        /* Describe observable breakage */
                        if (c_ptr->info & CAVE_MARK)
@@ -2695,9 +2785,7 @@ msg_print("
                        c_ptr->info &= ~(CAVE_MARK);
 
                        /* Break the rune */
-                       c_ptr->feat = floor_type[rand_int(100)];
-                       c_ptr->info &= ~(CAVE_MASK);
-                       c_ptr->info |= CAVE_FLOOR;
+                       c_ptr->feat = floor_type[randint0(100)];
 
                        /* Notice */
                        note_spot(y, x);
@@ -2767,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;
@@ -2781,8 +2880,7 @@ msg_print("
        /* Unknown distance */
        m_ptr->cdis = 0;
 
-       m_ptr->target_y = 0;
-       m_ptr->target_x = 0;
+       reset_target(m_ptr);
 
        m_ptr->nickname = 0;
 
@@ -2799,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 */
@@ -2825,7 +2928,7 @@ msg_print("
        if (slp && r_ptr->sleep && !ironman_nightmare)
        {
                int val = r_ptr->sleep;
-               m_ptr->csleep = ((val * 2) + randint(val * 10));
+               m_ptr->csleep = ((val * 2) + randint1(val * 10));
        }
 
        /* Assign maximal hitpoints */
@@ -2861,7 +2964,7 @@ msg_print("
        if (!(r_ptr->flags1 & RF1_UNIQUE) && !p_ptr->inside_arena)
        {
                /* Allow some small variation per monster */
-         if(rand_int(4) == 1){
+         if(one_in_(4)){
                i = extract_energy[r_ptr->speed] / 3;
                if (i) m_ptr->mspeed += rand_spread(0, i);
          }
@@ -2871,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)rand_int(100);
-
-       /* Nightmare monsters are more prepared */
-       if (ironman_nightmare)
+       if (!ironman_nightmare)
        {
-               m_ptr->energy *= 2;
+               m_ptr->energy_need = ENERGY_NEED() - (s16b)randint0(100);
+       }
+       else
+       {
+               /* 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 */
@@ -2905,7 +3012,10 @@ msg_print("
 
 
        /* Hack -- Count the monsters on the level */
-       r_ptr->cur_num++;
+       if (m_ptr->mflag2 & MFLAG_CHAMELEON)
+               r_info[r_idx].cur_num++;
+       else
+               r_ptr->cur_num++;
 
 
        /* Hack -- Count the number of "reproducers" */
@@ -2917,9 +3027,12 @@ msg_print("
 
        if (p_ptr->warning && character_dungeon)
        {
-               cptr color;
                if (r_ptr->flags1 & RF1_UNIQUE)
                {
+                       cptr color;
+                       object_type *o_ptr;
+                       char o_name[MAX_NLEN];
+
                        if (r_ptr->level > p_ptr->lev + 30)
 #ifdef JP
                                color = "¹õ¤¯";
@@ -2956,10 +3069,13 @@ msg_print("
 #else
                                color = "white";
 #endif
+
+                       o_ptr = choose_warning_item();
+                       object_desc(o_name, o_ptr, FALSE, 0);
 #ifdef JP
-                       msg_format("»ØÎؤÏ%s¸÷¤Ã¤¿¡£",color);
+                       msg_format("%s¤Ï%s¸÷¤Ã¤¿¡£",o_name, color);
 #else
-                       msg_format("Your ring glows %s.",color);
+                       msg_format("%s glows %s.",o_name, color);
 #endif
                }
        }
@@ -2967,7 +3083,7 @@ msg_print("
        if (c_ptr->feat == FEAT_MINOR_GLYPH)
        {
                /* Break the ward */
-               if (randint(BREAK_MINOR_GLYPH) > r_ptr->level)
+               if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level)
                {
                        /* Describe observable breakage */
                        if (c_ptr->info & CAVE_MARK)
@@ -2994,9 +3110,7 @@ msg_print("
                c_ptr->info &= ~(CAVE_MARK);
 
                /* Break the rune */
-               c_ptr->feat = floor_type[rand_int(100)];
-               c_ptr->info &= ~(CAVE_MASK);
-               c_ptr->info |= CAVE_FLOOR;
+               c_ptr->feat = floor_type[randint0(100)];
                note_spot(y, x);
                lite_spot(y, x);
        }
@@ -3089,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];
 
@@ -3103,20 +3217,20 @@ static bool place_monster_group(int y, int x, int r_idx, bool slp, bool friendly
 
 
        /* Pick a group size */
-       total = randint(10);
+       total = randint1(10);
 
        /* Hard monsters, small groups */
        if (r_ptr->level > dun_level)
        {
                extra = r_ptr->level - dun_level;
-               extra = 0 - randint(extra);
+               extra = 0 - randint1(extra);
        }
 
        /* Easy monsters, large groups */
        else if (r_ptr->level < dun_level)
        {
                extra = dun_level - r_ptr->level;
-               extra = randint(extra);
+               extra = randint1(extra);
        }
 
        /* Hack -- limit group reduction */
@@ -3158,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;
@@ -3181,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
@@ -3188,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];
 
@@ -3206,6 +3322,21 @@ static bool place_monster_okay(int r_idx)
        /* Paranoia -- Skip identical monsters */
        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 (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 ((r_ptr->flags7 & RF7_CHAMELEON) && !(z_ptr->flags7 & RF7_CHAMELEON))
+               return FALSE;
+
        /* Okay */
        return (TRUE);
 }
@@ -3229,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];
@@ -3238,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);
        }
 
 
@@ -3279,31 +3411,15 @@ bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp, bool friendl
                        /* Handle failure */
                        if (!z) break;
 
-                       if (((r_ptr->flags3 & RF3_EVIL) && (r_info[z].flags3 & RF3_GOOD)) || ((r_ptr->flags3 & RF3_GOOD) && (r_info[z].flags3 & RF3_EVIL)))
-                       {
-                               i--;
-                               continue;
-                       }
-
-                       if (r_ptr->flags7 & RF7_FRIENDLY)
-                       {
-                               if (((p_ptr->align < 0) && (r_info[z].flags3 & RF3_GOOD)) ||
-                                        ((p_ptr->align > 0) && (r_info[z].flags3 & RF3_EVIL)))
-                               {
-                                       i--;
-                                       continue;
-                               }
-                       }
-
                        /* 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);
                        }
                }
        }
@@ -3332,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);
@@ -3378,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;}
@@ -3388,7 +3504,7 @@ bool alloc_horde(int y, int x)
        if (m_list[m_idx].mflag2 & MFLAG_CHAMELEON) r_ptr = &r_info[m_list[m_idx].r_idx];
        summon_kin_type = r_ptr->d_char;
 
-       for (attempts = randint(10) + 5; attempts; attempts--)
+       for (attempts = randint1(10) + 5; attempts; attempts--)
        {
                scatter(&cy, &cx, y, x, 5, 0);
 
@@ -3419,13 +3535,40 @@ bool alloc_monster(int dis, bool slp)
 {
        int                     y = 0, x = 0;
        int         attempts_left = 10000;
+       int guardian = d_info[dungeon_type].final_guardian;
+
+        /* Put an Guardian */
+        if(guardian && d_info[dungeon_type].maxdepth == dun_level && r_info[guardian].cur_num < r_info[guardian].max_num )
+        {
+                int oy;
+                int ox;
+                int try = 4000;
+
+                /* Find a good position */
+                while(try)
+                {
+                        /* Get a random spot */
+                        oy = randint1(cur_hgt - 4) + 2;
+                        ox = randint1(cur_wid - 4) + 2;
+
+                        /* Is it a good spot ? */
+                        if (cave_empty_bold2(oy, ox) && monster_can_cross_terrain(cave[oy][ox].feat, &r_info[guardian]))
+                       {
+                               /* Place the guardian */
+                               if (place_monster_aux(0, oy, ox, guardian, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE)) break;
+                       }
+                        /* One less try */
+                        try--;
+                }
+       }
+
 
        /* Find a legal, distant, unoccupied, space */
        while (attempts_left--)
        {
                /* Pick a location */
-               y = rand_int(cur_hgt);
-               x = rand_int(cur_wid);
+               y = randint0(cur_hgt);
+               x = randint0(cur_wid);
 
                /* Require empty floor grid (was "naked") */
                if (dun_level || (wilderness[p_ptr->wilderness_y][p_ptr->wilderness_x].terrain != TERRAIN_MOUNTAIN))
@@ -3458,7 +3601,7 @@ msg_print("
 
 
 #ifdef MONSTER_HORDES
-       if (randint(5000) <= dun_level)
+       if (randint1(5000) <= dun_level)
        {
                if (alloc_horde(y, x))
                {
@@ -3503,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;
                }
@@ -3528,11 +3670,11 @@ static bool summon_specific_okay(int r_idx)
                /* 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;
+                       if (!one_in_((0-p_ptr->align)/2+1)) return FALSE;
                }
                else if ((p_ptr->align > 9) && (r_ptr->flags3 & RF3_EVIL))
                {
-                       if (!(one_in_(p_ptr->align/2+1))) return FALSE;
+                       if (!one_in_(p_ptr->align/2+1)) return FALSE;
                }
        }
 
@@ -3617,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);
@@ -3629,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;
 
@@ -3644,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);
 }
 
 
@@ -3663,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)
@@ -4409,7 +4551,7 @@ void update_smart_learn(int m_idx, int what)
        if (r_ptr->flags2 & (RF2_STUPID)) return;
 
        /* Not intelligent, only learn sometimes */
-       if (!(r_ptr->flags2 & (RF2_SMART)) && (rand_int(100) < 50)) return;
+       if (!(r_ptr->flags2 & (RF2_SMART)) && (randint0(100) < 50)) return;
 
 
        /* XXX XXX XXX */