};
-int get_wilderness_flag(void)
+/*
+ * Set the target of counter attack
+ */
+void set_target(monster_type *m_ptr, int y, int x)
{
- int x = p_ptr->wilderness_x;
- int y = p_ptr->wilderness_y;
-
- if (dun_level)
- return (RF8_DUNGEON);
- else
- return (1L << wilderness[y][x].terrain);
+ 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.
/* 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--;
/* Count monsters */
m_cnt--;
-#ifdef USE_SCRIPT
- delete_monster_callback(i);
-#endif /* USE_SCRIPT */
-
/* Visual update */
lite_spot(y, x);
}
/* Wipe the hole */
(void)WIPE(&m_list[i1], monster_type);
-#ifdef USE_SCRIPT
- copy_monster_callback(i1, i2);
-#endif /* USE_SCRIPT */
-
}
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);
{
int i;
+ /* Hack -- if Banor or Lupart dies, stay another dead */
+ if (!r_info[MON_BANORLUPART].max_num)
+ {
+ if (r_info[MON_BANOR].max_num)
+ {
+ r_info[MON_BANOR].max_num = 0;
+ r_info[MON_BANOR].r_pkills++;
+ if (r_info[MON_BANOR].r_tkills < MAX_SHORT) r_info[MON_BANOR].r_tkills++;
+ }
+ if (r_info[MON_LUPART].max_num)
+ {
+ r_info[MON_LUPART].max_num = 0;
+ r_info[MON_LUPART].r_pkills++;
+ if (r_info[MON_LUPART].r_tkills < MAX_SHORT) r_info[MON_LUPART].r_tkills++;
+ }
+ }
+
/* Delete all the monsters */
for (i = m_max - 1; i >= 1; i--)
{
/* 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;
/* Wipe the Monster */
(void)WIPE(m_ptr, monster_type);
-#ifdef USE_SCRIPT
- delete_monster_callback(i);
-#endif /* USE_SCRIPT */
}
/* Reset "m_max" */
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)
okay = (r_idx == MON_LOUSE);
break;
}
+
+ case SUMMON_GUARDIANS:
+ {
+ okay = (r_ptr->flags7 & RF7_GUARDIAN);
+ break;
+ }
}
/* Result */
- return (okay);
+ /* Since okay is int, "return (okay);" is not correct. */
+ return (bool)(okay ? TRUE : FALSE);
}
/* 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++;
}
}
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
{
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;
}
/* Occasional "nasty" monster */
- if (!rand_int(pls_kakuritu))
+ if (!randint0(pls_kakuritu))
{
/* Pick a level bonus */
int d = MIN(5, level/10) + pls_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)
+ if ((r_ptr->flags7 & (RF7_UNIQUE2)) &&
+ (r_ptr->cur_num >= 1))
{
continue;
}
- 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))
+ 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 */
/* Pick a monster */
- value = rand_int(total);
+ value = randint0(total);
/* Find the monster */
for (i = 0; i < alloc_race_size; i++)
/* Power boost */
- p = rand_int(100);
+ p = randint0(100);
/* Try for a "harder" monster once (50%) or twice (10%) */
if (p < 60)
j = i;
/* Pick a monster */
- value = rand_int(total);
+ value = randint0(total);
/* Find the monster */
for (i = 0; i < alloc_race_size; i++)
j = i;
/* Pick a monster */
- value = rand_int(total);
+ value = randint0(total);
/* Find the monster */
for (i = 0; i < alloc_race_size; i++)
* 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"
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))
{
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))
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);
/* 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))
#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 (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))
{
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 */
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;
{
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;
}
{
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;
}
while (!happened)
{
- switch (randint(21))
+ switch (randint1(21))
{
case 1:
if (!(p_ptr->muta3 & MUT3_MORONIC) && one_in_(5))
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)
}
+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)
{
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];
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)
{
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;
}
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;
if (m_idx == p_ptr->riding)
{
+ char m_name[80];
+ monster_desc(m_name, m_ptr, 0);
+#ifdef JP
msg_format("ÆÍÁ³%s¤¬ÊѿȤ·¤¿¡£", old_m_name);
+#else
+ msg_format("Suddenly, %s transforms!", old_m_name);
+#endif
if (!(r_ptr->flags7 & RF7_RIDING))
+#ifdef JP
if (rakuba(0, TRUE)) msg_print("ÃÏÌ̤ËÍî¤È¤µ¤ì¤¿¡£");
+#else
+ if (rakuba(0, TRUE)) msg_format("You have fallen from %s.", m_name);
+#endif
}
/* Extract the monster base speed */
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);
}
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.
bool place_monster_one(int y, int x, int r_idx, bool slp, bool friendly, bool pet, bool no_pet)
{
int i;
+ int rune_dam = 0;
cave_type *c_ptr;
!(cave_perma_bold(y, x) || cave[y][x].m_idx ||
((y == py) && (x == px))))) return (FALSE);
+ /* Paranoia */
+ if (!r_idx) return (FALSE);
+
+ /* Paranoia */
+ if (!r_ptr->name) return (FALSE);
+
+#if 0
/* Hack -- no creation on glyph of warding */
if (cave[y][x].feat == FEAT_GLYPH) return (FALSE);
if (cave[y][x].feat == FEAT_MINOR_GLYPH) return (FALSE);
+#endif
/* Nor on the Pattern */
if ((cave[y][x].feat >= FEAT_PATTERN_START)
&& (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
return (FALSE);
- /* Paranoia */
- if (!r_idx) return (FALSE);
-
- /* Paranoia */
- if (!r_ptr->name) return (FALSE);
-
if (monster_terrain_sensitive &&
!monster_can_cross_terrain(cave[y][x].feat, r_ptr))
{
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))
}
}
+ /* Access the location */
+ c_ptr = &cave[y][x];
+
+ if (c_ptr->feat == FEAT_GLYPH)
+ {
+ if (randint1(BREAK_GLYPH) < (r_ptr->level+20))
+ {
+ /* Describe observable breakage */
+ if (c_ptr->info & CAVE_MARK)
+ {
+#ifdef JP
+msg_print("¼é¤ê¤Î¥ë¡¼¥ó¤¬²õ¤ì¤¿¡ª");
+#else
+ msg_print("The rune of protection is broken!");
+#endif
+
+ }
+
+ /* Forget the rune */
+ c_ptr->info &= ~(CAVE_MARK);
+
+ /* 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);
+ rune_dam = 1000;
+ }
+ else return FALSE;
+ }
+
/* Powerful monster */
if (r_ptr->level > dun_level)
{
if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7) || (r_ptr->level < 10)) is_kage = FALSE;
- /* Access the location */
- c_ptr = &cave[y][x];
-
/* Make a new monster */
c_ptr->m_idx = m_pop();
hack_m_idx_ii = c_ptr->m_idx;
/* Save the race */
m_ptr->r_idx = r_idx;
+ m_ptr->ap_r_idx = initial_r_appearance(r_idx);
/* Place the monster at the location */
m_ptr->fy = y;
/* Unknown distance */
m_ptr->cdis = 0;
- m_ptr->target_y = 0;
- m_ptr->target_x = 0;
+ reset_target(m_ptr);
m_ptr->nickname = 0;
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 (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 */
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);
}
if (m_ptr->mspeed > 199) m_ptr->mspeed = 199;
/* Give a random starting energy */
- m_ptr->energy = (byte)rand_int(100);
+ m_ptr->energy = (byte)randint0(100);
/* Nightmare monsters are more prepared */
if (ironman_nightmare)
/* 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" */
/* Hack -- Notice new multi-hued monsters */
if (r_ptr->flags1 & RF1_ATTR_MULTI) shimmer_monsters = TRUE;
-#ifdef USE_SCRIPT
- create_monster_callback(c_ptr->m_idx);
-#endif /* USE_SCRIPT */
-
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 = "¹õ¤¯";
#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
}
}
+ if (c_ptr->feat == FEAT_MINOR_GLYPH)
+ {
+ /* Break the ward */
+ if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level)
+ {
+ /* Describe observable breakage */
+ if (c_ptr->info & CAVE_MARK)
+ {
+#ifdef JP
+msg_print("¥ë¡¼¥ó¤¬Çúȯ¤·¤¿¡ª");
+#else
+ msg_print("The rune explodes!");
+#endif
+
+ project(0, 2, y, x, 2 * (p_ptr->lev + damroll(7, 7)), GF_MANA, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_REF | PROJECT_NO_HANGEKI), -1);
+ }
+ }
+ else
+ {
+#ifdef JP
+msg_print("Çúȯ¤Î¥ë¡¼¥ó¤Ï²ò½ü¤µ¤ì¤¿¡£");
+#else
+ msg_print("An explosive rune was disarmed.");
+#endif
+ }
+
+ /* Forget the rune */
+ c_ptr->info &= ~(CAVE_MARK);
+
+ /* 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);
+ }
+
/* Success */
return (TRUE);
}
if (cave[ny][nx].m_idx) continue;
if ((ny == py) && (nx == px)) continue;
+#if 0
/* Hack -- no summon on glyph of warding */
if (cave[ny][nx].feat == FEAT_GLYPH) continue;
if (cave[ny][nx].feat == FEAT_MINOR_GLYPH) continue;
+#endif
/* ... nor on the Pattern */
if ((cave[ny][nx].feat >= FEAT_PATTERN_START) &&
/* 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 */
/* Paranoia -- Skip identical monsters */
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)))
+ 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);
}
/* 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);
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);
{
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(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))
#ifdef MONSTER_HORDES
- if (randint(5000) <= dun_level)
+ if (randint1(5000) <= dun_level)
{
if (alloc_horde(y, x))
{
/* 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;
}
}
return FALSE;
/* Create a new monster (awake, no groups) */
- if (!place_monster_aux(y, x, m_ptr->r_idx, FALSE, FALSE, friendly, pet, TRUE, (m_ptr->mflag2 & MFLAG_NOPET)))
+ if (!place_monster_aux(y, x, m_ptr->r_idx, FALSE, FALSE, friendly, pet, TRUE, (bool)(m_ptr->mflag2 & MFLAG_NOPET)))
return FALSE;
if (clone)
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 */