2 * @brief 敵への攻撃によって徳を変化させる処理
7 #include "avatar/avatar-changer.h"
8 #include "avatar/avatar.h"
9 #include "dungeon/dungeon.h"
10 #include "monster-race/monster-race.h"
11 #include "monster-race/race-ability-mask.h"
12 #include "monster-race/race-flags1.h"
13 #include "monster-race/race-flags2.h"
14 #include "monster-race/race-flags3.h"
15 #include "monster-race/race-indice-types.h"
16 #include "system/floor-type-definition.h"
17 #include "system/monster-race-definition.h"
18 #include "system/monster-type-definition.h"
19 #include "system/player-type-definition.h"
20 #include "util/bit-flags-calculator.h"
23 * @brief AvaterChangerコンストラクタ
25 AvatarChanger::AvatarChanger(player_type *player_ptr, monster_type *m_ptr)
26 : player_ptr(player_ptr)
32 * @brief 徳変化処理のメインルーチン
34 void AvatarChanger::change_virtue()
36 this->change_virtue_non_beginner();
37 this->change_virtue_unique();
38 auto *r_ptr = &r_info[m_ptr->r_idx];
39 if (m_ptr->r_idx == MON_BEGGAR || m_ptr->r_idx == MON_LEPER) {
40 chg_virtue(this->player_ptr, V_COMPASSION, -1);
43 this->change_virtue_good_evil();
44 if (any_bits(r_ptr->flags3, RF3_UNDEAD) && any_bits(r_ptr->flags1, RF1_UNIQUE)) {
45 chg_virtue(this->player_ptr, V_VITALITY, 2);
48 this->change_virtue_revenge();
49 if (any_bits(r_ptr->flags2, RF2_MULTIPLY) && (r_ptr->r_akills > 1000) && one_in_(10)) {
50 chg_virtue(this->player_ptr, V_VALOUR, -1);
53 this->change_virtue_wild_thief();
54 this->change_virtue_good_animal();
58 * @brief 非BEGINNERダンジョン時に伴う徳の変化処理
60 void AvatarChanger::change_virtue_non_beginner()
62 auto *floor_ptr = this->player_ptr->current_floor_ptr;
63 auto *r_ptr = &r_info[m_ptr->r_idx];
64 if (d_info[this->player_ptr->dungeon_idx].flags.has(DF::BEGINNER)) {
68 if ((floor_ptr->dun_level == 0) && !this->player_ptr->ambush_flag && !floor_ptr->inside_arena) {
69 chg_virtue(this->player_ptr, V_VALOUR, -1);
70 } else if (r_ptr->level > floor_ptr->dun_level) {
71 if (randint1(10) <= (r_ptr->level - floor_ptr->dun_level)) {
72 chg_virtue(this->player_ptr, V_VALOUR, 1);
76 if (r_ptr->level > 60) {
77 chg_virtue(this->player_ptr, V_VALOUR, 1);
80 if (r_ptr->level >= 2 * (this->player_ptr->lev + 1)) {
81 chg_virtue(this->player_ptr, V_VALOUR, 2);
86 * @brief ユニークを攻撃対象にした場合限定の徳変化処理
88 void AvatarChanger::change_virtue_unique()
90 auto *r_ptr = &r_info[m_ptr->r_idx];
91 if (none_bits(r_ptr->flags1, RF1_UNIQUE)) {
95 if (any_bits(r_ptr->flags3, RF3_EVIL | RF3_GOOD)) {
96 chg_virtue(this->player_ptr, V_HARMONY, 2);
99 if (any_bits(r_ptr->flags3, RF3_GOOD)) {
100 chg_virtue(this->player_ptr, V_UNLIFE, 2);
101 chg_virtue(this->player_ptr, V_VITALITY, -2);
105 chg_virtue(this->player_ptr, V_INDIVIDUALISM, -1);
110 * @brief 攻撃を与えたモンスターが天使か悪魔だった場合、徳を変化させる
111 * @details 天使かつ悪魔だった場合、天使であることが優先される
113 void AvatarChanger::change_virtue_good_evil()
115 auto *floor_ptr = this->player_ptr->current_floor_ptr;
116 auto *r_ptr = &r_info[m_ptr->r_idx];
117 if (any_bits(r_ptr->flags3, RF3_GOOD) && ((r_ptr->level) / 10 + (3 * floor_ptr->dun_level) >= randint1(100))) {
118 chg_virtue(this->player_ptr, V_UNLIFE, 1);
121 if (any_bits(r_ptr->flags3, RF3_ANGEL)) {
122 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
123 chg_virtue(this->player_ptr, V_FAITH, -2);
124 } else if ((r_ptr->level) / 10 + (3 * floor_ptr->dun_level) >= randint1(100)) {
125 auto change_value = any_bits(r_ptr->flags3, RF3_GOOD) ? -1 : 1;
126 chg_virtue(this->player_ptr, V_FAITH, change_value);
132 if (any_bits(r_ptr->flags3, RF3_DEMON)) {
133 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
134 chg_virtue(this->player_ptr, V_FAITH, 2);
135 } else if ((r_ptr->level) / 10 + (3 * floor_ptr->dun_level) >= randint1(100)) {
136 chg_virtue(this->player_ptr, V_FAITH, 1);
142 * @brief 過去に@を殺したことがあるユニークにリゾンべを果たせたら徳を上げる
144 void AvatarChanger::change_virtue_revenge()
146 auto *floor_ptr = this->player_ptr->current_floor_ptr;
147 auto *r_ptr = &r_info[m_ptr->r_idx];
148 if (r_ptr->r_deaths == 0) {
152 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
153 chg_virtue(this->player_ptr, V_HONOUR, 10);
157 if ((r_ptr->level) / 10 + (2 * floor_ptr->dun_level) >= randint1(100)) {
158 chg_virtue(this->player_ptr, V_HONOUR, 1);
163 * @brief 盗み逃げをするモンスター及び地上のモンスターを攻撃した際に徳を変化させる
165 void AvatarChanger::change_virtue_wild_thief()
167 auto *floor_ptr = this->player_ptr->current_floor_ptr;
168 auto *r_ptr = &r_info[m_ptr->r_idx];
169 auto innocent = true;
171 for (auto i = 0; i < MAX_NUM_BLOWS; i++) {
172 if (r_ptr->blow[i].d_dice != 0) {
176 if ((r_ptr->blow[i].effect == RaceBlowEffectType::EAT_ITEM) || (r_ptr->blow[i].effect == RaceBlowEffectType::EAT_GOLD)) {
181 if (r_ptr->level > 0) {
186 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
187 chg_virtue(this->player_ptr, V_JUSTICE, 3);
191 if (1 + ((r_ptr->level) / 10 + (2 * floor_ptr->dun_level)) >= randint1(100)) {
192 chg_virtue(this->player_ptr, V_JUSTICE, 1);
199 chg_virtue(this->player_ptr, V_JUSTICE, -1);
204 * @brief 邪悪でなく、魔法も持たない動物を攻撃した時に徳を下げる
206 void AvatarChanger::change_virtue_good_animal()
208 auto *r_ptr = &r_info[m_ptr->r_idx];
209 auto magic_ability_flags = r_ptr->ability_flags;
210 magic_ability_flags.reset(RF_ABILITY_NOMAGIC_MASK);
211 if (none_bits(r_ptr->flags3, RF3_ANIMAL) || any_bits(r_ptr->flags3, RF3_EVIL) || magic_ability_flags.any()) {
216 chg_virtue(this->player_ptr, V_NATURE, -1);