X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmelee%2Fmelee-postprocess.cpp;h=d0e843fbc9bf8bf317b95a856e7859b5783a3838;hb=d05be23e87882abc4faca27fa91dcf9ffaa031ab;hp=c6d12168eece5217fa7d37373f926144314b70df;hpb=99c48e7cf8dd6983ff23b72e593a5f638f2b82ec;p=hengbandforosx%2Fhengbandosx.git diff --git a/src/melee/melee-postprocess.cpp b/src/melee/melee-postprocess.cpp index c6d12168e..d28e2b811 100644 --- a/src/melee/melee-postprocess.cpp +++ b/src/melee/melee-postprocess.cpp @@ -1,4 +1,4 @@ -/*! +/*! * @brief モンスター同士の打撃後処理 / Melee post-process. * @date 2014/01/17 * @author @@ -12,72 +12,82 @@ #include "melee/melee-postprocess.h" #include "core/disturbance.h" -#include "core/player-redraw-types.h" +#include "effect/attribute-types.h" #include "floor/cave.h" +#include "floor/geometry.h" #include "grid/grid.h" #include "main/sound-definitions-table.h" #include "main/sound-of-music.h" -#include "monster-attack/monster-attack-types.h" +#include "monster-attack/monster-attack-table.h" #include "monster-floor/monster-death.h" #include "monster-floor/monster-move.h" #include "monster-floor/monster-remover.h" #include "monster-race/monster-race-hook.h" #include "monster-race/monster-race.h" #include "monster-race/race-flags-resistance.h" -#include "monster-race/race-flags1.h" -#include "monster-race/race-flags3.h" -#include "monster-race/race-flags7.h" #include "monster/monster-describer.h" #include "monster/monster-description-types.h" #include "monster/monster-info.h" #include "monster/monster-status-setter.h" #include "monster/monster-status.h" #include "pet/pet-fall-off.h" -#include "player/player-class.h" -#include "player/player-personalities-types.h" -#include "player/player-race-types.h" +#include "player-info/class-info.h" +#include "player-info/race-types.h" +#include "player/player-personality-types.h" +#include "system/angband-system.h" #include "system/floor-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 "util/bit-flags-calculator.h" +#include "util/string-processor.h" #include "view/display-messages.h" +#include // Melee-post-process-type -typedef struct mam_pp_type { +struct mam_pp_type { + mam_pp_type(PlayerType *player_ptr, MONSTER_IDX m_idx, int dam, bool *dead, bool *fear, std::string_view note, MONSTER_IDX src_idx); MONSTER_IDX m_idx; - monster_type *m_ptr; - bool seen; - GAME_TEXT m_name[160]; - HIT_POINT dam; - bool known; /* Can the player be aware of this attack? */ - concptr note; + MonsterEntity *m_ptr; + int dam; bool *dead; bool *fear; - MONSTER_IDX who; -} mam_pp_type; - -mam_pp_type *initialize_mam_pp_type( - player_type *player_ptr, mam_pp_type *mam_pp_ptr, MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear, concptr note, MONSTER_IDX who) + std::string note; + MONSTER_IDX src_idx; + bool seen; + bool known; /* Can the player be aware of this attack? */ + std::string m_name; +}; + +mam_pp_type::mam_pp_type(PlayerType *player_ptr, MONSTER_IDX m_idx, int dam, bool *dead, bool *fear, std::string_view note, MONSTER_IDX src_idx) + : m_idx(m_idx) + , m_ptr(&player_ptr->current_floor_ptr->m_list[m_idx]) + , dam(dam) + , dead(dead) + , fear(fear) + , note(note) + , src_idx(src_idx) { - mam_pp_ptr->m_idx = m_idx; - mam_pp_ptr->m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx]; - mam_pp_ptr->seen = is_seen(player_ptr, mam_pp_ptr->m_ptr); - mam_pp_ptr->dam = dam; - mam_pp_ptr->known = mam_pp_ptr->m_ptr->cdis <= MAX_SIGHT; - mam_pp_ptr->dead = dead; - mam_pp_ptr->fear = fear; - mam_pp_ptr->note = note; - mam_pp_ptr->who = who; - return mam_pp_ptr; + this->seen = is_seen(player_ptr, this->m_ptr); + this->known = this->m_ptr->cdis <= MAX_PLAYER_SIGHT; + this->m_name = monster_desc(player_ptr, m_ptr, 0); } -static void prepare_redraw(player_type *player_ptr, mam_pp_type *mam_pp_ptr) +static void prepare_redraw(PlayerType *player_ptr, mam_pp_type *mam_pp_ptr) { - if (!mam_pp_ptr->m_ptr->ml) + if (!mam_pp_ptr->m_ptr->ml) { return; + } - if (player_ptr->health_who == mam_pp_ptr->m_idx) - player_ptr->redraw |= (PR_HEALTH); + auto &rfu = RedrawingFlagsUpdater::get_instance(); + if (player_ptr->health_who == mam_pp_ptr->m_idx) { + rfu.set_flag(MainWindowRedrawingFlag::HEALTH); + } - if (player_ptr->riding == mam_pp_ptr->m_idx) - player_ptr->redraw |= (PR_UHEALTH); + if (player_ptr->riding == mam_pp_ptr->m_idx) { + rfu.set_flag(MainWindowRedrawingFlag::UHEALTH); + } } /*! @@ -87,13 +97,15 @@ static void prepare_redraw(player_type *player_ptr, mam_pp_type *mam_pp_ptr) */ static bool process_invulnerability(mam_pp_type *mam_pp_ptr) { - if (monster_invulner_remaining(mam_pp_ptr->m_ptr) && randint0(PENETRATE_INVULNERABILITY)) - return FALSE; + if (mam_pp_ptr->m_ptr->is_invulnerable() && randint0(PENETRATE_INVULNERABILITY)) { + return false; + } - if (mam_pp_ptr->seen) - msg_format(_("%^sはダメージを受けない。", "%^s is unharmed."), mam_pp_ptr->m_name); + if (mam_pp_ptr->seen) { + msg_format(_("%s^はダメージを受けない。", "%s^ is unharmed."), mam_pp_ptr->m_name.data()); + } - return TRUE; + return true; } /*! @@ -103,180 +115,196 @@ static bool process_invulnerability(mam_pp_type *mam_pp_ptr) */ static bool process_all_resistances(mam_pp_type *mam_pp_ptr) { - monster_race *r_ptr = &r_info[mam_pp_ptr->m_ptr->r_idx]; - if ((r_ptr->flagsr & RFR_RES_ALL) == 0) - return FALSE; + auto *r_ptr = &mam_pp_ptr->m_ptr->get_monrace(); + if (r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_ALL)) { + return false; + } if (mam_pp_ptr->dam > 0) { mam_pp_ptr->dam /= 100; - if ((mam_pp_ptr->dam == 0) && one_in_(3)) + if ((mam_pp_ptr->dam == 0) && one_in_(3)) { mam_pp_ptr->dam = 1; + } } - if (mam_pp_ptr->dam != 0) - return FALSE; + if (mam_pp_ptr->dam != 0) { + return false; + } - if (mam_pp_ptr->seen) - msg_format(_("%^sはダメージを受けない。", "%^s is unharmed."), mam_pp_ptr->m_name); + if (mam_pp_ptr->seen) { + msg_format(_("%s^はダメージを受けない。", "%s^ is unharmed."), mam_pp_ptr->m_name.data()); + } - return TRUE; + return true; } /*! * @brief モンスター死亡時のメッセージ表示 - * @param player_ptr プレーヤーへの参照ポインタ + * @param player_ptr プレイヤーへの参照ポインタ * @param mam_pp_ptr 標的モンスター構造体への参照ポインタ - * @return なし * @details * 見えない位置で死んだら何も表示しない * 爆発して粉々になった等ならその旨を、残りは生命か無生命かで分岐 */ -static void print_monster_dead_by_monster(player_type *player_ptr, mam_pp_type *mam_pp_ptr) +static void print_monster_dead_by_monster(PlayerType *player_ptr, mam_pp_type *mam_pp_ptr) { - if (!mam_pp_ptr->known) + if (!mam_pp_ptr->known) { return; + } - monster_desc(player_ptr, mam_pp_ptr->m_name, mam_pp_ptr->m_ptr, MD_TRUE_NAME); + mam_pp_ptr->m_name = monster_desc(player_ptr, mam_pp_ptr->m_ptr, MD_TRUE_NAME); if (!mam_pp_ptr->seen) { - player_ptr->current_floor_ptr->monster_noise = TRUE; + player_ptr->current_floor_ptr->monster_noise = true; return; } - if (mam_pp_ptr->note) { - msg_format(_("%^s%s", "%^s%s"), mam_pp_ptr->m_name, mam_pp_ptr->note); + if (!mam_pp_ptr->note.empty()) { + sound_type kill_sound = mam_pp_ptr->m_ptr->has_living_flag() ? SOUND_KILL : SOUND_N_KILL; + sound(kill_sound); + msg_format(_("%s^%s", "%s^%s"), mam_pp_ptr->m_name.data(), mam_pp_ptr->note.data()); return; } - if (!monster_living(mam_pp_ptr->m_ptr->r_idx)) { - msg_format(_("%^sは破壊された。", "%^s is destroyed."), mam_pp_ptr->m_name); + if (!mam_pp_ptr->m_ptr->has_living_flag()) { + sound(SOUND_N_KILL); + msg_format(_("%s^は破壊された。", "%s^ is destroyed."), mam_pp_ptr->m_name.data()); return; } - msg_format(_("%^sは殺された。", "%^s is killed."), mam_pp_ptr->m_name); + sound(SOUND_KILL); + msg_format(_("%s^は殺された。", "%s^ is killed."), mam_pp_ptr->m_name.data()); } /*! * @brief ダメージを受けたモンスターのHPが0未満になった際の処理 - * @param player_ptr プレーヤーへの参照ポインタ + * @param player_ptr プレイヤーへの参照ポインタ * @param mam_pp_ptr 標的モンスター構造体への参照ポインタ * @return 生きていたらTRUE、それ以外 (ユニークは@以外の攻撃では死なない)はFALSE */ -static bool check_monster_hp(player_type *player_ptr, mam_pp_type *mam_pp_ptr) +static bool check_monster_hp(PlayerType *player_ptr, mam_pp_type *mam_pp_ptr) { - monster_race *r_ptr = &r_info[mam_pp_ptr->m_ptr->r_idx]; - if (mam_pp_ptr->m_ptr->hp < 0) - return FALSE; + const auto &monrace = mam_pp_ptr->m_ptr->get_monrace(); + if (mam_pp_ptr->m_ptr->hp < 0) { + return false; + } - if (((r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) || (r_ptr->flags7 & RF7_NAZGUL)) && !player_ptr->phase_out) { + auto is_like_unique = monrace.kind_flags.has(MonsterKindType::UNIQUE); + is_like_unique |= monrace.misc_flags.has(MonsterMiscType::QUESTOR); + is_like_unique |= monrace.population_flags.has(MonsterPopulationType::NAZGUL); + if (is_like_unique && !AngbandSystem::get_instance().is_phase_out()) { mam_pp_ptr->m_ptr->hp = 1; - return FALSE; + return false; } - sound_type kill_sound = monster_living(mam_pp_ptr->m_ptr->r_idx) ? SOUND_KILL : SOUND_N_KILL; - sound(kill_sound); - *(mam_pp_ptr->dead) = TRUE; + *(mam_pp_ptr->dead) = true; print_monster_dead_by_monster(player_ptr, mam_pp_ptr); - monster_gain_exp(player_ptr, mam_pp_ptr->who, mam_pp_ptr->m_ptr->r_idx); - monster_death(player_ptr, mam_pp_ptr->m_idx, FALSE); + monster_gain_exp(player_ptr, mam_pp_ptr->src_idx, mam_pp_ptr->m_ptr->r_idx); + monster_death(player_ptr, mam_pp_ptr->m_idx, false, AttributeType::NONE); delete_monster_idx(player_ptr, mam_pp_ptr->m_idx); - *(mam_pp_ptr->fear) = FALSE; - return TRUE; + *(mam_pp_ptr->fear) = false; + return true; } /*! * @brief 死亡等で恐慌状態をキャンセルする - * @param player_ptr プレーヤーへの参照ポインタ + * @param player_ptr プレイヤーへの参照ポインタ * @param mam_pp_ptr 標的モンスター構造体への参照ポインタ - * @return なし */ -static void cancel_fear_by_pain(player_type *player_ptr, mam_pp_type *mam_pp_ptr) +static void cancel_fear_by_pain(PlayerType *player_ptr, mam_pp_type *mam_pp_ptr) { - if (!monster_fear_remaining(mam_pp_ptr->m_ptr) || (mam_pp_ptr->dam <= 0) - || !set_monster_monfear(player_ptr, mam_pp_ptr->m_idx, monster_fear_remaining(mam_pp_ptr->m_ptr) - randint1(mam_pp_ptr->dam / 4))) + const auto &m_ref = *mam_pp_ptr->m_ptr; + const auto dam = mam_pp_ptr->dam; + if (!m_ref.is_fearful() || (dam <= 0) || !set_monster_monfear(player_ptr, mam_pp_ptr->m_idx, m_ref.get_remaining_fear() - randint1(dam / 4))) { return; + } - *(mam_pp_ptr->fear) = FALSE; + *(mam_pp_ptr->fear) = false; } /*! * @biref HP残量などに応じてモンスターを恐慌状態にする - * @param player_ptr プレーヤーへの参照ポインタ + * @param player_ptr プレイヤーへの参照ポインタ * @param mam_pp_ptr 標的モンスター構造体への参照ポインタ - * @return なし */ -static void make_monster_fear(player_type *player_ptr, mam_pp_type *mam_pp_ptr) +static void make_monster_fear(PlayerType *player_ptr, mam_pp_type *mam_pp_ptr) { - monster_race *r_ptr = &r_info[mam_pp_ptr->m_ptr->r_idx]; - if (monster_fear_remaining(mam_pp_ptr->m_ptr) || ((r_ptr->flags3 & RF3_NO_FEAR) == 0)) + auto *r_ptr = &mam_pp_ptr->m_ptr->get_monrace(); + if (mam_pp_ptr->m_ptr->is_fearful() || (r_ptr->resistance_flags.has_not(MonsterResistanceType::NO_FEAR))) { return; + } int percentage = (100L * mam_pp_ptr->m_ptr->hp) / mam_pp_ptr->m_ptr->maxhp; bool can_make_fear = ((percentage <= 10) && (randint0(10) < percentage)) || ((mam_pp_ptr->dam >= mam_pp_ptr->m_ptr->hp) && (randint0(100) < 80)); - if (!can_make_fear) + if (!can_make_fear) { return; + } - *(mam_pp_ptr->fear) = TRUE; + *(mam_pp_ptr->fear) = true; (void)set_monster_monfear( player_ptr, mam_pp_ptr->m_idx, (randint1(10) + (((mam_pp_ptr->dam >= mam_pp_ptr->m_ptr->hp) && (percentage > 7)) ? 20 : ((11 - percentage) * 5)))); } /*! * @brief モンスター同士の乱闘による落馬処理 - * @param player_ptr プレーヤーへの参照ポインタ + * @param player_ptr プレイヤーへの参照ポインタ * @param mam_pp_ptr 標的モンスター構造体への参照ポインタ - * @return なし */ -static void fall_off_horse_by_melee(player_type *player_ptr, mam_pp_type *mam_pp_ptr) +static void fall_off_horse_by_melee(PlayerType *player_ptr, mam_pp_type *mam_pp_ptr) { - if (!player_ptr->riding || (player_ptr->riding != mam_pp_ptr->m_idx) || (mam_pp_ptr->dam <= 0)) + if (!player_ptr->riding || (player_ptr->riding != mam_pp_ptr->m_idx) || (mam_pp_ptr->dam <= 0)) { return; + } - monster_desc(player_ptr, mam_pp_ptr->m_name, mam_pp_ptr->m_ptr, 0); - if (mam_pp_ptr->m_ptr->hp > mam_pp_ptr->m_ptr->maxhp / 3) + mam_pp_ptr->m_name = monster_desc(player_ptr, mam_pp_ptr->m_ptr, 0); + if (mam_pp_ptr->m_ptr->hp > mam_pp_ptr->m_ptr->maxhp / 3) { mam_pp_ptr->dam = (mam_pp_ptr->dam + 1) / 2; + } - if (process_fall_off_horse(player_ptr, (mam_pp_ptr->dam > 200) ? 200 : mam_pp_ptr->dam, FALSE)) - msg_format(_("%^sに振り落とされた!", "You have been thrown off from %s!"), mam_pp_ptr->m_name); + if (process_fall_off_horse(player_ptr, (mam_pp_ptr->dam > 200) ? 200 : mam_pp_ptr->dam, false)) { + msg_format(_("%s^に振り落とされた!", "You have been thrown off from %s!"), mam_pp_ptr->m_name.data()); + } } /*! - * todo 打撃が当たった時の後処理 (爆発持ちのモンスターを爆発させる等)なので、関数名を変更する必要あり * @brief モンスターが敵モンスターに行う打撃処理 / * Hack, based on mon_take_hit... perhaps all monster attacks on other monsters should use this? * @param m_idx 目標となるモンスターの参照ID * @param dam ダメージ量 * @param dead 目標となったモンスターの死亡状態を返す参照ポインタ * @param fear 目標となったモンスターの恐慌状態を返す参照ポインタ - * @param note 目標モンスターが死亡した場合の特別メッセージ(NULLならば標準表示を行う) - * @param who 打撃を行ったモンスターの参照ID - * @return なし + * @param note 目標モンスターが死亡した場合の特別メッセージ(nullptrならば標準表示を行う) + * @param src_idx 打撃を行ったモンスターの参照ID + * @todo 打撃が当たった時の後処理 (爆発持ちのモンスターを爆発させる等)なので、関数名を変更する必要あり */ -void mon_take_hit_mon(player_type *player_ptr, MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear, concptr note, MONSTER_IDX who) +void mon_take_hit_mon(PlayerType *player_ptr, MONSTER_IDX m_idx, int dam, bool *dead, bool *fear, std::string_view note, MONSTER_IDX src_idx) { - floor_type *floor_ptr = player_ptr->current_floor_ptr; - monster_type *m_ptr = &floor_ptr->m_list[m_idx]; - mam_pp_type tmp_mam_pp; - mam_pp_type *mam_pp_ptr = initialize_mam_pp_type(player_ptr, &tmp_mam_pp, m_idx, dam, dead, fear, note, who); - monster_desc(player_ptr, mam_pp_ptr->m_name, m_ptr, 0); + auto *floor_ptr = player_ptr->current_floor_ptr; + auto *m_ptr = &floor_ptr->m_list[m_idx]; + mam_pp_type tmp_mam_pp(player_ptr, m_idx, dam, dead, fear, note, src_idx); + mam_pp_type *mam_pp_ptr = &tmp_mam_pp; prepare_redraw(player_ptr, mam_pp_ptr); (void)set_monster_csleep(player_ptr, m_idx, 0); - if (player_ptr->riding && (m_idx == player_ptr->riding)) - disturb(player_ptr, TRUE, TRUE); + if (player_ptr->riding && (m_idx == player_ptr->riding)) { + disturb(player_ptr, true, true); + } - if (process_invulnerability(mam_pp_ptr) || process_all_resistances(mam_pp_ptr)) + if (process_invulnerability(mam_pp_ptr) || process_all_resistances(mam_pp_ptr)) { return; + } m_ptr->hp -= dam; - if (check_monster_hp(player_ptr, mam_pp_ptr)) + if (check_monster_hp(player_ptr, mam_pp_ptr)) { return; + } - *dead = FALSE; + *dead = false; cancel_fear_by_pain(player_ptr, mam_pp_ptr); make_monster_fear(player_ptr, mam_pp_ptr); - if ((dam > 0) && !is_pet(m_ptr) && !is_friendly(m_ptr) && (mam_pp_ptr->who != m_idx)) { - if (is_pet(&floor_ptr->m_list[mam_pp_ptr->who]) && !player_bold(player_ptr, m_ptr->target_y, m_ptr->target_x)) { - set_target(m_ptr, floor_ptr->m_list[mam_pp_ptr->who].fy, floor_ptr->m_list[mam_pp_ptr->who].fx); + if ((dam > 0) && !m_ptr->is_pet() && !m_ptr->is_friendly() && (mam_pp_ptr->src_idx != m_idx)) { + const auto &m_ref = floor_ptr->m_list[src_idx]; + if (m_ref.is_pet() && !player_ptr->is_located_at({ m_ptr->target_y, m_ptr->target_x })) { + set_target(m_ptr, m_ref.fy, m_ref.fx); } }