OSDN Git Service

[Refactor] #963 Moved update_alignment() from player-status.cpp to alignment.cpp/h
[hengbandforosx/hengbandosx.git] / src / player-info / alignment.cpp
1 #include "player-info/alignment.h"
2 #include "artifact/fixed-art-types.h"
3 #include "game-option/text-display-options.h"
4 #include "inventory/inventory-slot-types.h"
5 #include "monster/monster-info.h"
6 #include "monster-race/monster-race.h"
7 #include "monster-race/race-flags3.h"
8 #include "monster/monster-status.h"
9 #include "player-info/avatar.h"
10 #include "player/player-race.h"
11 #include "player/player-status.h" // todo has_melee_weapon()が相互依存している。後で消す
12 #include "system/floor-type-definition.h"
13 #include "system/monster-race-definition.h"
14 #include "system/monster-type-definition.h"
15 #include "system/object-type-definition.h"
16 #include "system/player-type-definition.h"
17 #include "util/bit-flags-calculator.h"
18
19 PlayerAlignment::PlayerAlignment(player_type *creature_ptr)
20 {
21     this->creature_ptr = creature_ptr;
22 }
23
24 /*!
25  * @brief クリーチャーの抽象的善悪アライメントの表記を返す。 / Return alignment title
26  * @param with_value 徳の情報と一緒に表示する時だけtrue
27  * @return アライメントの表記を返す。
28  */
29 concptr PlayerAlignment::get_alignment_description(bool with_value)
30 {
31     auto s = alignment_label();
32     if (with_value || show_actual_value)
33         return format(_("%s(%ld)", "%s (%ld)"), s, static_cast<long>(this->creature_ptr->alignment));
34
35     return s;
36 }
37
38 /*
39  * @brief アライメント情報の更新
40  * @param なし
41  * @return なし
42  */
43 void PlayerAlignment::update_alignment()
44 {
45     this->reset_alignment();
46     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
47     for (MONSTER_IDX m_idx = floor_ptr->m_max - 1; m_idx >= 1; m_idx--) {
48         auto *m_ptr = &floor_ptr->m_list[m_idx];
49         if (!monster_is_valid(m_ptr))
50             continue;
51         auto *r_ptr = &r_info[m_ptr->r_idx];
52
53         if (!is_pet(m_ptr))
54             continue;
55
56         if (any_bits(r_ptr->flags3, RF3_GOOD)) {
57             this->set_alignment(r_ptr->level, update_alignment_type::ALIGNMENT_ADDITION);
58         }
59
60         if (any_bits(r_ptr->flags3, RF3_EVIL)) {
61             this->set_alignment(r_ptr->level, update_alignment_type::ALIGNMENT_SUBTRACTION);
62         }
63     }
64
65     if (creature_ptr->mimic_form) {
66         switch (creature_ptr->mimic_form) {
67         case MIMIC_DEMON:
68             this->set_alignment(200, update_alignment_type::ALIGNMENT_SUBTRACTION);
69             break;
70         case MIMIC_DEMON_LORD:
71             this->set_alignment(200, update_alignment_type::ALIGNMENT_SUBTRACTION);
72             break;
73         }
74     } else {
75         switch (creature_ptr->prace) {
76         case RACE_ARCHON:
77             this->set_alignment(200, update_alignment_type::ALIGNMENT_ADDITION);
78             break;
79         case RACE_BALROG:
80             this->set_alignment(200, update_alignment_type::ALIGNMENT_SUBTRACTION);
81             break;
82
83         default:
84             break;
85         }
86     }
87
88     for (int i = 0; i < 2; i++) {
89         if (!has_melee_weapon(creature_ptr, INVEN_MAIN_HAND + i) || (creature_ptr->inventory_list[INVEN_MAIN_HAND + i].name1 != ART_IRON_BALL))
90             continue;
91
92         this->set_alignment(1000, update_alignment_type::ALIGNMENT_SUBTRACTION);
93     }
94
95     int j = 0;
96     int neutral[2];
97     for (int i = 0; i < 8; i++) {
98         switch (creature_ptr->vir_types[i]) {
99         case V_JUSTICE:
100             this->set_alignment(creature_ptr->virtues[i] * 2, update_alignment_type::ALIGNMENT_ADDITION);
101             break;
102         case V_CHANCE:
103             break;
104         case V_NATURE:
105         case V_HARMONY:
106             neutral[j++] = i;
107             break;
108         case V_UNLIFE:
109             this->set_alignment(creature_ptr->virtues[i], update_alignment_type::ALIGNMENT_SUBTRACTION);
110             break;
111         default:
112             this->set_alignment(creature_ptr->virtues[i], update_alignment_type::ALIGNMENT_ADDITION);
113             break;
114         }
115     }
116
117     for (int i = 0; i < j; i++) {
118         if (creature_ptr->alignment > 0) {
119             this->set_alignment(creature_ptr->virtues[neutral[i]] / 2, update_alignment_type::ALIGNMENT_SUBTRACTION);
120             if (creature_ptr->alignment < 0)
121                 this->reset_alignment();
122         } else if (creature_ptr->alignment < 0) {
123             this->set_alignment(creature_ptr->virtues[neutral[i]] / 2, update_alignment_type::ALIGNMENT_ADDITION);
124             if (creature_ptr->alignment > 0)
125                 this->reset_alignment();
126         }
127     }
128 }
129
130 void PlayerAlignment::set_alignment(int value, update_alignment_type ua_type)
131 {
132     switch (ua_type) {
133     case update_alignment_type::ALIGNMENT_SUBSTITUTION:
134         this->creature_ptr->alignment = value;
135         return;
136     case update_alignment_type::ALIGNMENT_ADDITION:
137         this->creature_ptr->alignment += value;
138         return;
139     case update_alignment_type::ALIGNMENT_SUBTRACTION:
140         this->creature_ptr->alignment -= value;
141         return;
142     default:
143         return;
144     }
145 }
146
147 void PlayerAlignment::reset_alignment()
148 {
149     this->set_alignment(0, update_alignment_type::ALIGNMENT_SUBSTITUTION);
150 }
151
152 /*!
153  * @brief クリーチャーの抽象的善悪アライメントの表記名のみを返す。 / Return only alignment title
154  * @param creature_ptr 算出するクリーチャーの参照ポインタ。
155  * @return アライメントの表記名
156  */
157 concptr PlayerAlignment::alignment_label()
158 {
159     if (this->creature_ptr->alignment > 150)
160         return _("大善", "Lawful");
161     else if (this->creature_ptr->alignment > 50)
162         return _("中善", "Good");
163     else if (this->creature_ptr->alignment > 10)
164         return _("小善", "Neutral Good");
165     else if (this->creature_ptr->alignment > -11)
166         return _("中立", "Neutral");
167     else if (this->creature_ptr->alignment > -51)
168         return _("小悪", "Neutral Evil");
169     else if (this->creature_ptr->alignment > -151)
170         return _("中悪", "Evil");
171     else
172         return _("大悪", "Chaotic");
173 }