2 * @brief 敵への攻撃によって徳を変化させる処理
7 #include "avatar/avatar-changer.h"
8 #include "dungeon/dungeon.h"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-ability-mask.h"
11 #include "monster-race/race-flags1.h"
12 #include "monster-race/race-flags2.h"
13 #include "monster-race/race-flags3.h"
14 #include "monster-race/race-indice-types.h"
15 #include "player-info/avatar.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"
22 AvatarChanger::AvatarChanger(player_type *target_ptr, monster_type *m_ptr)
23 : target_ptr(target_ptr)
28 void AvatarChanger::change_virtue()
30 this->change_virtue_non_beginner();
31 this->change_virtue_unique();
32 auto *r_ptr = &r_info[m_ptr->r_idx];
33 if (m_ptr->r_idx == MON_BEGGAR || m_ptr->r_idx == MON_LEPER) {
34 chg_virtue(this->target_ptr, V_COMPASSION, -1);
37 this->change_virtue_good_evil();
38 if (any_bits(r_ptr->flags3, RF3_UNDEAD) && any_bits(r_ptr->flags1, RF1_UNIQUE)) {
39 chg_virtue(this->target_ptr, V_VITALITY, 2);
42 this->change_virtue_revenge();
43 if (any_bits(r_ptr->flags2, RF2_MULTIPLY) && (r_ptr->r_akills > 1000) && one_in_(10)) {
44 chg_virtue(this->target_ptr, V_VALOUR, -1);
47 this->change_virtue_wild_thief();
48 this->change_virtue_good_animal();
51 void AvatarChanger::change_virtue_non_beginner()
53 auto *floor_ptr = this->target_ptr->current_floor_ptr;
54 auto *r_ptr = &r_info[m_ptr->r_idx];
55 if (d_info[this->target_ptr->dungeon_idx].flags.has(DF::BEGINNER)) {
59 if ((floor_ptr->dun_level == 0) && !this->target_ptr->ambush_flag && !floor_ptr->inside_arena) {
60 chg_virtue(this->target_ptr, V_VALOUR, -1);
61 } else if (r_ptr->level > floor_ptr->dun_level) {
62 if (randint1(10) <= (r_ptr->level - floor_ptr->dun_level)) {
63 chg_virtue(this->target_ptr, V_VALOUR, 1);
67 if (r_ptr->level > 60) {
68 chg_virtue(this->target_ptr, V_VALOUR, 1);
71 if (r_ptr->level >= 2 * (this->target_ptr->lev + 1)) {
72 chg_virtue(this->target_ptr, V_VALOUR, 2);
76 void AvatarChanger::change_virtue_unique()
78 auto *r_ptr = &r_info[m_ptr->r_idx];
79 if (none_bits(r_ptr->flags1, RF1_UNIQUE)) {
83 if (any_bits(r_ptr->flags3, RF3_EVIL | RF3_GOOD)) {
84 chg_virtue(this->target_ptr, V_HARMONY, 2);
87 if (any_bits(r_ptr->flags3, RF3_GOOD)) {
88 chg_virtue(this->target_ptr, V_UNLIFE, 2);
89 chg_virtue(this->target_ptr, V_VITALITY, -2);
93 chg_virtue(this->target_ptr, V_INDIVIDUALISM, -1);
98 * @brief 攻撃を与えたモンスターが天使か悪魔だった場合、徳を変化させる
99 * @details 天使かつ悪魔だった場合、天使であることが優先される
101 void AvatarChanger::change_virtue_good_evil()
103 auto *floor_ptr = this->target_ptr->current_floor_ptr;
104 auto *r_ptr = &r_info[m_ptr->r_idx];
105 if (any_bits(r_ptr->flags3, RF3_GOOD) && ((r_ptr->level) / 10 + (3 * floor_ptr->dun_level) >= randint1(100))) {
106 chg_virtue(this->target_ptr, V_UNLIFE, 1);
109 if (any_bits(r_ptr->flags3, RF3_ANGEL)) {
110 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
111 chg_virtue(this->target_ptr, V_FAITH, -2);
112 } else if ((r_ptr->level) / 10 + (3 * floor_ptr->dun_level) >= randint1(100)) {
113 auto change_value = any_bits(r_ptr->flags3, RF3_GOOD) ? -1 : 1;
114 chg_virtue(this->target_ptr, V_FAITH, change_value);
120 if (any_bits(r_ptr->flags3, RF3_DEMON)) {
121 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
122 chg_virtue(this->target_ptr, V_FAITH, 2);
123 } else if ((r_ptr->level) / 10 + (3 * floor_ptr->dun_level) >= randint1(100)) {
124 chg_virtue(this->target_ptr, V_FAITH, 1);
130 * @brief 過去に@を殺したことがあるユニークにリゾンべを果たせたら徳を上げる
132 void AvatarChanger::change_virtue_revenge()
134 auto *floor_ptr = this->target_ptr->current_floor_ptr;
135 auto *r_ptr = &r_info[m_ptr->r_idx];
136 if (r_ptr->r_deaths == 0) {
140 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
141 chg_virtue(this->target_ptr, V_HONOUR, 10);
145 if ((r_ptr->level) / 10 + (2 * floor_ptr->dun_level) >= randint1(100)) {
146 chg_virtue(this->target_ptr, V_HONOUR, 1);
151 * @brief 盗み逃げをするモンスター及び地上のモンスターを攻撃した際に徳を変化させる
153 void AvatarChanger::change_virtue_wild_thief()
155 auto *floor_ptr = this->target_ptr->current_floor_ptr;
156 auto *r_ptr = &r_info[m_ptr->r_idx];
157 auto innocent = true;
159 for (auto i = 0; i < MAX_NUM_BLOWS; i++) {
160 if (r_ptr->blow[i].d_dice != 0) {
164 if ((r_ptr->blow[i].effect == RBE_EAT_ITEM) || (r_ptr->blow[i].effect == RBE_EAT_GOLD)) {
169 if (r_ptr->level > 0) {
174 if (any_bits(r_ptr->flags1, RF1_UNIQUE)) {
175 chg_virtue(this->target_ptr, V_JUSTICE, 3);
179 if (1 + ((r_ptr->level) / 10 + (2 * floor_ptr->dun_level)) >= randint1(100)) {
180 chg_virtue(this->target_ptr, V_JUSTICE, 1);
187 chg_virtue(this->target_ptr, V_JUSTICE, -1);
192 * @brief 邪悪でなく、魔法も持たない動物を攻撃した時に徳を下げる
194 void AvatarChanger::change_virtue_good_animal()
196 auto *r_ptr = &r_info[m_ptr->r_idx];
197 auto magic_ability_flags = r_ptr->ability_flags;
198 magic_ability_flags.reset(RF_ABILITY_NOMAGIC_MASK);
199 if (none_bits(r_ptr->flags3, RF3_ANIMAL) || any_bits(r_ptr->flags3, RF3_EVIL) || magic_ability_flags.any()) {
204 chg_virtue(this->target_ptr, V_NATURE, -1);