1 #include "status/shape-changer.h"
2 #include "autopick/autopick-reader-writer.h"
3 #include "avatar/avatar.h"
4 #include "birth/birth-body-spec.h"
5 #include "birth/birth-stat.h"
6 #include "core/disturbance.h"
7 #include "core/player-redraw-types.h"
8 #include "core/stuff-handler.h"
9 #include "game-option/disturbance-options.h"
10 #include "grid/grid.h"
11 #include "hpmp/hp-mp-processor.h"
12 #include "locale/english.h"
13 #include "mutation/mutation-investor-remover.h"
14 #include "player-base/player-class.h"
15 #include "player-base/player-race.h"
16 #include "player-info/class-info.h"
17 #include "player/player-damage.h"
18 #include "player/player-personality.h"
19 #include "player/player-sex.h"
20 #include "player/player-status.h"
21 #include "player/race-info-table.h"
22 #include "spell/spells-status.h"
23 #include "status/bad-status-setter.h"
24 #include "status/base-status.h"
25 #include "system/player-type-definition.h"
26 #include "system/redrawing-flags-updater.h"
27 #include "timed-effect/player-cut.h"
28 #include "timed-effect/timed-effects.h"
29 #include "util/enum-converter.h"
30 #include "view/display-messages.h"
32 void do_poly_wounds(PlayerType *player_ptr)
34 int16_t hit_p = (player_ptr->mhp - player_ptr->chp);
35 int16_t change = damroll(player_ptr->lev, 5);
36 auto nasty_effect = one_in_(5);
37 auto player_cut = player_ptr->effects()->cut();
38 if (!player_cut->is_cut() && (hit_p == 0) && !nasty_effect) {
42 msg_print(_("傷がより軽いものに変化した。", "Your wounds are polymorphed into less serious ones."));
43 hp_player(player_ptr, change);
44 BadStatusSetter bss(player_ptr);
46 (void)bss.mod_cut(change / 2);
50 msg_print(_("新たな傷ができた!", "A new wound was created!"));
51 take_hit(player_ptr, DAMAGE_LOSELIFE, change / 2, _("変化した傷", "a polymorphed wound"));
52 (void)bss.set_cut(change);
58 void change_race(PlayerType *player_ptr, PlayerRaceType new_race, concptr effect_msg)
60 concptr title = race_info[enum2i(new_race)].title;
61 PlayerRaceType old_race = player_ptr->prace;
63 msg_format("あなたは%s%sに変化した!", effect_msg, title);
65 msg_format("You turn into %s %s%s!", (is_a_vowel((effect_msg[0]) ? effect_msg[0] : title[0]) ? "an" : "a"), effect_msg, title);
68 chg_virtue(player_ptr, Virtue::CHANCE, 2);
69 if (enum2i(player_ptr->prace) < 32) {
70 player_ptr->old_race1 |= 1UL << enum2i(player_ptr->prace);
72 player_ptr->old_race2 |= 1UL << (enum2i(player_ptr->prace) - 32);
75 player_ptr->prace = new_race;
76 rp_ptr = &race_info[enum2i(player_ptr->prace)];
77 player_ptr->expfact = rp_ptr->r_exp + cp_ptr->c_exp;
79 PlayerClass pc(player_ptr);
80 bool is_special_class = pc.equals(PlayerClassType::MONK);
81 is_special_class |= pc.equals(PlayerClassType::FORCETRAINER);
82 is_special_class |= pc.equals(PlayerClassType::NINJA);
83 PlayerRace pr(player_ptr);
84 bool is_special_race = pr.equals(PlayerRaceType::KLACKON);
85 is_special_race |= pr.equals(PlayerRaceType::SPRITE);
86 if (is_special_class && is_special_race) {
87 player_ptr->expfact -= 15;
90 get_height_weight(player_ptr);
92 if (pc.equals(PlayerClassType::SORCERER)) {
93 player_ptr->hitdie = rp_ptr->r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
95 player_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
98 roll_hitdice(player_ptr, SPOP_NONE);
99 check_experience(player_ptr);
100 auto &rfu = RedrawingFlagsUpdater::get_instance();
101 rfu.set_flag(MainWindowRedrawingFlag::BASIC);
102 rfu.set_flag(StatusRedrawingFlag::BONUS);
103 handle_stuff(player_ptr);
105 if (old_race != player_ptr->prace) {
106 autopick_load_pref(player_ptr, false);
109 lite_spot(player_ptr, player_ptr->y, player_ptr->x);
112 void do_poly_self(PlayerType *player_ptr)
114 int power = player_ptr->lev;
116 msg_print(_("あなたは変化の訪れを感じた...", "You feel a change coming over you..."));
117 chg_virtue(player_ptr, Virtue::CHANCE, 1);
119 PlayerRace pr(player_ptr);
120 if ((power > randint0(20)) && one_in_(3) && !pr.equals(PlayerRaceType::ANDROID)) {
121 std::string effect_msg;
122 std::string_view sex_msg;
123 PlayerRaceType new_race;
126 if ((power > randint0(5)) && one_in_(4)) {
128 if (player_ptr->psex == SEX_MALE) {
129 player_ptr->psex = SEX_FEMALE;
130 sp_ptr = &sex_info[player_ptr->psex];
131 sex_msg = _("女性の", "female");
133 player_ptr->psex = SEX_MALE;
134 sp_ptr = &sex_info[player_ptr->psex];
135 sex_msg = _("男性の", "male");
139 if ((power > randint0(30)) && one_in_(5)) {
142 while (tmp < A_MAX) {
144 (void)dec_stat(player_ptr, tmp, randint1(6) + 6, one_in_(3));
150 (void)dec_stat(player_ptr, A_CHR, randint1(6), true);
152 effect_msg = _("奇形の", "deformed ");
153 if (!sex_msg.empty()) {
154 effect_msg.append(sex_msg).append(_("", " "));
158 while ((power > randint0(20)) && one_in_(10)) {
161 if (!lose_mutation(player_ptr, 0)) {
162 msg_print(_("奇妙なくらい普通になった気がする。", "You feel oddly normal."));
167 new_race = (PlayerRaceType)randint0(MAX_RACES);
168 } while (pr.equals(new_race) || (new_race == PlayerRaceType::ANDROID));
170 change_race(player_ptr, new_race, effect_msg.data());
173 if ((power > randint0(30)) && one_in_(6)) {
176 msg_print(_(format("%sの構成が変化した!", pr.equals(PlayerRaceType::ANDROID) ? "機械" : "内臓"), "Your internal organs are rearranged!"));
178 while (tmp < A_MAX) {
179 (void)dec_stat(player_ptr, tmp, randint1(6) + 6, one_in_(3));
183 msg_print(_("現在の姿で生きていくのは困難なようだ!", "You find living difficult in your present form!"));
184 take_hit(player_ptr, DAMAGE_LOSELIFE, damroll(randint1(10), player_ptr->lev), _("致命的な突然変異", "a lethal mutation"));
190 if ((power > randint0(20)) && one_in_(4)) {
193 get_max_stats(player_ptr);
194 roll_hitdice(player_ptr, SPOP_NONE);
197 while ((power > randint0(15)) && one_in_(3)) {
199 (void)gain_mutation(player_ptr, 0);
202 if (power > randint0(5)) {
204 do_poly_wounds(player_ptr);
208 status_shuffle(player_ptr);