OSDN Git Service

[Refactor] #3312 StatusRedrawingFlag をStatusRecalculatingFlag に改名した
[hengbandforosx/hengbandosx.git] / src / player-status / player-basic-statistics.cpp
1 #include "player-status/player-basic-statistics.h"
2 #include "core/window-redrawer.h"
3 #include "mutation/mutation-flag-types.h"
4 #include "object/object-flags.h"
5 #include "player-base/player-race.h"
6 #include "player-info/class-info.h"
7 #include "player-info/mimic-info-table.h"
8 #include "player/player-personality.h"
9 #include "player/player-status.h"
10 #include "player/race-info-table.h"
11 #include "player/special-defense-types.h"
12 #include "realm/realm-hex-numbers.h"
13 #include "spell-realm/spells-hex.h"
14 #include "system/player-type-definition.h"
15 #include "system/redrawing-flags-updater.h"
16 #include "util/bit-flags-calculator.h"
17 #include "util/enum-converter.h"
18
19 PlayerBasicStatistics::PlayerBasicStatistics(PlayerType *player_ptr)
20     : PlayerStatusBase(player_ptr)
21 {
22 }
23
24 /*!
25  * @brief 基礎ステータス補正値
26  * @return ステータス補正値
27  * @details
28  * * 各要素によるステータス修正値の合計
29  */
30 int16_t PlayerBasicStatistics::modification_value()
31 {
32     return PlayerStatusBase::get_value();
33 }
34
35 /*!
36  * @brief 基礎ステータスの実値
37  * @return status_typeに対応するステータスの実値を返す
38  */
39 int16_t PlayerBasicStatistics::get_value()
40 {
41     this->set_locals();
42     return this->player_ptr->stat_index[(int)this->ability_type];
43 }
44
45 /*!
46  * @brief 基礎ステータス補正計算 - 種族
47  * @param 計算するステータスの種類
48  * @return ステータス補正値
49  * @details
50  * * 種族によるステータス修正値。
51  */
52 int16_t PlayerBasicStatistics::race_bonus()
53 {
54     return PlayerRace(this->player_ptr).get_info()->r_adj[this->ability_type];
55 }
56
57 /*!
58  * @brief ステータス補正計算 - 職業
59  * @param 計算するステータスの種類
60  * @return ステータス補正値
61  * @details
62  * * 職業によるステータス修正値
63  */
64 int16_t PlayerBasicStatistics::class_bonus()
65 {
66     const player_class_info *c_ptr = &class_info[enum2i(this->player_ptr->pclass)];
67     return c_ptr->c_adj[this->ability_type];
68 }
69
70 /*!
71  * @brief ステータス補正計算 - 性格
72  * @param 計算するステータスの種類
73  * @return ステータス補正値
74  * @details
75  * * 性格によるステータス修正値
76  */
77 int16_t PlayerBasicStatistics::personality_bonus()
78 {
79     const player_personality *a_ptr = &personality_info[this->player_ptr->ppersonality];
80     return a_ptr->a_adj[this->ability_type];
81 }
82
83 /*!
84  * @brief ステータス更新処理
85  * @details
86  * * player_ptrのステータスを更新する
87  */
88 void PlayerBasicStatistics::update_value()
89 {
90     this->set_locals();
91     this->update_top_status();
92     this->update_use_status();
93     this->update_index_status();
94 }
95
96 /*!
97  * @brief ステータス最大値更新処理
98  * @details
99  * * player_ptrのステータス最大値を更新する
100  * * 更新対象はset_locals()で設定したstatus_typeで決定される
101  */
102 void PlayerBasicStatistics::update_top_status()
103 {
104     int status = (int)this->ability_type;
105     int top = modify_stat_value(this->player_ptr->stat_max[status], this->player_ptr->stat_add[status]);
106
107     if (this->player_ptr->stat_top[status] != top) {
108         this->player_ptr->stat_top[status] = (int16_t)top;
109         auto &rfu = RedrawingFlagsUpdater::get_instance();
110         rfu.set_flag(MainWindowRedrawingFlag::ABILITY_SCORE);
111         rfu.set_flag(SubWindowRedrawingFlag::PLAYER);
112     }
113 }
114
115 /*!
116  * @brief ステータス現在値更新の例外処理
117  * @param 通常処理されたステータスの値
118  * @returns 例外処理されたステータスの値
119  * @details
120  * * player_ptrのステータス現在値を更新する際の例外処理
121  * * 派生クラスでoverrideして使用する。
122  */
123 int16_t PlayerBasicStatistics::set_exception_use_status(int16_t value)
124 {
125     return value;
126 }
127
128 /*!
129  * @brief ステータス現在値更新処理
130  * @details
131  * * player_ptrのステータス現在値を更新する
132  * * 更新対象はset_locals()で設定したstatus_typeで決定される
133  */
134 void PlayerBasicStatistics::update_use_status()
135 {
136     int status = (int)this->ability_type;
137     int16_t use = modify_stat_value(this->player_ptr->stat_cur[status], this->player_ptr->stat_add[status]);
138
139     use = this->set_exception_use_status(use);
140
141     if (this->player_ptr->stat_use[status] != use) {
142         this->player_ptr->stat_use[status] = (int16_t)use;
143         auto &rfu = RedrawingFlagsUpdater::get_instance();
144         rfu.set_flag(MainWindowRedrawingFlag::ABILITY_SCORE);
145         rfu.set_flag(SubWindowRedrawingFlag::PLAYER);
146     }
147 }
148
149 /*!
150  * @brief ステータス内部値更新処理
151  * @details
152  * * player_ptrのステータス内部値を更新する
153  * * ステータス内部値は実際の数値処理に使われる0-37の整数値
154  * * 更新対象はset_locals()で設定したstatus_typeで決定される
155  */
156 void PlayerBasicStatistics::update_index_status()
157 {
158     int status = (int)this->ability_type;
159     int index;
160     if (this->player_ptr->stat_use[status] <= 18) {
161         index = (this->player_ptr->stat_use[status] - 3);
162     } else if (this->player_ptr->stat_use[status] <= 18 + 219) {
163         index = (15 + (this->player_ptr->stat_use[status] - 18) / 10);
164     } else {
165         index = (37);
166     }
167
168     if (this->player_ptr->stat_index[status] == index) {
169         return;
170     }
171
172     this->player_ptr->stat_index[status] = (int16_t)index;
173     auto &rfu = RedrawingFlagsUpdater::get_instance();
174     static constexpr auto flags = {
175         StatusRecalculatingFlag::MP,
176         StatusRecalculatingFlag::SPELLS,
177     };
178     if (status == A_CON) {
179         rfu.set_flag(StatusRecalculatingFlag::HP);
180     } else if (status == A_INT) {
181         if (mp_ptr->spell_stat == A_INT) {
182             rfu.set_flags(flags);
183         }
184     } else if (status == A_WIS) {
185         if (mp_ptr->spell_stat == A_WIS) {
186             rfu.set_flags(flags);
187         }
188     } else if (status == A_CHR) {
189         if (mp_ptr->spell_stat == A_CHR) {
190             rfu.set_flags(flags);
191         }
192     }
193
194     rfu.set_flag(SubWindowRedrawingFlag::PLAYER);
195 }