OSDN Git Service

f48a772c031df27df8f1b421d4c634aebac2eb02
[hengbandforosx/hengbandosx.git] / src / status / shape-changer.cpp
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/player-update-types.h"
9 #include "core/stuff-handler.h"
10 #include "game-option/disturbance-options.h"
11 #include "grid/grid.h"
12 #include "hpmp/hp-mp-processor.h"
13 #include "mutation/mutation-investor-remover.h"
14 #include "player/player-class.h"
15 #include "player/player-damage.h"
16 #include "player/player-personality.h"
17 #include "player/player-sex.h"
18 #include "player/player-status.h"
19 #include "player/race-info-table.h"
20 #include "spell/spells-status.h"
21 #include "status/bad-status-setter.h"
22 #include "status/base-status.h"
23 #include "system/player-type-definition.h"
24 #include "util/enum-converter.h"
25 #include "view/display-messages.h"
26 #ifdef JP
27 #else
28 #include "locale/english.h"
29 #endif
30
31 void do_poly_wounds(player_type *creature_ptr)
32 {
33     int16_t wounds = creature_ptr->cut;
34     int16_t hit_p = (creature_ptr->mhp - creature_ptr->chp);
35     int16_t change = damroll(creature_ptr->lev, 5);
36     bool Nasty_effect = one_in_(5);
37     if (!(wounds || hit_p || Nasty_effect))
38         return;
39
40     msg_print(_("傷がより軽いものに変化した。", "Your wounds are polymorphed into less serious ones."));
41     hp_player(creature_ptr, change);
42     if (Nasty_effect) {
43         msg_print(_("新たな傷ができた!", "A new wound was created!"));
44         take_hit(creature_ptr, DAMAGE_LOSELIFE, change / 2, _("変化した傷", "a polymorphed wound"));
45         set_cut(creature_ptr, change);
46     } else {
47         set_cut(creature_ptr, creature_ptr->cut - (change / 2));
48     }
49 }
50
51 /*
52  * Change player race
53  */
54 void change_race(player_type *creature_ptr, player_race_type new_race, concptr effect_msg)
55 {
56     concptr title = race_info[enum2i(new_race)].title;
57     player_race_type old_race = creature_ptr->prace;
58 #ifdef JP
59     msg_format("あなたは%s%sに変化した!", effect_msg, title);
60 #else
61     msg_format("You turn into %s %s%s!", (is_a_vowel((effect_msg[0]) ? effect_msg[0] : title[0]) ? "an" : "a"), effect_msg, title);
62 #endif
63
64     chg_virtue(creature_ptr, V_CHANCE, 2);
65     if (enum2i(creature_ptr->prace) < 32) {
66         creature_ptr->old_race1 |= 1UL << enum2i(creature_ptr->prace);
67     } else {
68         creature_ptr->old_race2 |= 1UL << (enum2i(creature_ptr->prace) - 32);
69     }
70
71     creature_ptr->prace = new_race;
72     rp_ptr = &race_info[enum2i(creature_ptr->prace)];
73     creature_ptr->expfact = rp_ptr->r_exp + cp_ptr->c_exp;
74
75     bool is_special_class = creature_ptr->pclass == CLASS_MONK;
76     is_special_class |= creature_ptr->pclass == CLASS_FORCETRAINER;
77     is_special_class |= creature_ptr->pclass == CLASS_NINJA;
78     bool is_special_race = creature_ptr->prace == player_race_type::KLACKON;
79     is_special_race |= creature_ptr->prace == player_race_type::SPRITE;
80     if (is_special_class && is_special_race)
81         creature_ptr->expfact -= 15;
82
83     get_height_weight(creature_ptr);
84
85     if (creature_ptr->pclass == CLASS_SORCERER)
86         creature_ptr->hitdie = rp_ptr->r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
87     else
88         creature_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
89
90     roll_hitdice(creature_ptr, SPOP_NONE);
91     check_experience(creature_ptr);
92     creature_ptr->redraw |= (PR_BASIC);
93     creature_ptr->update |= (PU_BONUS);
94     handle_stuff(creature_ptr);
95
96     if (old_race != creature_ptr->prace)
97         autopick_load_pref(creature_ptr, false);
98
99     lite_spot(creature_ptr, creature_ptr->y, creature_ptr->x);
100 }
101
102 void do_poly_self(player_type *creature_ptr)
103 {
104     int power = creature_ptr->lev;
105
106     msg_print(_("あなたは変化の訪れを感じた...", "You feel a change coming over you..."));
107     chg_virtue(creature_ptr, V_CHANCE, 1);
108
109     if ((power > randint0(20)) && one_in_(3) && (creature_ptr->prace != player_race_type::ANDROID)) {
110         char effect_msg[80] = "";
111         char sex_msg[32] = "";
112         player_race_type new_race;
113
114         power -= 10;
115         if ((power > randint0(5)) && one_in_(4)) {
116             power -= 2;
117             if (creature_ptr->psex == SEX_MALE) {
118                 creature_ptr->psex = SEX_FEMALE;
119                 sp_ptr = &sex_info[creature_ptr->psex];
120                 sprintf(sex_msg, _("女性の", "female"));
121             } else {
122                 creature_ptr->psex = SEX_MALE;
123                 sp_ptr = &sex_info[creature_ptr->psex];
124                 sprintf(sex_msg, _("男性の", "male"));
125             }
126         }
127
128         if ((power > randint0(30)) && one_in_(5)) {
129             int tmp = 0;
130             power -= 15;
131             while (tmp < A_MAX) {
132                 if (one_in_(2)) {
133                     (void)dec_stat(creature_ptr, tmp, randint1(6) + 6, one_in_(3));
134                     power -= 1;
135                 }
136                 tmp++;
137             }
138
139             (void)dec_stat(creature_ptr, A_CHR, randint1(6), true);
140
141             if (sex_msg[0]) {
142                 sprintf(effect_msg, _("奇形の%s", "deformed %s "), sex_msg);
143             } else {
144                 sprintf(effect_msg, _("奇形の", "deformed "));
145             }
146         }
147
148         while ((power > randint0(20)) && one_in_(10)) {
149             power -= 10;
150
151             if (!lose_mutation(creature_ptr, 0))
152                 msg_print(_("奇妙なくらい普通になった気がする。", "You feel oddly normal."));
153         }
154
155         do {
156             new_race = (player_race_type)randint0(MAX_RACES);
157         } while ((new_race == creature_ptr->prace) || (new_race == player_race_type::ANDROID));
158
159         change_race(creature_ptr, new_race, effect_msg);
160     }
161
162     if ((power > randint0(30)) && one_in_(6)) {
163         int tmp = 0;
164         power -= 20;
165         msg_format(_("%sの構成が変化した!", "Your internal organs are rearranged!"), creature_ptr->prace == player_race_type::ANDROID ? "機械" : "内臓");
166
167         while (tmp < A_MAX) {
168             (void)dec_stat(creature_ptr, tmp, randint1(6) + 6, one_in_(3));
169             tmp++;
170         }
171         if (one_in_(6)) {
172             msg_print(_("現在の姿で生きていくのは困難なようだ!", "You find living difficult in your present form!"));
173             take_hit(creature_ptr, DAMAGE_LOSELIFE, damroll(randint1(10), creature_ptr->lev), _("致命的な突然変異", "a lethal mutation"));
174
175             power -= 10;
176         }
177     }
178
179     if ((power > randint0(20)) && one_in_(4)) {
180         power -= 10;
181
182         get_max_stats(creature_ptr);
183         roll_hitdice(creature_ptr, SPOP_NONE);
184     }
185
186     while ((power > randint0(15)) && one_in_(3)) {
187         power -= 7;
188         (void)gain_mutation(creature_ptr, 0);
189     }
190
191     if (power > randint0(5)) {
192         power -= 5;
193         do_poly_wounds(creature_ptr);
194     }
195
196     while (power > 0) {
197         status_shuffle(creature_ptr);
198         power--;
199     }
200 }