2 * @brief プレイヤーの種族に基づく耐性・能力の判定処理等を行うクラス
5 * @details PlayerRaceからPlayerClassへの依存はあるが、逆は依存させないこと.
7 #include "player-base/player-race.h"
8 #include "grid/feature-flag-types.h"
9 #include "player-base/player-class.h"
10 #include "player-info/mimic-info-table.h"
11 #include "player/race-info-table.h"
12 #include "system/angband-exceptions.h"
13 #include "system/floor-type-definition.h"
14 #include "system/grid-type-definition.h"
15 #include "system/player-type-definition.h"
16 #include "system/terrain-type-definition.h"
17 #include "util/bit-flags-calculator.h"
20 * @brief Construct a new Player Race:: Player Race object
22 * @param base_race true の場合、仮に変身している場合でも元の種族について扱う。 false の場合変身している種族について扱う。
25 PlayerRace::PlayerRace(PlayerType *player_ptr, bool base_race)
26 : player_ptr(player_ptr)
27 , base_race(base_race)
32 * @brief 種族固有の特性フラグを取得する
35 TrFlags PlayerRace::tr_flags() const
39 auto race_ptr = this->get_info();
40 if (race_ptr->infra > 0) {
44 for (auto &cond : race_ptr->extra_flags) {
45 if (this->player_ptr->lev < cond.level) {
48 if (cond.pclass.has_value()) {
49 auto is_class_equal = PlayerClass(this->player_ptr).equals(cond.pclass.value());
50 if (cond.not_class && is_class_equal) {
53 if (!cond.not_class && !is_class_equal) {
65 * @brief プレイヤーの種族情報テーブルへのポインタを取得する
67 * @return プレイヤーの種族情報テーブルへのポインタ
69 const player_race_info *PlayerRace::get_info() const
71 if (this->base_race) {
72 return &race_info[enum2i(this->player_ptr->prace)];
75 switch (this->player_ptr->mimic_form) {
76 case MimicKindType::NONE:
77 return &race_info[enum2i(this->player_ptr->prace)];
78 case MimicKindType::DEMON:
79 case MimicKindType::DEMON_LORD:
80 case MimicKindType::VAMPIRE:
81 return &mimic_info.at(this->player_ptr->mimic_form);
83 THROW_EXCEPTION(std::logic_error, "Invalid MimicKindType was specified!");
89 * @param player_ptr プレイヤー情報への参照ポインタ
92 PlayerRaceLifeType PlayerRace::life() const
94 return this->get_info()->life;
99 * @param player_ptr プレイヤー情報への参照ポインタ
100 * @param base_race ミミック中も元種族の情報を返すならtrue
103 PlayerRaceFoodType PlayerRace::food() const
105 return this->get_info()->food;
108 bool PlayerRace::is_mimic_nonliving() const
110 constexpr int nonliving_flag = 1;
111 return any_bits(mimic_info.at(this->player_ptr->mimic_form).choice, nonliving_flag);
114 bool PlayerRace::has_cut_immunity() const
116 auto cut_immunity = this->equals(PlayerRaceType::GOLEM);
117 cut_immunity |= this->equals(PlayerRaceType::SKELETON);
118 cut_immunity |= this->equals(PlayerRaceType::SPECTRE);
119 cut_immunity |= this->equals(PlayerRaceType::ZOMBIE) && (this->player_ptr->lev > 11);
123 bool PlayerRace::has_stun_immunity() const
125 return this->equals(PlayerRaceType::GOLEM);
128 bool PlayerRace::equals(PlayerRaceType prace) const
130 return (this->player_ptr->mimic_form == MimicKindType::NONE) && (this->player_ptr->prace == prace);
137 * ** クラッコンと妖精に加算(+レベル/10)
138 * ** 悪魔変化/吸血鬼変化で加算(+3)
140 * ** マーフォークがFF_WATER地形にいれば加算(+2+レベル/10)
141 * ** そうでなく浮遊を持っていないなら減算(-2)
143 int16_t PlayerRace::speed() const
147 if (this->equals(PlayerRaceType::KLACKON) || this->equals(PlayerRaceType::SPRITE)) {
148 result += (this->player_ptr->lev) / 10;
151 if (this->equals(PlayerRaceType::MERFOLK)) {
152 auto *floor_ptr = this->player_ptr->current_floor_ptr;
153 auto *f_ptr = &terrains_info[floor_ptr->grid_array[this->player_ptr->y][this->player_ptr->x].feat];
154 if (f_ptr->flags.has(TerrainCharacteristics::WATER)) {
155 result += (2 + this->player_ptr->lev / 10);
156 } else if (!this->player_ptr->levitation) {
161 switch (this->player_ptr->mimic_form) {
162 case MimicKindType::NONE:
164 case MimicKindType::DEMON:
166 case MimicKindType::DEMON_LORD:
168 case MimicKindType::VAMPIRE:
171 THROW_EXCEPTION(std::logic_error, "Invalid MimicKindType was specified!");
180 * * エントはレベル26,41,46到達ごとに加算(+1)
182 int16_t PlayerRace::additional_strength() const
186 if (this->equals(PlayerRaceType::ENT)) {
187 if (this->player_ptr->lev > 25) {
190 if (this->player_ptr->lev > 40) {
193 if (this->player_ptr->lev > 45) {
202 * @brief 器用さ補正計算 - 種族
206 * * エントはレベル26,41,46到達ごとに減算(-1)
208 int16_t PlayerRace::additional_dexterity() const
212 if (this->equals(PlayerRaceType::ENT)) {
213 if (this->player_ptr->lev > 25) {
216 if (this->player_ptr->lev > 40) {
219 if (this->player_ptr->lev > 45) {
228 * @brief 耐久力補正計算 - 種族
232 * * エントはレベル26,41,46到達ごとに加算(+1)
234 int16_t PlayerRace::additional_constitution() const
238 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::ENT)) {
239 if (this->player_ptr->lev > 25) {
242 if (this->player_ptr->lev > 40) {
245 if (this->player_ptr->lev > 45) {
254 * @brief 救援召喚時のモンスターシンボルを返す
255 * @param player_ptr プレイヤー情報への参照ポインタ
258 char PlayerRace::get_summon_symbol() const
261 auto mmc_ptr = this->get_info();
263 auto l = strlen(mmc_ptr->symbol);
265 for (size_t i = 0; i < l; i++) {
267 symbol = mmc_ptr->symbol[i];