OSDN Git Service

[Refactor] format 関数の戻り値を std::string にする
[hengbandforosx/hengbandosx.git] / src / player-info / alignment.cpp
1 #include "player-info/alignment.h"
2 #include "artifact/fixed-art-types.h"
3 #include "avatar/avatar.h"
4 #include "game-option/text-display-options.h"
5 #include "inventory/inventory-slot-types.h"
6 #include "monster-race/monster-race.h"
7 #include "monster-race/race-flags3.h"
8 #include "monster/monster-info.h"
9 #include "monster/monster-status.h"
10 #include "player-info/equipment-info.h"
11 #include "player-info/race-info.h"
12 #include "system/floor-type-definition.h"
13 #include "system/item-entity.h"
14 #include "system/monster-entity.h"
15 #include "system/monster-race-info.h"
16 #include "system/player-type-definition.h"
17 #include "util/bit-flags-calculator.h"
18
19 PlayerAlignment::PlayerAlignment(PlayerType *player_ptr)
20 {
21     this->player_ptr = player_ptr;
22 }
23
24 /*!
25  * @brief プレイヤーの抽象的善悪アライメントの表記を返す。 / Return alignment title
26  * @param with_value 徳の情報と一緒に表示する時だけtrue
27  * @return アライメントの表記を返す。
28  */
29 std::string 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->player_ptr->alignment));
34     }
35
36     return s;
37 }
38
39 /*
40  * @brief アライメント情報の更新
41  * @param なし
42  */
43 void PlayerAlignment::update_alignment()
44 {
45     this->reset_alignment();
46     auto *floor_ptr = this->player_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 (!m_ptr->is_valid()) {
50             continue;
51         }
52         auto *r_ptr = &monraces_info[m_ptr->r_idx];
53
54         if (!m_ptr->is_pet()) {
55             continue;
56         }
57
58         if (r_ptr->kind_flags.has(MonsterKindType::GOOD)) {
59             this->bias_good_alignment(r_ptr->level);
60         }
61
62         if (r_ptr->kind_flags.has(MonsterKindType::EVIL)) {
63             this->bias_evil_alignment(r_ptr->level);
64         }
65     }
66
67     switch (this->player_ptr->mimic_form) {
68     case MimicKindType::NONE:
69         switch (this->player_ptr->prace) {
70         case PlayerRaceType::ARCHON:
71             this->bias_good_alignment(200);
72             break;
73         case PlayerRaceType::BALROG:
74             this->bias_evil_alignment(200);
75             break;
76         default:
77             break;
78         }
79
80         break;
81     case MimicKindType::DEMON:
82         this->bias_evil_alignment(200);
83         break;
84     case MimicKindType::DEMON_LORD:
85         this->bias_evil_alignment(200);
86         break;
87     case MimicKindType::VAMPIRE:
88         break;
89     default:
90         throw("Invalid MimicKindType was specified!");
91     }
92
93     for (int i = 0; i < 2; i++) {
94         const auto &wielding_weapon = this->player_ptr->inventory_list[INVEN_MAIN_HAND + i];
95         if (!has_melee_weapon(this->player_ptr, INVEN_MAIN_HAND + i) || !wielding_weapon.is_specific_artifact(FixedArtifactId::IRON_BALL)) {
96             continue;
97         }
98
99         this->bias_evil_alignment(1000);
100     }
101
102     int j = 0;
103     int neutral[2];
104     for (int i = 0; i < 8; i++) {
105         switch (this->player_ptr->vir_types[i]) {
106         case V_JUSTICE:
107             this->bias_good_alignment(this->player_ptr->virtues[i] * 2);
108             break;
109         case V_CHANCE:
110             break;
111         case V_NATURE:
112         case V_HARMONY:
113             neutral[j++] = i;
114             break;
115         case V_UNLIFE:
116             this->bias_evil_alignment(this->player_ptr->virtues[i]);
117             break;
118         default:
119             this->bias_good_alignment(this->player_ptr->virtues[i]);
120             break;
121         }
122     }
123
124     for (int i = 0; i < j; i++) {
125         if (this->player_ptr->alignment > 0) {
126             this->bias_evil_alignment(this->player_ptr->virtues[neutral[i]] / 2);
127             if (this->player_ptr->alignment < 0) {
128                 this->reset_alignment();
129             }
130         } else if (this->player_ptr->alignment < 0) {
131             this->bias_good_alignment(this->player_ptr->virtues[neutral[i]] / 2);
132             if (this->player_ptr->alignment > 0) {
133                 this->reset_alignment();
134             }
135         }
136     }
137 }
138
139 void PlayerAlignment::bias_good_alignment(int value)
140 {
141     this->player_ptr->alignment += value;
142 }
143
144 void PlayerAlignment::bias_evil_alignment(int value)
145 {
146     this->player_ptr->alignment -= value;
147 }
148
149 void PlayerAlignment::reset_alignment()
150 {
151     this->player_ptr->alignment = 0;
152 }
153
154 /*!
155  * @brief プレイヤーの抽象的善悪アライメントの表記名のみを返す。 / Return only alignment title
156  * @param player_ptr プレイヤーへの参照ポインタ。
157  * @return アライメントの表記名
158  */
159 concptr PlayerAlignment::alignment_label()
160 {
161     if (this->player_ptr->alignment > 150) {
162         return _("大善", "Lawful");
163     } else if (this->player_ptr->alignment > 50) {
164         return _("中善", "Good");
165     } else if (this->player_ptr->alignment > 10) {
166         return _("小善", "Neutral Good");
167     } else if (this->player_ptr->alignment > -11) {
168         return _("中立", "Neutral");
169     } else if (this->player_ptr->alignment > -51) {
170         return _("小悪", "Neutral Evil");
171     } else if (this->player_ptr->alignment > -151) {
172         return _("中悪", "Evil");
173     } else {
174         return _("大悪", "Chaotic");
175     }
176 }