2 * @file racial-execution.cpp
3 * @brief レイシャルパワー実行処理実装
6 #include "action/racial-execution.h"
7 #include "action/action-limited.h"
8 #include "artifact/fixed-art-types.h"
9 #include "core/asking-player.h"
10 #include "game-option/disturbance-options.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "player-base/player-class.h"
13 #include "player-info/race-info.h"
14 #include "player-status/player-energy.h"
15 #include "racial/racial-switcher.h"
16 #include "racial/racial-util.h"
17 #include "system/item-entity.h"
18 #include "system/player-type-definition.h"
19 #include "term/screen-processor.h"
20 #include "timed-effect/player-confusion.h"
21 #include "timed-effect/player-stun.h"
22 #include "timed-effect/timed-effects.h"
23 #include "view/display-messages.h"
26 * @brief レイシャル・パワー発動処理
27 * @param player_ptr プレイヤーへの参照ポインタ
28 * @param command 発動するレイシャルのID
29 * @return 処理を実際に実行した場合はTRUE、キャンセルした場合FALSEを返す。
31 bool exe_racial_power(PlayerType *player_ptr, const int32_t command)
34 return switch_class_racial_execution(player_ptr, command);
37 if (player_ptr->mimic_form != MimicKindType::NONE) {
38 return switch_mimic_racial_execution(player_ptr);
41 return switch_race_racial_execution(player_ptr, command);
45 * @brief レイシャル・パワーの発動成功率を計算する / Returns the chance to activate a racial power/mutation
46 * @param rpi_ptr 発動したいレイシャル・パワー情報の構造体参照ポインタ
49 PERCENTAGE racial_chance(PlayerType *player_ptr, rpi_type *rpi_ptr)
51 if ((player_ptr->lev < rpi_ptr->min_level) || player_ptr->effects()->confusion()->is_confused()) {
55 PERCENTAGE difficulty = rpi_ptr->fail;
56 if (difficulty == 0) {
60 auto player_stun = player_ptr->effects()->stun();
61 if (player_stun->is_stunned()) {
62 difficulty += player_stun->current();
63 } else if (player_ptr->lev > rpi_ptr->min_level) {
64 PERCENTAGE lev_adj = (PERCENTAGE)((player_ptr->lev - rpi_ptr->min_level) / 3);
69 difficulty -= lev_adj;
72 auto special_easy = PlayerClass(player_ptr).equals(PlayerClassType::IMITATOR);
73 special_easy &= player_ptr->inventory_list[INVEN_NECK].is_specific_artifact(FixedArtifactId::GOGO_PENDANT);
74 special_easy &= rpi_ptr->racial_name.compare("倍返し") == 0;
83 difficulty = difficulty / 2;
84 const auto stat = player_ptr->stat_cur[rpi_ptr->stat];
86 for (auto i = 1; i <= stat; i++) {
87 int val = i - difficulty;
89 sum += (val <= difficulty) ? val : difficulty;
93 if (difficulty == 0) {
96 return ((sum * 100) / difficulty) / stat;
100 static void adjust_racial_power_difficulty(PlayerType *player_ptr, rpi_type *rpi_ptr, int *difficulty)
102 if (*difficulty == 0) {
106 auto player_stun = player_ptr->effects()->stun();
107 if (player_stun->is_stunned()) {
108 *difficulty += player_stun->current();
109 } else if (player_ptr->lev > rpi_ptr->min_level) {
110 int lev_adj = ((player_ptr->lev - rpi_ptr->min_level) / 3);
114 *difficulty -= lev_adj;
117 if (*difficulty < 5) {
123 * @brief レイシャル・パワーの発動の判定処理
124 * @param rpi_ptr 発動したいレイシャル・パワー情報の構造体参照ポインタ
125 * @return racial_level_check_result
127 racial_level_check_result check_racial_level(PlayerType *player_ptr, rpi_type *rpi_ptr)
129 PLAYER_LEVEL min_level = rpi_ptr->min_level;
130 int use_stat = rpi_ptr->stat;
131 int difficulty = rpi_ptr->fail;
133 rpi_ptr->racial_cost = rpi_ptr->cost;
134 if (player_ptr->csp < rpi_ptr->racial_cost) {
135 use_hp = rpi_ptr->racial_cost - player_ptr->csp;
138 PlayerEnergy energy(player_ptr);
139 if (player_ptr->lev < min_level) {
140 msg_format(_("この能力を使用するにはレベル %d に達していなければなりません。", "You need to attain level %d to use this power."), min_level);
141 energy.reset_player_turn();
142 return RACIAL_CANCEL;
145 if (cmd_limit_confused(player_ptr)) {
146 energy.reset_player_turn();
147 return RACIAL_CANCEL;
148 } else if (player_ptr->chp < use_hp) {
149 if (!get_check(_("本当に今の衰弱した状態でこの能力を使いますか?", "Really use the power in your weakened state? "))) {
150 energy.reset_player_turn();
151 return RACIAL_CANCEL;
155 adjust_racial_power_difficulty(player_ptr, rpi_ptr, &difficulty);
156 energy.set_player_turn_energy(100);
157 if (randint1(player_ptr->stat_cur[use_stat]) >= ((difficulty / 2) + randint1(difficulty / 2))) {
158 return RACIAL_SUCCESS;
165 msg_print(_("充分に集中できなかった。", "You've failed to concentrate hard enough."));
166 return RACIAL_FAILURE;