-/*!
+/*!
* @brief モンスターの特殊技能とターン経過処理 (移動等)/ Monster spells and movement for passaging a turn
* @date 2014/01/17
* @author
#include "monster/monster-processor.h"
#include "avatar/avatar.h"
#include "cmd-io/cmd-dump.h"
-#include "core/player-update-types.h"
#include "core/speed-table.h"
#include "floor/cave.h"
#include "floor/geometry.h"
#include "player/special-defense-types.h"
#include "spell-realm/spells-hex.h"
#include "spell/summon-types.h"
+#include "system/angband-system.h"
#include "system/floor-type-definition.h"
#include "system/grid-type-definition.h"
-#include "system/monster-race-definition.h"
-#include "system/monster-type-definition.h"
+#include "system/monster-entity.h"
+#include "system/monster-race-info.h"
#include "system/player-type-definition.h"
+#include "system/redrawing-flags-updater.h"
#include "target/projection-path-calculator.h"
#include "view/display-messages.h"
bool process_monster_fear(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx);
void sweep_monster_process(PlayerType *player_ptr);
-bool decide_process_continue(PlayerType *player_ptr, monster_type *m_ptr);
+bool decide_process_continue(PlayerType *player_ptr, MonsterEntity *m_ptr);
/*!
* @brief モンスター単体の1ターン行動処理メインルーチン /
void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
{
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
+ auto *r_ptr = &m_ptr->get_monrace();
turn_flags tmp_flags;
turn_flags *turn_flags_ptr = init_turn_flags(player_ptr->riding, m_idx, &tmp_flags);
turn_flags_ptr->see_m = is_seen(player_ptr, m_ptr);
decide_drop_from_monster(player_ptr, m_idx, turn_flags_ptr->is_riding_mon);
- if (m_ptr->mflag2.has(MonsterConstantFlagType::CHAMELEON) && one_in_(13) && !monster_csleep_remaining(m_ptr)) {
+ if (m_ptr->mflag2.has(MonsterConstantFlagType::CHAMELEON) && one_in_(13) && !m_ptr->is_asleep()) {
choose_new_monster(player_ptr, m_idx, false, MonsterRace::empty_id());
- r_ptr = &r_info[m_ptr->r_idx];
+ r_ptr = &m_ptr->get_monrace();
}
turn_flags_ptr->aware = process_stealth(player_ptr, m_idx);
- if (vanish_summoned_children(player_ptr, m_idx, turn_flags_ptr->see_m) || process_quantum_effect(player_ptr, m_idx, turn_flags_ptr->see_m) || explode_grenade(player_ptr, m_idx) || runaway_monster(player_ptr, turn_flags_ptr, m_idx) || !awake_monster(player_ptr, m_idx)) {
+ if (vanish_summoned_children(player_ptr, m_idx, turn_flags_ptr->see_m)) {
+ return;
+ }
+
+ if (process_quantum_effect(player_ptr, m_idx, turn_flags_ptr->see_m)) {
+ return;
+ }
+
+ if (explode_grenade(player_ptr, m_idx)) {
+ return;
+ }
+
+ if (runaway_monster(player_ptr, turn_flags_ptr, m_idx)) {
return;
}
- if (monster_stunned_remaining(m_ptr) && one_in_(2)) {
+ if (!awake_monster(player_ptr, m_idx)) {
+ return;
+ }
+
+ if (m_ptr->is_stunned() && one_in_(2)) {
return;
}
if (turn_flags_ptr->is_riding_mon) {
- player_ptr->update |= PU_BONUS;
+ RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::BONUS);
}
process_angar(player_ptr, m_idx, turn_flags_ptr->see_m);
}
int count = 0;
- if (!process_monster_movement(player_ptr, turn_flags_ptr, m_idx, mm, oy, ox, &count)) {
+ if (!process_monster_movement(player_ptr, turn_flags_ptr, m_idx, mm, { oy, ox }, &count)) {
return;
}
m_ptr->mflag2.reset(MonsterConstantFlagType::NOFLOW);
}
- if (!turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && !monster_fear_remaining(m_ptr) && !turn_flags_ptr->is_riding_mon && turn_flags_ptr->aware) {
+ if (!turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && !m_ptr->is_fearful() && !turn_flags_ptr->is_riding_mon && turn_flags_ptr->aware) {
if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell) {
if (make_attack_spell(player_ptr, m_idx)) {
return;
}
}
- update_player_type(player_ptr, turn_flags_ptr, r_ptr);
+ update_map_flags(turn_flags_ptr);
+ update_lite_flags(turn_flags_ptr, r_ptr);
update_monster_race_flags(player_ptr, turn_flags_ptr, m_ptr);
if (!process_monster_fear(player_ptr, turn_flags_ptr, m_idx)) {
}
if (m_ptr->ml) {
- chg_virtue(player_ptr, V_COMPASSION, -1);
+ chg_virtue(player_ptr, Virtue::COMPASSION, -1);
}
}
}
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
+ auto *r_ptr = &m_ptr->get_monrace();
int tmp = player_ptr->lev * 6 + (player_ptr->skill_stl + 10) * 4;
if (player_ptr->monlite) {
tmp /= 3;
void decide_drop_from_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool is_riding_mon)
{
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
- if (!is_riding_mon || ((r_ptr->flags7 & RF7_RIDING) != 0)) {
+ auto *r_ptr = &m_ptr->get_monrace();
+ if (!is_riding_mon || r_ptr->misc_flags.has(MonsterMiscType::RIDING)) {
return;
}
#ifdef JP
msg_print("地面に落とされた。");
#else
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(player_ptr, m_name, &player_ptr->current_floor_ptr->m_list[player_ptr->riding], 0);
- msg_format("You have fallen from %s.", m_name);
+ const auto m_name = monster_desc(player_ptr, &player_ptr->current_floor_ptr->m_list[player_ptr->riding], 0);
+ msg_format("You have fallen from %s.", m_name.data());
#endif
}
}
}
if (see_m) {
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(player_ptr, m_name, m_ptr, 0);
- msg_format(_("%sは消え去った!", "%^s disappears!"), m_name);
+ const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+ msg_format(_("%sは消え去った!", "%s^ disappears!"), m_name.data());
}
- if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname) {
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(player_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
- exe_write_diary(player_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
+ if (record_named_pet && m_ptr->is_named_pet()) {
+ const auto m_name = monster_desc(player_ptr, m_ptr, MD_INDEF_VISIBLE);
+ exe_write_diary(player_ptr, DiaryKind::NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
}
delete_monster_idx(player_ptr, m_idx);
bool awake_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
{
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
- if (!monster_csleep_remaining(m_ptr)) {
+ auto *r_ptr = &m_ptr->get_monrace();
+ if (!m_ptr->is_asleep()) {
return true;
}
(void)set_monster_csleep(player_ptr, m_idx, 0);
if (m_ptr->ml) {
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(player_ptr, m_name, m_ptr, 0);
- msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
+ const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+ msg_format(_("%s^が目を覚ました。", "%s^ wakes up."), m_name.data());
}
if (is_original_ap_and_seen(player_ptr, m_ptr) && (r_ptr->r_wake < MAX_UCHAR)) {
*/
void process_angar(PlayerType *player_ptr, MONSTER_IDX m_idx, bool see_m)
{
- auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
- bool gets_angry = false;
- if (is_friendly(m_ptr) && has_aggravate(player_ptr)) {
+ auto &monster = player_ptr->current_floor_ptr->m_list[m_idx];
+ const auto &monrace = monster.get_monrace();
+ auto gets_angry = monster.is_friendly() && has_aggravate(player_ptr);
+ const auto should_aggravate = monster.is_pet();
+ auto has_hostile = monrace.kind_flags.has(MonsterKindType::UNIQUE) || (monrace.population_flags.has(MonsterPopulationType::NAZGUL));
+ has_hostile &= monster_has_hostile_align(player_ptr, nullptr, 10, -10, &monrace);
+ const auto has_resist_all = monrace.resistance_flags.has(MonsterResistanceType::RESIST_ALL);
+ if (should_aggravate && (has_hostile || has_resist_all)) {
gets_angry = true;
}
- if (is_pet(m_ptr) && (((r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) && monster_has_hostile_align(player_ptr, nullptr, 10, -10, r_ptr)) || r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL))) {
- gets_angry = true;
- }
-
- if (player_ptr->phase_out || !gets_angry) {
+ if (AngbandSystem::get_instance().is_phase_out() || !gets_angry) {
return;
}
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(player_ptr, m_name, m_ptr, is_pet(m_ptr) ? MD_ASSUME_VISIBLE : 0);
+ const auto m_name = monster_desc(player_ptr, &monster, monster.is_pet() ? MD_ASSUME_VISIBLE : 0);
/* When riding a hostile alignment pet */
if (player_ptr->riding == m_idx) {
return;
}
- msg_format(_("%^sが突然暴れだした!", "%^s suddenly begins unruly!"), m_name);
+ msg_format(_("%s^が突然暴れだした!", "%s^ suddenly begins unruly!"), m_name.data());
if (!process_fall_off_horse(player_ptr, 1, true)) {
return;
}
msg_format(_("あなたは振り落とされた。", "You have fallen."));
}
- if (is_pet(m_ptr) || see_m) {
- msg_format(_("%^sは突然敵にまわった!", "%^s suddenly becomes hostile!"), m_name);
+ if (monster.is_pet() || see_m) {
+ msg_format(_("%s^は突然敵にまわった!", "%s^ suddenly becomes hostile!"), m_name.data());
}
- set_hostile(player_ptr, m_ptr);
+ monster.set_hostile();
}
/*!
void process_special(PlayerType *player_ptr, MONSTER_IDX m_idx)
{
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
- if (r_ptr->ability_flags.has_not(MonsterAbilityType::SPECIAL) || (m_ptr->r_idx != MonsterRaceId::OHMU) || player_ptr->current_floor_ptr->inside_arena || player_ptr->phase_out || (r_ptr->freq_spell == 0) || (randint1(100) > r_ptr->freq_spell)) {
+ auto *r_ptr = &m_ptr->get_monrace();
+ auto can_do_special = r_ptr->ability_flags.has(MonsterAbilityType::SPECIAL);
+ can_do_special &= m_ptr->r_idx == MonsterRaceId::OHMU;
+ can_do_special &= !player_ptr->current_floor_ptr->inside_arena;
+ can_do_special &= !AngbandSystem::get_instance().is_phase_out();
+ can_do_special &= r_ptr->freq_spell != 0;
+ can_do_special &= randint1(100) <= r_ptr->freq_spell;
+ if (!can_do_special) {
return;
}
int count = 0;
DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
- BIT_FLAGS p_mode = is_pet(m_ptr) ? PM_FORCE_PET : PM_NONE;
+ BIT_FLAGS p_mode = m_ptr->is_pet() ? PM_FORCE_PET : PM_NONE;
for (int k = 0; k < A_MAX; k++) {
if (summon_specific(player_ptr, m_idx, m_ptr->fy, m_ptr->fx, rlev, SUMMON_MOLD, (PM_ALLOW_GROUP | p_mode))) {
bool decide_monster_multiplication(PlayerType *player_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox)
{
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
- if (((r_ptr->flags2 & RF2_MULTIPLY) == 0) || (player_ptr->current_floor_ptr->num_repro >= MAX_REPRO)) {
+ auto *r_ptr = &m_ptr->get_monrace();
+ if (((r_ptr->flags2 & RF2_MULTIPLY) == 0) || (player_ptr->current_floor_ptr->num_repro >= MAX_REPRODUCTION)) {
return false;
}
k = 8;
}
- if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ))) {
- if (multiply_monster(player_ptr, m_idx, false, (is_pet(m_ptr) ? PM_FORCE_PET : 0))) {
+ constexpr auto chance_reproduction = 8;
+ if ((k < 4) && (!k || !randint0(k * chance_reproduction))) {
+ if (multiply_monster(player_ptr, m_idx, false, (m_ptr->is_pet() ? PM_FORCE_PET : 0))) {
if (player_ptr->current_floor_ptr->m_list[hack_m_idx_ii].ml && is_original_ap_and_seen(player_ptr, m_ptr)) {
r_ptr->r_flags2 |= RF2_MULTIPLY;
}
*/
bool cast_spell(PlayerType *player_ptr, MONSTER_IDX m_idx, bool aware)
{
- auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- auto *r_ptr = &r_info[m_ptr->r_idx];
- if ((r_ptr->freq_spell == 0) || (randint1(100) > r_ptr->freq_spell)) {
+ auto &floor = *player_ptr->current_floor_ptr;
+ const auto &monster_from = floor.m_list[m_idx];
+ const auto &monrace = monster_from.get_monrace();
+ if ((monrace.freq_spell == 0) || (randint1(100) > monrace.freq_spell)) {
return false;
}
bool counterattack = false;
- if (m_ptr->target_y) {
- MONSTER_IDX t_m_idx = player_ptr->current_floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
- if (t_m_idx && are_enemies(player_ptr, m_ptr, &player_ptr->current_floor_ptr->m_list[t_m_idx]) && projectable(player_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x)) {
+ if (monster_from.target_y) {
+ Pos2D pos(monster_from.target_y, monster_from.target_x);
+ const auto t_m_idx = floor.get_grid(pos).m_idx;
+ const auto &monster_to = floor.m_list[t_m_idx];
+ const auto is_projectable = projectable(player_ptr, monster_from.fy, monster_from.fx, monster_from.target_y, monster_from.target_x);
+ if (t_m_idx && monster_from.is_hostile_to_melee(monster_to) && is_projectable) {
counterattack = true;
}
}
bool process_monster_fear(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx)
{
auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
- bool is_battle_determined = !turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && monster_fear_remaining(m_ptr) && turn_flags_ptr->aware;
+ bool is_battle_determined = !turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && m_ptr->is_fearful() && turn_flags_ptr->aware;
if (!is_battle_determined) {
return false;
}
return true;
}
- GAME_TEXT m_name[MAX_NLEN];
- monster_desc(player_ptr, m_name, m_ptr, 0);
- msg_format(_("%^sは戦いを決意した!", "%^s turns to fight!"), m_name);
+ const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+ msg_format(_("%s^は戦いを決意した!", "%s^ turns to fight!"), m_name.data());
return true;
}
*/
void process_monsters(PlayerType *player_ptr)
{
- old_race_flags tmp_flags;
- old_race_flags *old_race_flags_ptr = init_old_race_flags(&tmp_flags);
+ const auto old_monrace_id = player_ptr->monster_race_idx;
+ old_race_flags tmp_flags(old_monrace_id);
+ old_race_flags *old_race_flags_ptr = &tmp_flags;
player_ptr->current_floor_ptr->monster_noise = false;
- MonsterRaceId old_monster_race_idx = player_ptr->monster_race_idx;
- save_old_race_flags(player_ptr->monster_race_idx, old_race_flags_ptr);
sweep_monster_process(player_ptr);
hack_m_idx = 0;
- if (!MonsterRace(player_ptr->monster_race_idx).is_valid() || (player_ptr->monster_race_idx != old_monster_race_idx)) {
+ if (!MonsterRace(player_ptr->monster_race_idx).is_valid() || (player_ptr->monster_race_idx != old_monrace_id)) {
return;
}
{
auto *floor_ptr = player_ptr->current_floor_ptr;
for (MONSTER_IDX i = floor_ptr->m_max - 1; i >= 1; i--) {
- monster_type *m_ptr;
+ MonsterEntity *m_ptr;
m_ptr = &floor_ptr->m_list[i];
if (player_ptr->leaving) {
return;
}
- if (!monster_is_valid(m_ptr) || player_ptr->wild_mode) {
+ if (!m_ptr->is_valid() || player_ptr->wild_mode) {
continue;
}
continue;
}
- if ((m_ptr->cdis >= AAF_LIMIT) || !decide_process_continue(player_ptr, m_ptr)) {
+ if ((m_ptr->cdis >= MAX_MONSTER_SENSING) || !decide_process_continue(player_ptr, m_ptr)) {
continue;
}
- byte speed = (player_ptr->riding == i) ? player_ptr->pspeed : decide_monster_speed(m_ptr);
+ byte speed = (player_ptr->riding == i) ? player_ptr->pspeed : m_ptr->get_temporary_speed();
m_ptr->energy_need -= speed_to_energy(speed);
if (m_ptr->energy_need > 0) {
continue;
* @param m_ptr モンスターへの参照ポインタ
* @return 後続処理が必要ならTRUE
*/
-bool decide_process_continue(PlayerType *player_ptr, monster_type *m_ptr)
+bool decide_process_continue(PlayerType *player_ptr, MonsterEntity *m_ptr)
{
- monster_race *r_ptr;
- r_ptr = &r_info[m_ptr->r_idx];
+ const auto &monrace = m_ptr->get_monrace();
if (!player_ptr->no_flowed) {
m_ptr->mflag2.reset(MonsterConstantFlagType::NOFLOW);
}
- if (m_ptr->cdis <= (is_pet(m_ptr) ? (r_ptr->aaf > MAX_SIGHT ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf)) {
+ if (m_ptr->cdis <= (m_ptr->is_pet() ? (monrace.aaf > MAX_PLAYER_SIGHT ? MAX_PLAYER_SIGHT : monrace.aaf) : monrace.aaf)) {
return true;
}
- if ((m_ptr->cdis <= MAX_SIGHT || player_ptr->phase_out) && (player_has_los_bold(player_ptr, m_ptr->fy, m_ptr->fx) || has_aggravate(player_ptr))) {
+ auto should_continue = (m_ptr->cdis <= MAX_PLAYER_SIGHT) || AngbandSystem::get_instance().is_phase_out();
+ should_continue &= player_ptr->current_floor_ptr->has_los({ m_ptr->fy, m_ptr->fx }) || has_aggravate(player_ptr);
+ if (should_continue) {
return true;
}