OSDN Git Service

Merge branch 'develop' into feature/Remove-Dependency-Player-Status
[hengbandforosx/hengbandosx.git] / src / action / racial-execution.cpp
1 /*!
2  * @file racial-execution.cpp
3  * @brief レイシャルパワー実行処理実装
4  */
5
6 #include "action/racial-execution.h"
7 #include "action/action-limited.h"
8 #include "core/asking-player.h"
9 #include "game-option/disturbance-options.h"
10 #include "player/player-status.h"
11 #include "racial/racial-switcher.h"
12 #include "racial/racial-util.h"
13 #include "system/player-type-definition.h"
14 #include "term/screen-processor.h"
15 #include "view/display-messages.h"
16
17 /*!
18  * @brief レイシャル・パワー発動処理
19  * @param creature_ptr プレーヤーへの参照ポインタ
20  * @param command 発動するレイシャルのID
21  * @return 処理を実際に実行した場合はTRUE、キャンセルした場合FALSEを返す。
22  */
23 bool exe_racial_power(player_type *creature_ptr, const s32b command)
24 {
25     if (command <= -3)
26         return switch_class_racial_execution(creature_ptr, command);
27
28     if (creature_ptr->mimic_form)
29         return switch_mimic_racial_execution(creature_ptr);
30
31     return switch_race_racial_execution(creature_ptr, command);
32 }
33
34 /*!
35  * @brief レイシャル・パワーの発動成功率を計算する / Returns the chance to activate a racial power/mutation
36  * @param rpi_ptr 発動したいレイシャル・パワー情報の構造体参照ポインタ
37  * @return 成功率(%)を返す
38  */
39 PERCENTAGE racial_chance(player_type *creature_ptr, rpi_type *rpi_ptr)
40 {
41     if ((creature_ptr->lev < rpi_ptr->min_level) || creature_ptr->confused)
42         return 0;
43
44     PERCENTAGE difficulty = rpi_ptr->fail;
45     if (difficulty == 0)
46         return 100;
47
48     if (creature_ptr->stun) {
49         difficulty += (PERCENTAGE)creature_ptr->stun;
50     } else if (creature_ptr->lev > rpi_ptr->min_level) {
51         PERCENTAGE lev_adj = (PERCENTAGE)((creature_ptr->lev - rpi_ptr->min_level) / 3);
52         if (lev_adj > 10)
53             lev_adj = 10;
54
55         difficulty -= lev_adj;
56     }
57
58     if (difficulty < 5)
59         difficulty = 5;
60
61     difficulty = difficulty / 2;
62     const BASE_STATUS stat = creature_ptr->stat_cur[rpi_ptr->stat];
63     int sum = 0;
64     for (int i = 1; i <= stat; i++) {
65         int val = i - difficulty;
66         if (val > 0)
67             sum += (val <= difficulty) ? val : difficulty;
68     }
69
70     if (difficulty == 0)
71         return 100;
72     else
73         return ((sum * 100) / difficulty) / stat;
74 }
75
76 static void adjust_racial_power_difficulty(player_type *creature_ptr, rpi_type *rpi_ptr, int *difficulty)
77 {
78     if (*difficulty == 0)
79         return;
80
81     if (creature_ptr->stun) {
82         *difficulty += creature_ptr->stun;
83     } else if (creature_ptr->lev > rpi_ptr->min_level) {
84         int lev_adj = ((creature_ptr->lev - rpi_ptr->min_level) / 3);
85         if (lev_adj > 10)
86             lev_adj = 10;
87         *difficulty -= lev_adj;
88     }
89
90     if (*difficulty < 5)
91         *difficulty = 5;
92 }
93
94 /*!
95  * @brief レイシャル・パワーの発動の判定処理
96  * @param rpi_ptr 発動したいレイシャル・パワー情報の構造体参照ポインタ
97  * @return racial_level_check_result
98  */
99 racial_level_check_result check_racial_level(player_type *creature_ptr, rpi_type *rpi_ptr)
100 {
101     PLAYER_LEVEL min_level = rpi_ptr->min_level;
102     int use_stat = rpi_ptr->stat;
103     int difficulty = rpi_ptr->fail;
104     int use_hp = 0;
105     rpi_ptr->racial_cost = rpi_ptr->cost;
106     if (creature_ptr->csp < rpi_ptr->racial_cost)
107         use_hp = rpi_ptr->racial_cost - creature_ptr->csp;
108
109     if (creature_ptr->lev < min_level) {
110         msg_format(_("この能力を使用するにはレベル %d に達していなければなりません。", "You need to attain level %d to use this power."), min_level);
111         free_turn(creature_ptr);
112         return RACIAL_CANCEL;
113     }
114
115     if (cmd_limit_confused(creature_ptr)) {
116         free_turn(creature_ptr);
117         return RACIAL_CANCEL;
118     } else if (creature_ptr->chp < use_hp) {
119         if (!get_check(_("本当に今の衰弱した状態でこの能力を使いますか?", "Really use the power in your weakened state? "))) {
120             free_turn(creature_ptr);
121             return RACIAL_CANCEL;
122         }
123     }
124
125     adjust_racial_power_difficulty(creature_ptr, rpi_ptr, &difficulty);
126     take_turn(creature_ptr, 100);
127     if (randint1(creature_ptr->stat_cur[use_stat]) >= ((difficulty / 2) + randint1(difficulty / 2)))
128         return RACIAL_SUCCESS;
129
130     if (flush_failure)
131         flush();
132
133     msg_print(_("充分に集中できなかった。", "You've failed to concentrate hard enough."));
134     return RACIAL_FAILURE;
135 }