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 */
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
{
* 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"
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))
{
/* 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)))
{
#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 */
#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, "¤Î");
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)
}
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;
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.
* 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;
/* 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);
/* 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;
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 */
}
}
+ 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 */
/* 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);
}
/*
* 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];
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;
* 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
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];
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)
* 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];
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);
}
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);
}
}
}
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);
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;}
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--;
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;
}
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);
}
/* 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;
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);
}
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)