1 #include "monster-race/monster-race.h"
2 #include "monster-race/race-flags-resistance.h"
3 #include "monster-race/race-flags1.h"
4 #include "monster-race/race-indice-types.h"
5 #include "monster-race/race-resistance-mask.h"
6 #include "system/monster-race-info.h"
7 #include "util/probability-table.h"
8 #include "world/world.h"
12 /* The monster race arrays */
13 std::map<MonsterRaceId, MonsterRaceInfo> monraces_info;
15 MonsterRace::MonsterRace(MonsterRaceId r_idx)
21 * @brief どのモンスター種族でもない事を意味する MonsterRaceId を返す
22 * @details 実態は MonsterRaceId::PLAYER だが、この値は実際にプレイヤーとしての意味として使われる場合
23 * (召喚主がプレイヤーの場合やマップ上の表示属性情報等)とどのモンスターでもない意味として使われる場合があるので、
24 * 後者ではこれを使用することでコード上の意図をわかりやすくする。
26 * @return (どのモンスター種族でもないという意味での) MonsterRaceId::PLAYER を返す
28 MonsterRaceId MonsterRace::empty_id()
30 return MonsterRaceId::PLAYER;
34 * @brief (MonsterRaceId::PLAYERを除く)実在するすべてのモンスター種族IDから等確率で1つ選択する
36 * @return 選択したモンスター種族ID
38 MonsterRaceId MonsterRace::pick_one_at_random()
40 static ProbabilityTable<MonsterRaceId> table;
43 for (const auto &[r_idx, r_ref] : monraces_info) {
44 if (MonsterRace(r_idx).is_valid()) {
45 table.entry_item(r_idx, 1);
50 return table.pick_one_at_random();
54 * @brief コンストラクタに渡された MonsterRaceId が正当なもの(実際に存在するモンスター種族IDである)かどうかを調べる
55 * @details モンスター種族IDが MonsterRaceDefinitions に実在するもの(MonsterRaceId::PLAYERは除く)であるかどうかの用途の他、
56 * m_list 上の要素などの r_idx にMonsterRaceId::PLAYER を入れることで死亡扱いとして使われるのでその判定に使用する事もある
57 * @return 正当なものであれば true、そうでなければ false
59 bool MonsterRace::is_valid() const
61 return this->r_idx != MonsterRaceId::PLAYER;
65 * @brief モンスター種族が賞金首の対象かどうかを調べる。日替わり賞金首は対象外。
67 * @param unachieved_only true の場合未達成の賞金首のみを対象とする。false の場合達成未達成に関わらずすべての賞金首を対象とする。
68 * @return モンスター種族が賞金首の対象ならば true、そうでなければ false
70 bool MonsterRace::is_bounty(bool unachieved_only) const
72 auto it = std::find_if(std::begin(w_ptr->bounties), std::end(w_ptr->bounties),
73 [r_idx = this->r_idx](const auto &b_ref) {
74 return b_ref.r_idx == r_idx;
77 if (it == std::end(w_ptr->bounties)) {
81 if (unachieved_only && (*it).is_achieved) {
89 * @brief モンスター種族の総合的な強さを計算する。
90 * @details 現在はモンスター闘技場でのモンスターの強さの総合的な評価にのみ使用されている。
91 * @return 計算した結果のモンスター種族の総合的な強さの値を返す。
93 int MonsterRace::calc_power() const
96 const auto *r_ptr = &monraces_info[this->r_idx];
97 auto num_resistances = EnumClassFlagGroup<MonsterResistanceType>(r_ptr->resistance_flags & RFR_EFF_IMMUNE_ELEMENT_MASK).count();
99 if (r_ptr->misc_flags.has(MonsterMiscType::FORCE_MAXHP)) {
100 ret = r_ptr->hdice * r_ptr->hside * 2;
102 ret = r_ptr->hdice * (r_ptr->hside + 1);
104 ret = ret * (100 + r_ptr->level) / 100;
105 if (r_ptr->speed > STANDARD_SPEED) {
106 ret = ret * (r_ptr->speed * 2 - 110) / 100;
108 if (r_ptr->speed < STANDARD_SPEED) {
109 ret = ret * (r_ptr->speed - 20) / 100;
111 if (num_resistances > 2) {
112 ret = ret * (num_resistances * 2 + 5) / 10;
113 } else if (r_ptr->ability_flags.has(MonsterAbilityType::INVULNER)) {
115 } else if (r_ptr->ability_flags.has(MonsterAbilityType::HEAL)) {
117 } else if (r_ptr->ability_flags.has(MonsterAbilityType::DRAIN_MANA)) {
120 if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
123 if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50)) {
126 if (r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL)) {
129 if (r_ptr->arena_ratio) {
130 ret = ret * r_ptr->arena_ratio / 100;