1 #include "system/player-type-definition.h"
2 #include "floor/geometry.h"
3 #include "market/arena-info-table.h"
4 #include "system/angband-exceptions.h"
5 #include "system/redrawing-flags-updater.h"
6 #include "timed-effect/player-blindness.h"
7 #include "timed-effect/player-confusion.h"
8 #include "timed-effect/player-cut.h"
9 #include "timed-effect/player-deceleration.h"
10 #include "timed-effect/player-fear.h"
11 #include "timed-effect/player-hallucination.h"
12 #include "timed-effect/player-paralysis.h"
13 #include "timed-effect/player-poison.h"
14 #include "timed-effect/player-stun.h"
15 #include "timed-effect/timed-effects.h"
16 #include "world/world.h"
19 * @brief プレイヤー構造体実体 / Static player info record
24 * @brief プレイヤー構造体へのグローバル参照ポインタ / Pointer to the player info
26 PlayerType *p_ptr = &p_body;
28 PlayerType::PlayerType()
29 : timed_effects(std::make_shared<TimedEffects>())
33 bool PlayerType::is_true_winner() const
35 return (w_ptr->total_winner > 0) && (this->arena_number > MAX_ARENA_MONS + 2);
38 std::shared_ptr<TimedEffects> PlayerType::effects() const
40 return this->timed_effects;
44 * @brief 自身の状態が全快で、かつフロアに影響を与えないかを検証する
46 * @todo 時限効果系に分類されるものはいずれTimedEffectsクラスのメソッドとして繰り込みたい
48 bool PlayerType::is_fully_healthy() const
50 auto effects = this->effects();
51 auto is_fully_healthy = this->chp == this->mhp;
52 is_fully_healthy &= this->csp >= this->msp;
53 is_fully_healthy &= !effects->blindness()->is_blind();
54 is_fully_healthy &= !effects->confusion()->is_confused();
55 is_fully_healthy &= !effects->poison()->is_poisoned();
56 is_fully_healthy &= !effects->fear()->is_fearful();
57 is_fully_healthy &= !effects->stun()->is_stunned();
58 is_fully_healthy &= !effects->cut()->is_cut();
59 is_fully_healthy &= !effects->deceleration()->is_slow();
60 is_fully_healthy &= !effects->paralysis()->is_paralyzed();
61 is_fully_healthy &= !effects->hallucination()->is_hallucinated();
62 is_fully_healthy &= !this->word_recall;
63 is_fully_healthy &= !this->alter_reality;
64 return is_fully_healthy;
68 * @brief ランダムに1つアビリティスコアを減少させる
69 * @return アビリティスコア減少メッセージ
70 * @todo stat_curにのみ依存するのでアビリティスコアを表すクラスへ移設する
72 std::string PlayerType::decrease_ability_random()
74 constexpr std::array<std::pair<int, std::string_view>, 6> candidates = { {
75 { A_STR, _("強く", "strong") },
76 { A_INT, _("聡明で", "bright") },
77 { A_WIS, _("賢明で", "wise") },
78 { A_DEX, _("器用で", "agile") },
79 { A_CON, _("健康で", "hale") },
80 { A_CHR, _("美しく", "beautiful") },
83 const auto &[k, act] = rand_choice(candidates);
84 this->stat_cur[k] = (this->stat_cur[k] * 3) / 4;
85 if (this->stat_cur[k] < 3) {
86 this->stat_cur[k] = 3;
89 RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::BONUS);
90 return format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), act.data());
94 * @brief 全てのアビリティスコアを減少させる
95 * @return アビリティスコア減少メッセージ
96 * @todo stat_curにのみ依存するのでアビリティスコアを表すクラスへ移設する
98 std::string PlayerType::decrease_ability_all()
100 for (auto i = 0; i < A_MAX; i++) {
101 this->stat_cur[i] = (this->stat_cur[i] * 7) / 8;
102 if (this->stat_cur[i] < 3) {
103 this->stat_cur[i] = 3;
107 RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::BONUS);
108 return _("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be...");
113 * @details プレイヤーが移動する前後の文脈で使用すると不整合を起こすので注意
115 Pos2D PlayerType::get_position() const
117 return Pos2D(this->y, this->x);
121 * @brief 現在地の隣 (瞬時値)または現在地を返す
122 * @param dir 隣を表す方向番号
123 * @details プレイヤーが移動する前後の文脈で使用すると不整合を起こすので注意
124 * 方向番号による位置取りは以下の通り. 0と5は現在地.
129 Pos2D PlayerType::get_neighbor(int dir) const
131 if ((dir < 0) || (dir >= static_cast<int>(std::size(ddx)))) {
132 THROW_EXCEPTION(std::logic_error, "Invalid direction is specified!");
135 return Pos2D(this->y + ddy[dir], this->x + ddx[dir]);
138 bool PlayerType::is_located_at_running_destination() const
140 return (this->y == this->run_py) && (this->x == this->run_px);
143 bool PlayerType::is_located_at(const Pos2D &pos) const
145 return (this->y == pos.y) && (this->x == pos.x);
148 bool PlayerType::in_saved_floor() const
150 return this->floor_id != 0;