1 #include "system/monster-entity.h"
2 #include "game-option/birth-options.h"
3 #include "monster-race/monster-race.h"
4 #include "monster-race/race-indice-types.h"
5 #include "monster-race/race-kind-flags.h"
6 #include "monster/monster-status.h"
7 #include "system/angband-system.h"
8 #include "system/monster-race-info.h"
9 #include "term/term-color-types.h"
10 #include "util/bit-flags-calculator.h"
11 #include "util/string-processor.h"
15 * @brief モンスターの属性に基づいた敵対関係の有無を返す
16 * @param sub_align1 モンスター1のサブフラグ
17 * @param sub_align2 モンスター2のサブフラグ
20 bool MonsterEntity::check_sub_alignments(const byte sub_align1, const byte sub_align2)
22 if (sub_align1 == sub_align2) {
26 auto this_evil = any_bits(sub_align1, SUB_ALIGN_EVIL);
27 this_evil &= any_bits(sub_align2, SUB_ALIGN_GOOD);
32 auto this_good = any_bits(sub_align1, SUB_ALIGN_GOOD);
33 this_good &= any_bits(sub_align2, SUB_ALIGN_EVIL);
37 bool MonsterEntity::is_friendly() const
39 return this->mflag2.has(MonsterConstantFlagType::FRIENDLY);
42 bool MonsterEntity::is_pet() const
44 return this->mflag2.has(MonsterConstantFlagType::PET);
47 bool MonsterEntity::is_hostile() const
49 return !this->is_friendly() && !this->is_pet();
53 * @brief モンスターの属性の基づいた敵対関係の有無を返す
54 * @param other 比較対象モンスターへの参照
57 bool MonsterEntity::is_hostile_to_melee(const MonsterEntity &other) const
59 if (AngbandSystem::get_instance().is_phase_out()) {
60 return !this->is_pet() && !other.is_pet();
63 const auto &monrace1 = monraces_info[this->r_idx];
64 const auto &monrace2 = monraces_info[other.r_idx];
65 const auto is_m1_wild = monrace1.wilderness_flags.has_any_of({ MonsterWildernessType::WILD_TOWN, MonsterWildernessType::WILD_ALL });
66 const auto is_m2_wild = monrace2.wilderness_flags.has_any_of({ MonsterWildernessType::WILD_TOWN, MonsterWildernessType::WILD_ALL });
67 if (is_m1_wild && is_m2_wild) {
68 if (!this->is_pet() && !other.is_pet()) {
73 if (this->is_hostile_align(other.sub_align)) {
74 if (this->mflag2.has_not(MonsterConstantFlagType::CHAMELEON) || other.mflag2.has_not(MonsterConstantFlagType::CHAMELEON)) {
79 return this->is_hostile() != other.is_hostile();
83 * @brief モンスターの属性の基づいた敵対関係の有無を返す
84 * @param other 比較対象のサブフラグ
87 bool MonsterEntity::is_hostile_align(const byte other_sub_align) const
89 return MonsterEntity::check_sub_alignments(this->sub_align, other_sub_align);
92 bool MonsterEntity::is_named() const
94 return !this->nickname.empty();
97 bool MonsterEntity::is_named_pet() const
99 return this->is_pet() && this->is_named();
102 bool MonsterEntity::is_original_ap() const
104 return this->ap_r_idx == this->r_idx;
108 * @brief モンスターがアイテム類に擬態しているかどうかを返す
109 * @param m_ptr モンスターの参照ポインタ
110 * @return モンスターがアイテム類に擬態しているならTRUE、そうでなければFALSE
113 * 一般モンスターもビハインダーだけ特別扱い
114 * その他増やしたい時はis_special_mimic に「|=」で追加すること
117 bool MonsterEntity::is_mimicry() const
119 auto is_special_mimic = this->ap_r_idx == MonsterRaceId::BEHINDER;
120 if (is_special_mimic) {
124 const auto &r_ref = this->get_appearance_monrace();
125 const auto mimic_symbols = "/|\\()[]=$,.!?&`#%<>+~";
126 if (angband_strchr(mimic_symbols, r_ref.d_char) == nullptr) {
130 if (r_ref.kind_flags.has(MonsterKindType::UNIQUE)) {
134 return r_ref.behavior_flags.has(MonsterBehaviorType::NEVER_MOVE) || this->is_asleep();
137 bool MonsterEntity::is_valid() const
139 return MonsterRace(this->r_idx).is_valid();
142 MonsterRaceId MonsterEntity::get_real_monrace_id() const
144 const auto &monrace = this->get_monrace();
145 if (this->mflag2.has_not(MonsterConstantFlagType::CHAMELEON)) {
149 return monrace.kind_flags.has(MonsterKindType::UNIQUE) ? MonsterRaceId::CHAMELEON_K : MonsterRaceId::CHAMELEON;
153 * @brief モンスターの真の種族定義を返す (CHAMAELEONフラグ専用)
154 * @return 真のモンスター種族参照
156 MonsterRaceInfo &MonsterEntity::get_real_monrace() const
158 return monraces_info[this->get_real_monrace_id()];
161 MonsterRaceInfo &MonsterEntity::get_appearance_monrace() const
163 return monraces_info[this->ap_r_idx];
166 MonsterRaceInfo &MonsterEntity::get_monrace() const
168 return monraces_info[this->r_idx];
171 short MonsterEntity::get_remaining_sleep() const
173 return this->mtimed[MTIMED_CSLEEP];
176 bool MonsterEntity::is_dead() const
181 bool MonsterEntity::is_asleep() const
183 return this->get_remaining_sleep() > 0;
186 short MonsterEntity::get_remaining_acceleration() const
188 return this->mtimed[MTIMED_FAST];
191 bool MonsterEntity::is_accelerated() const
193 return this->get_remaining_acceleration() > 0;
196 short MonsterEntity::get_remaining_deceleration() const
198 return this->mtimed[MTIMED_SLOW];
201 bool MonsterEntity::is_decelerated() const
203 return this->get_remaining_deceleration() > 0;
206 short MonsterEntity::get_remaining_stun() const
208 return this->mtimed[MTIMED_STUNNED];
211 bool MonsterEntity::is_stunned() const
213 return this->get_remaining_stun() > 0;
216 short MonsterEntity::get_remaining_confusion() const
218 return this->mtimed[MTIMED_CONFUSED];
221 bool MonsterEntity::is_confused() const
223 return this->get_remaining_confusion() > 0;
226 short MonsterEntity::get_remaining_fear() const
228 return this->mtimed[MTIMED_MONFEAR];
231 bool MonsterEntity::is_fearful() const
233 return this->get_remaining_fear() > 0;
236 short MonsterEntity::get_remaining_invulnerability() const
238 return this->mtimed[MTIMED_INVULNER];
241 bool MonsterEntity::is_invulnerable() const
243 return this->get_remaining_invulnerability() > 0;
247 * @brief 悪夢モード、一時加速、一時減速に基づくモンスターの現在速度を返す
249 byte MonsterEntity::get_temporary_speed() const
251 auto speed = this->mspeed;
252 if (ironman_nightmare) {
256 if (this->is_accelerated()) {
260 if (this->is_decelerated()) {
268 * @brief モンスターが生命体かどうかを返す
269 * @param is_apperance たぬき、カメレオン、各種誤認ならtrue
271 * @todo kind_flags をMonsterEntityへコピーする (将来的なモンスター仕様の拡張)
273 bool MonsterEntity::has_living_flag(bool is_apperance) const
275 const auto &monrace = is_apperance ? this->get_appearance_monrace() : this->get_monrace();
276 return monrace.has_living_flag();
279 bool MonsterEntity::is_explodable() const
281 const auto &monrace = this->get_monrace();
282 return monrace.is_explodable();
285 std::string MonsterEntity::get_died_message() const
287 const auto &monrace = this->get_monrace();
288 return monrace.get_died_message();
292 * @brief モンスターの状態(無敵、起きているか、HPの割合)に応じてHPバーの色と長さを算出する
293 * @return HPバーの色と長さ(1-10)のペア
295 std::pair<TERM_COLOR, int> MonsterEntity::get_hp_bar_data() const
297 const auto percent = (this->maxhp > 0) ? (100 * this->hp / this->maxhp) : 0;
298 const auto len = std::clamp(percent / 10 + 1, 1, 10);
300 if (this->is_invulnerable()) {
301 return { TERM_WHITE, len };
303 if (this->is_asleep()) {
304 return { TERM_BLUE, len };
306 if (percent >= 100) {
307 return { TERM_L_GREEN, len };
310 return { TERM_YELLOW, len };
313 return { TERM_ORANGE, len };
316 return { TERM_L_RED, len };
318 return { TERM_RED, len };
324 void MonsterEntity::set_hostile()
326 if (AngbandSystem::get_instance().is_phase_out()) {
330 this->mflag2.reset({ MonsterConstantFlagType::PET, MonsterConstantFlagType::FRIENDLY });
333 std::string MonsterEntity::get_pronoun_of_summoned_kin() const
335 return this->get_monrace().get_pronoun_of_summoned_kin();