2 * @brief プレイヤーの種族に基づく耐性・能力の判定処理等を行うクラス
5 * @details PlayerRaceからPlayerClassへの依存はあるが、逆は依存させないこと.
7 #include "player-base/player-race.h"
8 #include "grid/feature-flag-types.h"
9 #include "grid/feature.h"
10 #include "player-base/player-class.h"
11 #include "player-info/mimic-info-table.h"
12 #include "player/race-info-table.h"
13 #include "system/floor-type-definition.h"
14 #include "system/grid-type-definition.h"
15 #include "system/player-type-definition.h"
16 #include "util/bit-flags-calculator.h"
19 * @brief Construct a new Player Race:: Player Race object
21 * @param base_race true の場合、仮に変身している場合でも元の種族について扱う。 false の場合変身している種族について扱う。
24 PlayerRace::PlayerRace(PlayerType *player_ptr, bool base_race)
25 : player_ptr(player_ptr)
26 , base_race(base_race)
31 * @brief 種族固有の特性フラグを取得する
34 TrFlags PlayerRace::tr_flags() const
38 auto race_ptr = this->get_info();
39 if (race_ptr->infra > 0)
42 for (auto &cond : race_ptr->extra_flags) {
43 if (player_ptr->lev < cond.level)
45 if (cond.pclass.has_value()) {
46 auto is_class_equal = PlayerClass(player_ptr).equals(cond.pclass.value());
47 if (cond.not_class && is_class_equal)
49 if (!cond.not_class && !is_class_equal)
60 * @brief プレイヤーの種族情報テーブルへのポインタを取得する
62 * @return プレイヤーの種族情報テーブルへのポインタ
64 const player_race_info *PlayerRace::get_info() const
66 if (this->base_race) {
67 return &race_info[enum2i(this->player_ptr->prace)];
70 switch (this->player_ptr->mimic_form) {
72 case MIMIC_DEMON_LORD:
74 return &mimic_info[this->player_ptr->mimic_form];
75 default: // MIMIC_NONE or undefined
76 return &race_info[enum2i(this->player_ptr->prace)];
82 * @param player_ptr プレイヤー情報への参照ポインタ
85 PlayerRaceLifeType PlayerRace::life() const
87 return this->get_info()->life;
92 * @param player_ptr プレイヤー情報への参照ポインタ
93 * @param base_race ミミック中も元種族の情報を返すならtrue
96 PlayerRaceFoodType PlayerRace::food() const
98 return this->get_info()->food;
101 bool PlayerRace::is_mimic_nonliving() const
103 constexpr int nonliving_flag = 1;
104 return any_bits(mimic_info[this->player_ptr->mimic_form].choice, nonliving_flag);
107 bool PlayerRace::has_cut_immunity() const
109 auto cut_immunity = PlayerRace(this->player_ptr).equals(PlayerRaceType::GOLEM);
110 cut_immunity |= PlayerRace(this->player_ptr).equals(PlayerRaceType::SKELETON);
111 cut_immunity |= PlayerRace(this->player_ptr).equals(PlayerRaceType::SPECTRE);
112 cut_immunity |= PlayerRace(this->player_ptr).equals(PlayerRaceType::ZOMBIE) && (this->player_ptr->lev > 11);
117 bool PlayerRace::has_stun_immunity() const
119 return PlayerRace(this->player_ptr).equals(PlayerRaceType::GOLEM);
122 bool PlayerRace::equals(PlayerRaceType prace) const
124 return (this->player_ptr->mimic_form == MIMIC_NONE) && (this->player_ptr->prace == prace);
131 * ** クラッコンと妖精に加算(+レベル/10)
132 * ** 悪魔変化/吸血鬼変化で加算(+3)
134 * ** マーフォークがFF_WATER地形にいれば加算(+2+レベル/10)
135 * ** そうでなく浮遊を持っていないなら減算(-2)
137 int16_t PlayerRace::speed() const
141 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::KLACKON) || PlayerRace(this->player_ptr).equals(PlayerRaceType::SPRITE))
142 result += (this->player_ptr->lev) / 10;
144 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::MERFOLK)) {
145 auto *floor_ptr = this->player_ptr->current_floor_ptr;
146 feature_type *f_ptr = &f_info[floor_ptr->grid_array[this->player_ptr->y][this->player_ptr->x].feat];
147 if (f_ptr->flags.has(FloorFeatureType::WATER)) {
148 result += (2 + this->player_ptr->lev / 10);
149 } else if (!this->player_ptr->levitation) {
154 if (this->player_ptr->mimic_form) {
155 switch (this->player_ptr->mimic_form) {
159 case MIMIC_DEMON_LORD:
175 * * エントはレベル26,41,46到達ごとに加算(+1)
177 int16_t PlayerRace::additional_strength() const
181 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::ENT)) {
182 if (this->player_ptr->lev > 25)
184 if (this->player_ptr->lev > 40)
186 if (this->player_ptr->lev > 45)
194 * @brief 器用さ補正計算 - 種族
198 * * エントはレベル26,41,46到達ごとに減算(-1)
200 int16_t PlayerRace::additional_dexterity() const
204 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::ENT)) {
205 if (this->player_ptr->lev > 25)
207 if (this->player_ptr->lev > 40)
209 if (this->player_ptr->lev > 45)
217 * @brief 耐久力補正計算 - 種族
221 * * エントはレベル26,41,46到達ごとに加算(+1)
223 int16_t PlayerRace::additional_constitution() const
227 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::ENT)) {
228 if (this->player_ptr->lev > 25)
230 if (this->player_ptr->lev > 40)
232 if (this->player_ptr->lev > 45)