#define HORDE_NOGOOD 0x01
#define HORDE_NOEVIL 0x02
-bool is_kage = FALSE;
-
cptr horror_desc[MAX_SAN_HORROR] =
{
#ifdef JP
/* Acquire next object */
next_o_idx = o_ptr->next_o_idx;
- /* Hack -- efficiency */
- o_ptr->held_m_idx = 0;
+ /*
+ * o_ptr->held_m_idx is needed in delete_object_idx()
+ * to prevent calling lite_spot()
+ */
/* Delete the object */
delete_object_idx(this_o_idx);
lite_spot(y, x);
/* Update some things */
- p_ptr->update |= (PU_MON_LITE);
+ if (r_ptr->flags7 & (RF7_LITE_MASK | RF7_DARK_MASK))
+ p_ptr->update |= (PU_MON_LITE);
}
*/
static void compact_monsters_aux(int i1, int i2)
{
- int y, x;
+ int y, x, i;
cave_type *c_ptr;
/* Hack -- Update the health bar */
if (p_ptr->health_who == i1) health_track(i2);
+ /* Hack -- Update parent index */
+ if (is_pet(m_ptr))
+ {
+ for (i = 1; i < m_max; i++)
+ {
+ monster_type *m2_ptr = &m_list[i];
+
+ if (m2_ptr->parent_m_idx == i1)
+ m2_ptr->parent_m_idx = i2;
+ }
+ }
+
/* Structure copy */
COPY(&m_list[i2], &m_list[i1], monster_type);
/*
- * Pre-calculate the racial counters of preserved pets
- * To prevent multiple generation of unique monster who is the minion of player
- */
-void precalc_cur_num_of_pet(void)
-{
- monster_type *m_ptr;
- int i;
- int max_num = p_ptr->wild_mode ? 1 : MAX_PARTY_MON;
-
- for (i = 0; i < max_num; i++)
- {
- m_ptr = &party_mon[i];
-
- /* Skip empty monsters */
- if (!m_ptr->r_idx) continue;
-
- /* Hack -- Increase the racial counter */
- real_r_ptr(m_ptr)->cur_num++;
- }
-}
-
-
-/*
* Delete/Remove all the monsters when the player leaves the level
*
* This is an efficient method of simulating multiple calls to the
/* Hack -- Wipe the racial counter of all monster races */
for (i = 1; i < max_r_idx; i++) r_info[i].cur_num = 0;
- /* Hack -- Increase the racial counters of pets */
- precalc_cur_num_of_pet();
-
/* Reset "m_max" */
m_max = 1;
static int summon_specific_who = -1;
-/*
- * Hack -- the hostility of the summoned monster
- */
-static bool summon_specific_hostile = TRUE;
-
static bool summon_unique_okay = FALSE;
case SUMMON_ANIMAL_RANGER:
{
okay = ((r_ptr->flags3 & (RF3_ANIMAL)) &&
- (strchr("abcflqrwBCHIJKMRS", r_ptr->d_char)) &&
+ (my_strchr("abcflqrwBCHIJKMRS", r_ptr->d_char)) &&
!(r_ptr->flags3 & (RF3_DRAGON)) &&
!(r_ptr->flags3 & (RF3_EVIL)) &&
!(r_ptr->flags3 & (RF3_UNDEAD)) &&
{
/* Hack -- "unique" monsters must be "unique" */
if (((r_ptr->flags1 & (RF1_UNIQUE)) ||
- (r_ptr->flags7 & (RF7_UNIQUE_7))) &&
+ (r_ptr->flags7 & (RF7_NAZGUL))) &&
(r_ptr->cur_num >= r_ptr->max_num))
{
continue;
* MD_ASSUME_VISIBLE --> Assume the monster is visible
* MD_TRUE_NAME --> Chameleon's true name
* MD_IGNORE_HALLU --> Ignore hallucination, and penetrate shape change
- * MD_ASSUME_OUTSIDE --> Assume this monster pet waiting outside the floor
*
* Useful Modes:
* 0x00 --> Full nominative name ("the kobold") or "it"
strcat(desc, format("(%s)", r_name + r_info[m_ptr->r_idx].name));
}
- if (mode & MD_ASSUME_OUTSIDE)
- {
-#ifdef JP
- strcat(desc,"(ÂÔµ¡Ãæ)");
-#else
- strcat(desc,"(waiting)");
-#endif
- }
-
/* Handle the Possessive as a special afterthought */
if (mode & MD_POSSESSIVE)
{
/* Not born */
if (!(old_r_ptr->flags7 & RF7_CHAMELEON))
{
- if ((m_ptr->sub_align & SUB_ALIGN_EVIL) && (r_ptr->flags3 & RF3_GOOD)) return FALSE;
- if ((m_ptr->sub_align & SUB_ALIGN_GOOD) && (r_ptr->flags3 & RF3_EVIL)) return FALSE;
+ if (monster_has_hostile_align(m_ptr, 0, 0, r_ptr)) return FALSE;
}
/* Born now */
else if (summon_specific_who > 0)
{
- monster_type *sm_ptr = &m_list[summon_specific_who];
-
- if ((sm_ptr->sub_align & SUB_ALIGN_EVIL) && (r_ptr->flags3 & RF3_GOOD)) return FALSE;
- if ((sm_ptr->sub_align & SUB_ALIGN_GOOD) && (r_ptr->flags3 & RF3_EVIL)) return FALSE;
+ if (monster_has_hostile_align(&m_list[summon_specific_who], 0, 0, r_ptr)) return FALSE;
}
return TRUE;
/* Born now */
else if (summon_specific_who > 0)
{
- monster_type *sm_ptr = &m_list[summon_specific_who];
-
- if ((sm_ptr->sub_align & SUB_ALIGN_EVIL) && (r_ptr->flags3 & RF3_GOOD)) return FALSE;
- if ((sm_ptr->sub_align & SUB_ALIGN_GOOD) && (r_ptr->flags3 & RF3_EVIL)) return FALSE;
+ if (monster_has_hostile_align(&m_list[summon_specific_who], 0, 0, r_ptr)) return FALSE;
}
return (*(get_monster_hook()))(r_idx);
* This is the only function which may place a monster in the dungeon,
* except for the savefile loading code.
*/
-bool place_monster_one(int who, int y, int x, int r_idx, u32b mode)
+static bool place_monster_one(int who, int y, int x, int r_idx, u32b mode)
{
- cave_type *c_ptr;
+ /* Access the location */
+ cave_type *c_ptr = &cave[y][x];
monster_type *m_ptr;
if (!in_bounds(y, x)) return (FALSE);
/* Require empty space (if not ghostly) */
- if (!(!dun_level && (cave[y][x].feat == FEAT_MOUNTAIN) && ((r_ptr->flags8 & RF8_WILD_MOUNTAIN) || (r_ptr->flags7 & RF7_CAN_FLY))) &&
+ if (!(!dun_level && (c_ptr->feat == FEAT_MOUNTAIN) && ((r_ptr->flags8 & RF8_WILD_MOUNTAIN) || (r_ptr->flags7 & RF7_CAN_FLY))) &&
!(cave_empty_bold2(y, x) || (mode & PM_IGNORE_TERRAIN)) &&
!((r_ptr->flags2 & RF2_PASS_WALL) &&
- !(cave_perma_bold(y, x) || cave[y][x].m_idx ||
+ !(cave_perma_bold(y, x) || c_ptr->m_idx ||
player_bold(y, x)))) return (FALSE);
/* Paranoia */
if (!r_ptr->name) return (FALSE);
/* Nor on the Pattern */
- if ((cave[y][x].feat >= FEAT_PATTERN_START)
- && (cave[y][x].feat <= FEAT_PATTERN_XTRA2))
+ if ((c_ptr->feat >= FEAT_PATTERN_START)
+ && (c_ptr->feat <= FEAT_PATTERN_XTRA2))
return (FALSE);
if (!(mode & PM_IGNORE_TERRAIN) &&
- !monster_can_cross_terrain(cave[y][x].feat, r_ptr))
+ !monster_can_cross_terrain(c_ptr->feat, r_ptr))
{
return FALSE;
}
{
/* Hack -- "unique" monsters must be "unique" */
if (((r_ptr->flags1 & (RF1_UNIQUE)) ||
- (r_ptr->flags7 & (RF7_UNIQUE_7))) &&
+ (r_ptr->flags7 & (RF7_NAZGUL))) &&
(r_ptr->cur_num >= r_ptr->max_num))
{
/* Cannot create */
}
}
- /* Access the location */
- c_ptr = &cave[y][x];
-
if (is_glyph_grid(c_ptr))
{
if (randint1(BREAK_GLYPH) < (r_ptr->level+20))
}
- if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7) || (r_ptr->level < 10)) is_kage = FALSE;
+ if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL) || (r_ptr->level < 10)) mode &= ~PM_KAGE;
/* Make a new monster */
c_ptr->m_idx = m_pop();
m_ptr->mflag = 0;
m_ptr->mflag2 = 0;
+
+ /* Your pet summons its pet. */
+ if (who > 0 && is_pet(&m_list[who]))
+ {
+ mode |= PM_FORCE_PET;
+ m_ptr->parent_m_idx = who;
+ }
+ else
+ {
+ m_ptr->parent_m_idx = 0;
+ }
+
if (r_ptr->flags7 & RF7_CHAMELEON)
{
choose_new_monster(c_ptr->m_idx, TRUE, 0);
if ((r_ptr->flags1 & RF1_UNIQUE) && (who <= 0))
m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
}
- else if (is_kage)
+ else if ((mode & PM_KAGE) && !(mode & PM_FORCE_PET))
{
m_ptr->ap_r_idx = MON_KAGE;
m_ptr->mflag2 |= MFLAG2_KAGE;
else if ((r_ptr->flags7 & RF7_FRIENDLY) ||
(mode & PM_FORCE_FRIENDLY) || is_friendly_idx(who))
{
- if (!(p_ptr->align >= 0 && (r_ptr->flags3 & RF3_EVIL)) &&
- !(p_ptr->align < 0 && (r_ptr->flags3 & RF3_GOOD)))
- {
- set_friendly(m_ptr);
- }
+ if (!monster_has_hostile_align(NULL, 0, -1, r_ptr)) set_friendly(m_ptr);
}
/* Assume no sleeping */
* A unique monster move from old saved floor.
*/
if (character_dungeon &&
- ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)))
+ ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)))
real_r_ptr(m_ptr)->floor_id = p_ptr->floor_id;
/* Hack -- Count the number of "reproducers" */
#endif
o_ptr = choose_warning_item();
- object_desc(o_name, o_ptr, FALSE, 0);
+ if (o_ptr)
+ {
+ object_desc(o_name, o_ptr, FALSE, 0);
#ifdef JP
- msg_format("%s¤Ï%s¸÷¤Ã¤¿¡£",o_name, color);
+ msg_format("%s¤Ï%s¸÷¤Ã¤¿¡£", o_name, color);
#else
- msg_format("%s glows %s.",o_name, color);
+ msg_format("%s glows %s.", o_name, color);
#endif
+ }
+ else
+ {
+#ifdef JP
+ msg_format("s%¸÷¤ëʪ¤¬Æ¬¤ËÉ⤫¤ó¤À¡£", color);
+#else
+ msg_format("An %s image forms in your mind.");
+#endif
+ }
}
}
/* Walls and Monsters block flow */
if (!cave_empty_bold2(ny, nx)) continue;
- if (cave[ny][nx].m_idx) continue;
- if (player_bold(ny, nx)) continue;
/* ... nor on the Pattern */
if ((cave[ny][nx].feat >= FEAT_PATTERN_START) &&
monster_race *z_ptr = &r_info[r_idx];
/* Hack - Escorts have to have the same dungeon flag */
- if (monster_dungeon(place_monster_idx) != monster_dungeon(r_idx)) return (FALSE);
+ if (mon_hook_dungeon(place_monster_idx) != mon_hook_dungeon(r_idx)) return (FALSE);
/* Require similar "race" */
if (z_ptr->d_char != r_ptr->d_char) return (FALSE);
if (place_monster_idx == r_idx) return (FALSE);
/* Skip different alignment */
- if (((m_ptr->sub_align & SUB_ALIGN_EVIL) && (z_ptr->flags3 & RF3_GOOD)) ||
- ((m_ptr->sub_align & SUB_ALIGN_GOOD) && (z_ptr->flags3 & RF3_EVIL)))
- return FALSE;
+ if (monster_has_hostile_align(m_ptr, 0, 0, z_ptr)) return FALSE;
if (r_ptr->flags7 & RF7_FRIENDLY)
{
- if (((p_ptr->align < 0) && (z_ptr->flags3 & RF3_GOOD)) ||
- ((p_ptr->align > 0) && (z_ptr->flags3 & RF3_EVIL)))
- return FALSE;
+ if (monster_has_hostile_align(NULL, 1, -1, z_ptr)) return FALSE;
}
if ((r_ptr->flags7 & RF7_CHAMELEON) && !(z_ptr->flags7 & RF7_CHAMELEON))
int i;
monster_race *r_ptr = &r_info[r_idx];
- if (one_in_(333) && !(mode & PM_NO_KAGE) && !(mode & PM_FORCE_PET))
- is_kage = TRUE;
- else
- is_kage = FALSE;
+ if (!(mode & PM_NO_KAGE) && one_in_(333))
+ mode |= PM_KAGE;
/* Place one monster, or fail */
if (!place_monster_one(who, y, x, r_idx, mode)) return (FALSE);
monster_race *r_ptr = &r_info[r_idx];
/* Hack - Only summon dungeon monsters */
- if (!monster_dungeon(r_idx)) return (FALSE);
+ if (!mon_hook_dungeon(r_idx)) return (FALSE);
/* Hack -- identify the summoning monster */
if (summon_specific_who > 0)
/* Do not summon enemies */
/* Friendly vs. opposite aligned normal or pet */
- if (((r_ptr->flags3 & RF3_EVIL) &&
- (m_ptr->sub_align & SUB_ALIGN_GOOD)) ||
- ((r_ptr->flags3 & RF3_GOOD) &&
- (m_ptr->sub_align & SUB_ALIGN_EVIL)))
- {
- return FALSE;
- }
-
- /* Hostile vs. non-hostile */
- if (is_hostile(m_ptr) != summon_specific_hostile)
- {
- return FALSE;
- }
+ if (monster_has_hostile_align(m_ptr, 0, 0, r_ptr)) return FALSE;
}
/* Use the player's alignment */
else if (summon_specific_who < 0)
{
/* Do not summon enemies of the pets */
- if ((p_ptr->align < -9) && (r_ptr->flags3 & RF3_GOOD))
+ if (monster_has_hostile_align(NULL, 10, -10, r_ptr))
{
- 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_(ABS(p_ptr->align) / 2 + 1)) return FALSE;
}
}
/* Hack -- no specific type specified */
if (!summon_specific_type) return (TRUE);
- if (!summon_unique_okay && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7))) return FALSE;
+ if (!summon_unique_okay && ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL))) return FALSE;
if ((summon_specific_who < 0) &&
- ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE_7)) &&
- (((p_ptr->align > 9) && (r_ptr->flags3 & RF3_EVIL)) ||
- ((p_ptr->align < -9) && (r_ptr->flags3 & RF3_GOOD))))
+ ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) &&
+ monster_has_hostile_align(NULL, 10, -10, r_ptr))
return FALSE;
if ((r_ptr->flags7 & RF7_CHAMELEON) && (d_info[dungeon_type].flags1 & DF1_CHAMELEON)) return TRUE;
summon_unique_okay = (mode & PM_ALLOW_UNIQUE) ? TRUE : FALSE;
- /* Save the hostility */
- summon_specific_hostile = (!(mode & PM_FORCE_FRIENDLY) && !(is_friendly_idx(who)) && !(mode & PM_FORCE_PET));
-
/* Prepare allocation table */
get_mon_num_prep(summon_specific_okay, get_monster_hook2(y, x));
if (m_ptr->mflag2 & MFLAG2_NOPET) mode |= PM_NO_PET;
+ /* Hack -- Shadower spawns Shadower */
+ if (m_ptr->mflag2 & MFLAG2_KAGE) mode |= PM_KAGE;
+
/* Create a new monster (awake, no groups) */
if (!place_monster_aux(m_idx, y, x, m_ptr->r_idx, (mode | PM_NO_KAGE)))
return FALSE;
- if (clone)
+ /* Hack -- Transfer "clone" flag */
+ if (clone || (m_ptr->smart & SM_CLONED))
{
m_list[hack_m_idx_ii].smart |= SM_CLONED;
m_list[hack_m_idx_ii].mflag2 |= MFLAG2_NOPET;
}
- /* Hack -- Shadower spawns Shadower */
- if (m_ptr->mflag2 & MFLAG2_KAGE) m_list[hack_m_idx_ii].mflag2 |= MFLAG2_KAGE;
-
/* Hack -- Appearance transfer */
if (!is_original_ap(m_ptr)) m_list[hack_m_idx_ii].ap_r_idx = m_ptr->ap_r_idx;
/* Mushrooms, Eyes, Jellies, Molds, Vortices, Worms, Quylthulgs */
- if (strchr(",ejmvwQ", r_ptr->d_char))
+ if (my_strchr(",ejmvwQ", r_ptr->d_char))
{
#ifdef JP
if (percentage > 95)
/* Fish */
- else if (strchr("l", r_ptr->d_char))
+ else if (my_strchr("l", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Golems, Walls, Doors, Stairs */
- else if (strchr("g#+<>", r_ptr->d_char))
+ else if (my_strchr("g#+<>", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Snakes, Hydrae, Reptiles, Mimics */
- else if (strchr("JMR", r_ptr->d_char) || !isalpha(r_ptr->d_char))
+ else if (my_strchr("JMR", r_ptr->d_char) || !isalpha(r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Felines */
- else if (strchr("f", r_ptr->d_char))
+ else if (my_strchr("f", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Ants, Centipedes, Flies, Insects, Beetles, Spiders */
- else if (strchr("acFIKS", r_ptr->d_char))
+ else if (my_strchr("acFIKS", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Birds */
- else if (strchr("B", r_ptr->d_char))
+ else if (my_strchr("B", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Dragons, Demons, High Undead */
- else if (strchr("duDLUW", r_ptr->d_char))
+ else if (my_strchr("duDLUW", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Skeletons */
- else if (strchr("s", r_ptr->d_char))
+ else if (my_strchr("s", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Zombies */
- else if (strchr("z", r_ptr->d_char))
+ else if (my_strchr("z", r_ptr->d_char))
{
if (percentage > 95)
#ifdef JP
/* Ghosts */
- else if (strchr("G", r_ptr->d_char))
+ else if (my_strchr("G", r_ptr->d_char))
{
if (percentage > 95)
/* Dogs and Hounds */
- else if (strchr("CZ", r_ptr->d_char))
+ else if (my_strchr("CZ", r_ptr->d_char))
{
#ifdef JP
if (percentage > 95)
}
/* One type of monsters (ignore,squeal,shriek) */
- else if (strchr("Xbilqrt", r_ptr->d_char))
+ else if (my_strchr("Xbilqrt", r_ptr->d_char))
{
#ifdef JP
if (percentage > 95)
*/
void update_smart_learn(int m_idx, int what)
{
-#ifdef DRS_SMART_OPTIONS
-
monster_type *m_ptr = &m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
if (p_ptr->reflect) m_ptr-> smart |= (SM_IMM_REFLECT);
break;
}
-
-#endif /* DRS_SMART_OPTIONS */
-
}
/* Acquire next object */
next_o_idx = o_ptr->next_o_idx;
- /* Paranoia */
- o_ptr->held_m_idx = 0;
-
/* Get local object */
q_ptr = &forge;
/* Copy the object */
object_copy(q_ptr, o_ptr);
+ /* Forget monster */
+ q_ptr->held_m_idx = 0;
+
/* Delete the object */
delete_object_idx(this_o_idx);