OSDN Git Service

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