OSDN Git Service

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