OSDN Git Service

Merge pull request #1421 from sikabane-works/feature/refactor-io-dump-comment
[hengbandforosx/hengbandosx.git] / src / spell-realm / spells-craft.cpp
1 #include "spell-realm/spells-craft.h"
2 #include "avatar/avatar.h"
3 #include "core/disturbance.h"
4 #include "core/player-redraw-types.h"
5 #include "core/player-update-types.h"
6 #include "core/stuff-handler.h"
7 #include "flavor/flavor-describer.h"
8 #include "flavor/object-flavor-types.h"
9 #include "floor/floor-object.h"
10 #include "game-option/disturbance-options.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "io/input-key-acceptor.h"
13 #include "object-enchant/object-ego.h"
14 #include "object-hook/hook-checker.h"
15 #include "object-hook/hook-enchant.h"
16 #include "object/item-use-flags.h"
17 #include "object/object-flags.h"
18 #include "player-info/equipment-info.h"
19 #include "player/attack-defense-types.h"
20 #include "player/special-defense-types.h"
21 #include "racial/racial-android.h"
22 #include "spell/spells-object.h"
23 #include "sv-definition/sv-protector-types.h"
24 #include "system/object-type-definition.h"
25 #include "system/player-type-definition.h"
26 #include "term/screen-processor.h"
27 #include "term/term-color-types.h"
28 #include "view/display-messages.h"
29
30 /*!
31  * @brief 一時的元素スレイの継続時間をセットする / Set a temporary elemental brand. Clear all other brands. Print status messages. -LM-
32  * @param attack_type スレイのタイプID
33  * @param v 継続時間
34  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
35  */
36 bool set_ele_attack(player_type *creature_ptr, uint32_t attack_type, TIME_EFFECT v)
37 {
38     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
39
40     if ((creature_ptr->special_attack & (ATTACK_ACID)) && (attack_type != ATTACK_ACID)) {
41         creature_ptr->special_attack &= ~(ATTACK_ACID);
42         msg_print(_("酸で攻撃できなくなった。", "Your temporary acidic brand fades away."));
43     }
44
45     if ((creature_ptr->special_attack & (ATTACK_ELEC)) && (attack_type != ATTACK_ELEC)) {
46         creature_ptr->special_attack &= ~(ATTACK_ELEC);
47         msg_print(_("電撃で攻撃できなくなった。", "Your temporary electrical brand fades away."));
48     }
49
50     if ((creature_ptr->special_attack & (ATTACK_FIRE)) && (attack_type != ATTACK_FIRE)) {
51         creature_ptr->special_attack &= ~(ATTACK_FIRE);
52         msg_print(_("火炎で攻撃できなくなった。", "Your temporary fiery brand fades away."));
53     }
54
55     if ((creature_ptr->special_attack & (ATTACK_COLD)) && (attack_type != ATTACK_COLD)) {
56         creature_ptr->special_attack &= ~(ATTACK_COLD);
57         msg_print(_("冷気で攻撃できなくなった。", "Your temporary frost brand fades away."));
58     }
59
60     if ((creature_ptr->special_attack & (ATTACK_POIS)) && (attack_type != ATTACK_POIS)) {
61         creature_ptr->special_attack &= ~(ATTACK_POIS);
62         msg_print(_("毒で攻撃できなくなった。", "Your temporary poison brand fades away."));
63     }
64
65     if ((v) && (attack_type)) {
66         creature_ptr->special_attack |= (attack_type);
67         creature_ptr->ele_attack = v;
68 #ifdef JP
69         msg_format("%sで攻撃できるようになった!",
70             ((attack_type == ATTACK_ACID)
71                     ? "酸"
72                     : ((attack_type == ATTACK_ELEC)
73                             ? "電撃"
74                             : ((attack_type == ATTACK_FIRE) ? "火炎"
75                                                             : ((attack_type == ATTACK_COLD) ? "冷気" : ((attack_type == ATTACK_POIS) ? "毒" : "(なし)"))))));
76 #else
77         msg_format("For a while, the blows you deal will %s",
78             ((attack_type == ATTACK_ACID)
79                     ? "melt with acid!"
80                     : ((attack_type == ATTACK_ELEC)
81                             ? "shock your foes!"
82                             : ((attack_type == ATTACK_FIRE)
83                                     ? "burn with fire!"
84                                     : ((attack_type == ATTACK_COLD) ? "chill to the bone!"
85                                                                     : ((attack_type == ATTACK_POIS) ? "poison your enemies!" : "do nothing special."))))));
86 #endif
87     }
88
89     if (disturb_state)
90         disturb(creature_ptr, false, false);
91     creature_ptr->redraw |= (PR_STATUS);
92     creature_ptr->update |= (PU_BONUS);
93     handle_stuff(creature_ptr);
94
95     return true;
96 }
97
98 /*!
99  * @brief 一時的元素免疫の継続時間をセットする / Set a temporary elemental brand.  Clear all other brands.  Print status messages. -LM-
100  * @param immune_type 免疫のタイプID
101  * @param v 継続時間
102  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
103  */
104 bool set_ele_immune(player_type *creature_ptr, uint32_t immune_type, TIME_EFFECT v)
105 {
106     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
107
108     if ((creature_ptr->special_defense & (DEFENSE_ACID)) && (immune_type != DEFENSE_ACID)) {
109         creature_ptr->special_defense &= ~(DEFENSE_ACID);
110         msg_print(_("酸の攻撃で傷つけられるようになった。。", "You are no longer immune to acid."));
111     }
112
113     if ((creature_ptr->special_defense & (DEFENSE_ELEC)) && (immune_type != DEFENSE_ELEC)) {
114         creature_ptr->special_defense &= ~(DEFENSE_ELEC);
115         msg_print(_("電撃の攻撃で傷つけられるようになった。。", "You are no longer immune to electricity."));
116     }
117
118     if ((creature_ptr->special_defense & (DEFENSE_FIRE)) && (immune_type != DEFENSE_FIRE)) {
119         creature_ptr->special_defense &= ~(DEFENSE_FIRE);
120         msg_print(_("火炎の攻撃で傷つけられるようになった。。", "You are no longer immune to fire."));
121     }
122
123     if ((creature_ptr->special_defense & (DEFENSE_COLD)) && (immune_type != DEFENSE_COLD)) {
124         creature_ptr->special_defense &= ~(DEFENSE_COLD);
125         msg_print(_("冷気の攻撃で傷つけられるようになった。。", "You are no longer immune to cold."));
126     }
127
128     if ((creature_ptr->special_defense & (DEFENSE_POIS)) && (immune_type != DEFENSE_POIS)) {
129         creature_ptr->special_defense &= ~(DEFENSE_POIS);
130         msg_print(_("毒の攻撃で傷つけられるようになった。。", "You are no longer immune to poison."));
131     }
132
133     if ((v) && (immune_type)) {
134         creature_ptr->special_defense |= (immune_type);
135         creature_ptr->ele_immune = v;
136         msg_format(_("%sの攻撃を受けつけなくなった!", "For a while, you are immune to %s"),
137             ((immune_type == DEFENSE_ACID)
138                     ? _("酸", "acid!")
139                     : ((immune_type == DEFENSE_ELEC)
140                             ? _("電撃", "electricity!")
141                             : ((immune_type == DEFENSE_FIRE)
142                                     ? _("火炎", "fire!")
143                                     : ((immune_type == DEFENSE_COLD)
144                                             ? _("冷気", "cold!")
145                                             : ((immune_type == DEFENSE_POIS) ? _("毒", "poison!") : _("(なし)", "nothing special.")))))));
146     }
147
148     if (disturb_state)
149         disturb(creature_ptr, false, false);
150     creature_ptr->redraw |= (PR_STATUS);
151     creature_ptr->update |= (PU_BONUS);
152     handle_stuff(creature_ptr);
153
154     return true;
155 }
156
157 /*
158  * Choose a warrior-mage elemental attack. -LM-
159  */
160 bool choose_ele_attack(player_type *creature_ptr)
161 {
162     if (!has_melee_weapon(creature_ptr, INVEN_MAIN_HAND) && !has_melee_weapon(creature_ptr, INVEN_SUB_HAND)) {
163         msg_format(_("武器を持たないと魔法剣は使えない。", "You cannot use temporary branding with no weapon."));
164         return false;
165     }
166
167     screen_save();
168     int num = (creature_ptr->lev - 20) / 5;
169     c_prt(TERM_RED, _("        a) 焼棄", "        a) Fire Brand"), 2, 14);
170
171     if (num >= 2)
172         c_prt(TERM_L_WHITE, _("        b) 凍結", "        b) Cold Brand"), 3, 14);
173     else
174         prt("", 3, 14);
175
176     if (num >= 3)
177         c_prt(TERM_GREEN, _("        c) 毒殺", "        c) Poison Brand"), 4, 14);
178     else
179         prt("", 4, 14);
180
181     if (num >= 4)
182         c_prt(TERM_L_DARK, _("        d) 溶解", "        d) Acid Brand"), 5, 14);
183     else
184         prt("", 5, 14);
185
186     if (num >= 5)
187         c_prt(TERM_BLUE, _("        e) 電撃", "        e) Elec Brand"), 6, 14);
188     else
189         prt("", 6, 14);
190
191     prt("", 7, 14);
192     prt("", 8, 14);
193     prt("", 9, 14);
194
195     prt("", 1, 0);
196     prt(_("        どの元素攻撃をしますか?", "        Choose a temporary elemental brand "), 1, 14);
197
198     char choice = inkey();
199
200     if ((choice == 'a') || (choice == 'A'))
201         set_ele_attack(creature_ptr, ATTACK_FIRE, creature_ptr->lev / 2 + randint1(creature_ptr->lev / 2));
202     else if (((choice == 'b') || (choice == 'B')) && (num >= 2))
203         set_ele_attack(creature_ptr, ATTACK_COLD, creature_ptr->lev / 2 + randint1(creature_ptr->lev / 2));
204     else if (((choice == 'c') || (choice == 'C')) && (num >= 3))
205         set_ele_attack(creature_ptr, ATTACK_POIS, creature_ptr->lev / 2 + randint1(creature_ptr->lev / 2));
206     else if (((choice == 'd') || (choice == 'D')) && (num >= 4))
207         set_ele_attack(creature_ptr, ATTACK_ACID, creature_ptr->lev / 2 + randint1(creature_ptr->lev / 2));
208     else if (((choice == 'e') || (choice == 'E')) && (num >= 5))
209         set_ele_attack(creature_ptr, ATTACK_ELEC, creature_ptr->lev / 2 + randint1(creature_ptr->lev / 2));
210     else {
211         msg_print(_("魔法剣を使うのをやめた。", "You cancel the temporary branding."));
212         screen_load();
213         return false;
214     }
215
216     screen_load();
217     return true;
218 }
219 /*
220  * Choose a elemental immune. -LM-
221  */
222 bool choose_ele_immune(player_type *creature_ptr, TIME_EFFECT immune_turn)
223 {
224     screen_save();
225
226     c_prt(TERM_RED, _("        a) 火炎", "        a) Immunity to fire"), 2, 14);
227     c_prt(TERM_L_WHITE, _("        b) 冷気", "        b) Immunity to cold"), 3, 14);
228     c_prt(TERM_L_DARK, _("        c) 酸", "        c) Immunity to acid"), 4, 14);
229     c_prt(TERM_BLUE, _("        d) 電撃", "        d) Immunity to elec"), 5, 14);
230
231     prt("", 6, 14);
232     prt("", 7, 14);
233     prt("", 8, 14);
234     prt("", 9, 14);
235
236     prt("", 1, 0);
237     prt(_("        どの元素の免疫をつけますか?", "        Choose a temporary elemental immunity "), 1, 14);
238
239     char choice = inkey();
240
241     if ((choice == 'a') || (choice == 'A'))
242         set_ele_immune(creature_ptr, DEFENSE_FIRE, immune_turn);
243     else if ((choice == 'b') || (choice == 'B'))
244         set_ele_immune(creature_ptr, DEFENSE_COLD, immune_turn);
245     else if ((choice == 'c') || (choice == 'C'))
246         set_ele_immune(creature_ptr, DEFENSE_ACID, immune_turn);
247     else if ((choice == 'd') || (choice == 'D'))
248         set_ele_immune(creature_ptr, DEFENSE_ELEC, immune_turn);
249     else {
250         msg_print(_("免疫を付けるのをやめた。", "You cancel the temporary immunity."));
251         screen_load();
252         return false;
253     }
254
255     screen_load();
256     return true;
257 }
258
259 /*!
260  * @brief 盾磨き処理 /
261  * pulish shield
262  * @return ターン消費を要する処理を行ったならばTRUEを返す
263  */
264 bool pulish_shield(player_type *caster_ptr)
265 {
266     concptr q = _("どの盾を磨きますか?", "Polish which shield? ");
267     concptr s = _("磨く盾がありません。", "You have no shield to polish.");
268
269     OBJECT_IDX item;
270     object_type *o_ptr = choose_object(caster_ptr, &item, q, s, USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT, TvalItemTester(TV_SHIELD));
271     if (o_ptr == NULL)
272         return false;
273
274     GAME_TEXT o_name[MAX_NLEN];
275     describe_flavor(caster_ptr, o_name, o_ptr, OD_OMIT_PREFIX | OD_NAME_ONLY);
276     TrFlags flgs;
277     object_flags(o_ptr, flgs);
278
279     bool is_pulish_successful = o_ptr->k_idx && !o_ptr->is_artifact() && !o_ptr->is_ego();
280     is_pulish_successful &= !o_ptr->is_cursed();
281     is_pulish_successful &= (o_ptr->sval != SV_MIRROR_SHIELD);
282     if (is_pulish_successful) {
283 #ifdef JP
284         msg_format("%sは輝いた!", o_name);
285 #else
286         msg_format("%s %s shine%s!", ((item >= 0) ? "Your" : "The"), o_name, ((o_ptr->number > 1) ? "" : "s"));
287 #endif
288         o_ptr->name2 = EGO_REFLECTION;
289         enchant_equipment(caster_ptr, o_ptr, randint0(3) + 4, ENCH_TOAC);
290         o_ptr->discount = 99;
291         chg_virtue(caster_ptr, V_ENCHANT, 2);
292         return true;
293     }
294
295     if (flush_failure)
296         flush();
297
298     msg_print(_("失敗した。", "Failed."));
299     chg_virtue(caster_ptr, V_ENCHANT, -2);
300     calc_android_exp(caster_ptr);
301     return false;
302 }