/*! * @brief 移動先のフロアに伴ったペットを配置する / Place preserved pet monsters on new floor * @return なし */ static void place_pet(void) { int i; int max_num = p_ptr->wild_mode ? 1 : MAX_PARTY_MON; for (i = 0; i < max_num; i++) { POSITION cy = 0, cx = 0; MONSTER_IDX m_idx; if (!(party_mon[i].r_idx)) continue; if (i == 0) { m_idx = m_pop(); p_ptr->riding = m_idx; if (m_idx) { cy = p_ptr->y; cx = p_ptr->x; } } else { int j; POSITION d; for (d = 1; d < 6; d++) { for (j = 1000; j > 0; j--) { scatter(&cy, &cx, p_ptr->y, p_ptr->x, d, 0); if (monster_can_enter(cy, cx, &r_info[party_mon[i].r_idx], 0)) break; } if (j) break; } m_idx = (d == 6) ? 0 : m_pop(); } if (m_idx) { monster_type *m_ptr = &m_list[m_idx]; monster_race *r_ptr; cave[cy][cx].m_idx = m_idx; m_ptr->r_idx = party_mon[i].r_idx; /* Copy all member of the structure */ *m_ptr = party_mon[i]; r_ptr = real_r_ptr(m_ptr); m_ptr->fy = cy; m_ptr->fx = cx; m_ptr->ml = TRUE; m_ptr->mtimed[MTIMED_CSLEEP] = 0; /* Paranoia */ m_ptr->hold_o_idx = 0; m_ptr->target_y = 0; if ((r_ptr->flags1 & RF1_FORCE_SLEEP) && !ironman_nightmare) { /* Monster is still being nice */ m_ptr->mflag |= (MFLAG_NICE); /* Must repair monsters */ repair_monsters = TRUE; } /* Update the monster */ update_mon(m_idx, TRUE); lite_spot(cy, cx); /* Pre-calculated in precalc_cur_num_of_pet() */ /* r_ptr->cur_num++; */ /* Hack -- Count the number of "reproducers" */ if (r_ptr->flags2 & RF2_MULTIPLY) num_repro++; /* Hack -- Notice new multi-hued monsters */ { monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx]; if (ap_r_ptr->flags1 & (RF1_ATTR_MULTI | RF1_SHAPECHANGER)) shimmer_monsters = TRUE; } } else { monster_type *m_ptr = &party_mon[i]; monster_race *r_ptr = real_r_ptr(m_ptr); char m_name[80]; monster_desc(m_name, m_ptr, 0); #ifdef JP msg_format("%sとはぐれてしまった。", m_name); #else msg_format("You have lost sight of %s.", m_name); #endif if (record_named_pet && m_ptr->nickname) { monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE); do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_LOST_SIGHT, m_name); } /* Pre-calculated in precalc_cur_num_of_pet(), but need to decrease */ if (r_ptr->cur_num) r_ptr->cur_num--; } } /* For accuracy of precalc_cur_num_of_pet() */ (void)C_WIPE(party_mon, MAX_PARTY_MON, monster_type); }
/* Place quest monsters */ bool place_quest_monsters(void) { int i; /* Handle the quest monster placements */ for (i = 0; i < max_quests; i++) { monster_race *r_ptr; u32b mode; int j; if (quest[i].status != QUEST_STATUS_TAKEN || (quest[i].type != QUEST_TYPE_KILL_LEVEL && quest[i].type != QUEST_TYPE_RANDOM) || quest[i].level != dun_level || dungeon_type != quest[i].dungeon || (quest[i].flags & QUEST_FLAG_PRESET)) { /* Ignore it */ continue; } r_ptr = &r_info[quest[i].r_idx]; /* Hack -- "unique" monsters must be "unique" */ if ((r_ptr->flags1 & RF1_UNIQUE) && (r_ptr->cur_num >= r_ptr->max_num)) continue; mode = (PM_NO_KAGE | PM_NO_PET); if (!(r_ptr->flags1 & RF1_FRIENDS)) mode |= PM_ALLOW_GROUP; for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++) { int k; for (k = 0; k < SAFE_MAX_ATTEMPTS; k++) { int x, y; int l; /* Find an empty grid */ for (l = SAFE_MAX_ATTEMPTS; l > 0; l--) { cave_type *c_ptr; feature_type *f_ptr; y = randint0(cur_hgt); x = randint0(cur_wid); c_ptr = &cave[y][x]; f_ptr = &f_info[c_ptr->feat]; if (!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) continue; if (!monster_can_enter(y, x, r_ptr, 0)) continue; if (distance(y, x, py, px) < 10) continue; if (c_ptr->info & CAVE_ICKY) continue; else break; } /* Failed to place */ if (!l) return FALSE; /* Try to place the monster */ if (place_monster_aux(0, y, x, quest[i].r_idx, mode)) { /* Success */ break; } else { /* Failure - Try again */ continue; } } /* Failed to place */ if (k == SAFE_MAX_ATTEMPTS) return FALSE; } } return TRUE; }