OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / pet / pet-util.cpp
1 #include "pet/pet-util.h"
2 #include "core/stuff-handler.h"
3 #include "grid/grid.h"
4 #include "monster-race/monster-race.h"
5 #include "monster-race/race-flags1.h"
6 #include "monster-race/race-flags7.h"
7 #include "monster/monster-info.h"
8 #include "monster/monster-status.h"
9 #include "player-info/class-info.h"
10 #include "system/floor-type-definition.h"
11 #include "system/grid-type-definition.h"
12 #include "system/monster-entity.h"
13 #include "system/monster-race-info.h"
14 #include "system/player-type-definition.h"
15 #include "system/redrawing-flags-updater.h"
16 #include "util/bit-flags-calculator.h"
17 #include "world/world.h"
18
19 int total_friends = 0;
20
21 /*!
22  * @brief プレイヤーの騎乗/下馬処理判定
23  * @param g_ptr プレイヤーの移動先マスの構造体参照ポインタ
24  * @param now_riding trueなら下馬処理、falseならば騎乗処理
25  * @return 可能ならばtrueを返す
26  */
27 bool can_player_ride_pet(PlayerType *player_ptr, grid_type *g_ptr, bool now_riding)
28 {
29     bool old_character_xtra = w_ptr->character_xtra;
30     MONSTER_IDX old_riding = player_ptr->riding;
31     bool old_riding_two_hands = player_ptr->riding_ryoute;
32     bool old_old_riding_two_hands = player_ptr->old_riding_ryoute;
33     bool old_pf_two_hands = any_bits(player_ptr->pet_extra_flags, PF_TWO_HANDS);
34     w_ptr->character_xtra = true;
35
36     if (now_riding) {
37         player_ptr->riding = g_ptr->m_idx;
38     } else {
39         player_ptr->riding = 0;
40         player_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
41         player_ptr->riding_ryoute = player_ptr->old_riding_ryoute = false;
42     }
43
44     auto &rfu = RedrawingFlagsUpdater::get_instance();
45     rfu.set_flag(StatusRecalculatingFlag::BONUS);
46     handle_stuff(player_ptr);
47
48     bool p_can_enter = player_can_enter(player_ptr, g_ptr->feat, CEM_P_CAN_ENTER_PATTERN);
49     player_ptr->riding = old_riding;
50     if (old_pf_two_hands) {
51         player_ptr->pet_extra_flags |= (PF_TWO_HANDS);
52     } else {
53         player_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
54     }
55
56     player_ptr->riding_ryoute = old_riding_two_hands;
57     player_ptr->old_riding_ryoute = old_old_riding_two_hands;
58     rfu.set_flag(StatusRecalculatingFlag::BONUS);
59     handle_stuff(player_ptr);
60
61     w_ptr->character_xtra = old_character_xtra;
62     return p_can_enter;
63 }
64
65 /*!
66  * @brief ペットの維持コスト計算
67  * @return 維持コスト(%)
68  */
69 PERCENTAGE calculate_upkeep(PlayerType *player_ptr)
70 {
71     bool has_a_unique = false;
72     DEPTH total_friend_levels = 0;
73     total_friends = 0;
74     for (auto m_idx = player_ptr->current_floor_ptr->m_max - 1; m_idx >= 1; m_idx--) {
75         auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
76         if (!m_ptr->is_valid()) {
77             continue;
78         }
79         auto *r_ptr = &monraces_info[m_ptr->r_idx];
80
81         if (!m_ptr->is_pet()) {
82             continue;
83         }
84
85         total_friends++;
86         if (r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
87             total_friend_levels += r_ptr->level;
88             continue;
89         }
90
91         if (player_ptr->pclass != PlayerClassType::CAVALRY) {
92             total_friend_levels += (r_ptr->level + 5) * 10;
93             continue;
94         }
95
96         if (player_ptr->riding == m_idx) {
97             total_friend_levels += (r_ptr->level + 5) * 2;
98         } else if (!has_a_unique && any_bits(monraces_info[m_ptr->r_idx].flags7, RF7_RIDING)) {
99             total_friend_levels += (r_ptr->level + 5) * 7 / 2;
100         } else {
101             total_friend_levels += (r_ptr->level + 5) * 10;
102         }
103
104         has_a_unique = true;
105     }
106
107     if (total_friends == 0) {
108         return 0;
109     }
110
111     int upkeep_factor = (total_friend_levels - (player_ptr->lev * 80 / (cp_ptr->pet_upkeep_div)));
112     if (upkeep_factor < 0) {
113         upkeep_factor = 0;
114     }
115
116     if (upkeep_factor > 1000) {
117         upkeep_factor = 1000;
118     }
119
120     return upkeep_factor;
121 }