OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / racial / racial-switcher.cpp
1 /*!
2  * @brief レイシャルと突然変異の技能処理 / Racial powers (and mutations)
3  * @date 2014/01/08
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
6  * This software may be copied and distributed for educational, research,\n
7  * and not for profit purposes provided that this copyright and statement\n
8  * are included in all such copies.  Other copyrights may also apply.\n
9  * 2014 Deskull rearranged comment for Doxygen. \n
10  */
11
12 #include "racial/racial-switcher.h"
13 #include "action/action-limited.h"
14 #include "action/mutation-execution.h"
15 #include "cmd-action/cmd-mane.h"
16 #include "cmd-action/cmd-spell.h"
17 #include "cmd-item/cmd-magiceat.h"
18 #include "cmd-item/cmd-zapwand.h"
19 #include "core/stuff-handler.h"
20 #include "core/window-redrawer.h"
21 #include "effect/spells-effect-util.h"
22 #include "game-option/text-display-options.h"
23 #include "inventory/inventory-slot-types.h"
24 #include "io/command-repeater.h"
25 #include "io/input-key-acceptor.h"
26 #include "io/input-key-requester.h"
27 #include "main/sound-of-music.h"
28 #include "melee/melee-postprocess.h"
29 #include "mind/mind-archer.h"
30 #include "mind/mind-cavalry.h"
31 #include "mind/mind-elementalist.h"
32 #include "mind/mind-force-trainer.h"
33 #include "mind/mind-hobbit.h"
34 #include "mind/mind-mage.h"
35 #include "mind/mind-magic-eater.h"
36 #include "mind/mind-mirror-master.h"
37 #include "mind/mind-monk.h"
38 #include "mind/mind-ninja.h"
39 #include "mind/mind-priest.h"
40 #include "mind/mind-samurai.h"
41 #include "mind/mind-warrior-mage.h"
42 #include "mind/mind-warrior.h"
43 #include "mind/monk-attack.h"
44 #include "mind/stances-table.h"
45 #include "mutation/mutation-flag-types.h"
46 #include "object/item-tester-hooker.h"
47 #include "player-info/class-info.h"
48 #include "player-info/equipment-info.h"
49 #include "player-info/race-info.h"
50 #include "player-info/race-types.h"
51 #include "player-status/player-energy.h"
52 #include "player-status/player-hand-types.h"
53 #include "player/attack-defense-types.h"
54 #include "player/player-damage.h"
55 #include "player/player-status.h"
56 #include "racial/racial-android.h"
57 #include "racial/racial-balrog.h"
58 #include "racial/racial-draconian.h"
59 #include "racial/racial-kutar.h"
60 #include "racial/racial-vampire.h"
61 #include "realm/realm-names-table.h"
62 #include "spell-class/spells-mirror-master.h"
63 #include "spell-kind/spells-beam.h"
64 #include "spell-kind/spells-detection.h"
65 #include "spell-kind/spells-grid.h"
66 #include "spell-kind/spells-launcher.h"
67 #include "spell-kind/spells-neighbor.h"
68 #include "spell-kind/spells-perception.h"
69 #include "spell-kind/spells-sight.h"
70 #include "spell-kind/spells-teleport.h"
71 #include "spell-kind/spells-world.h"
72 #include "spell-realm/spells-hex.h"
73 #include "spell-realm/spells-song.h"
74 #include "spell/spells-status.h"
75 #include "status/action-setter.h"
76 #include "status/bad-status-setter.h"
77 #include "status/buff-setter.h"
78 #include "status/experience.h"
79 #include "system/player-type-definition.h"
80 #include "system/redrawing-flags-updater.h"
81 #include "target/target-getter.h"
82 #include "timed-effect/player-paralysis.h"
83 #include "timed-effect/timed-effects.h"
84 #include "util/bit-flags-calculator.h"
85 #include "util/int-char-converter.h"
86 #include "view/display-messages.h"
87
88 bool switch_class_racial_execution(PlayerType *player_ptr, const int32_t command)
89 {
90     DIRECTION dir = 0;
91     switch (player_ptr->pclass) {
92     case PlayerClassType::WARRIOR:
93         return sword_dancing(player_ptr);
94     case PlayerClassType::HIGH_MAGE:
95         if (player_ptr->realm1 == REALM_HEX) {
96             const auto retval = SpellHex(player_ptr).stop_spells_with_selection();
97             if (retval) {
98                 PlayerEnergy(player_ptr).set_player_turn_energy(10);
99             }
100
101             return retval;
102         }
103
104         [[fallthrough]];
105     case PlayerClassType::MAGE:
106     case PlayerClassType::SORCERER:
107         return eat_magic(player_ptr, player_ptr->lev * 2);
108     case PlayerClassType::PRIEST:
109         if (!is_good_realm(player_ptr->realm1)) {
110             (void)dispel_monsters(player_ptr, player_ptr->lev * 4);
111             turn_monsters(player_ptr, player_ptr->lev * 4);
112             banish_monsters(player_ptr, player_ptr->lev * 4);
113             return true;
114         }
115
116         return bless_weapon(player_ptr);
117     case PlayerClassType::ROGUE:
118         return hit_and_away(player_ptr);
119     case PlayerClassType::RANGER:
120     case PlayerClassType::SNIPER:
121         msg_print(_("敵を調査した...", "You examine your foes..."));
122         probing(player_ptr);
123         return true;
124     case PlayerClassType::PALADIN:
125         if (!get_aim_dir(player_ptr, &dir)) {
126             return false;
127         }
128
129         fire_beam(player_ptr, is_good_realm(player_ptr->realm1) ? AttributeType::HOLY_FIRE : AttributeType::HELL_FIRE, dir, player_ptr->lev * 3);
130         return true;
131     case PlayerClassType::WARRIOR_MAGE:
132         if (command == -3) {
133             return comvert_hp_to_mp(player_ptr);
134         } else if (command == -4) {
135             return comvert_mp_to_hp(player_ptr);
136         }
137
138         return true;
139     case PlayerClassType::CHAOS_WARRIOR:
140         return confusing_light(player_ptr);
141     case PlayerClassType::MONK:
142         if (none_bits(empty_hands(player_ptr, true), EMPTY_HAND_MAIN)) {
143             msg_print(_("素手じゃないとできません。", "You need to be barehanded."));
144             return false;
145         }
146
147         if (player_ptr->riding) {
148             msg_print(_("乗馬中はできません。", "You need to get off a pet."));
149             return false;
150         }
151
152         if (command == -3) {
153             if (!choose_monk_stance(player_ptr)) {
154                 return false;
155             }
156
157             RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::BONUS);
158             return true;
159         }
160
161         if (command == -4) {
162             return double_attack(player_ptr);
163         }
164
165         return true;
166     case PlayerClassType::MINDCRAFTER:
167     case PlayerClassType::FORCETRAINER:
168         return clear_mind(player_ptr);
169     case PlayerClassType::TOURIST:
170         if (command == -3) {
171             if (!get_aim_dir(player_ptr, &dir)) {
172                 return false;
173             }
174
175             project_length = 1;
176             fire_beam(player_ptr, AttributeType::PHOTO, dir, 1);
177             return true;
178         }
179
180         return (command != -4) || identify_fully(player_ptr, false);
181     case PlayerClassType::IMITATOR:
182         handle_stuff(player_ptr);
183         return do_cmd_mane(player_ptr, true);
184     case PlayerClassType::BEASTMASTER:
185         if (command == -3) {
186             if (!get_aim_dir(player_ptr, &dir)) {
187                 return false;
188             }
189
190             (void)fire_ball_hide(player_ptr, AttributeType::CHARM_LIVING, dir, player_ptr->lev, 0);
191             return true;
192         }
193
194         if (command == -4) {
195             project_all_los(player_ptr, AttributeType::CHARM_LIVING, player_ptr->lev);
196         }
197
198         return true;
199     case PlayerClassType::ARCHER:
200         return create_ammo(player_ptr);
201     case PlayerClassType::MAGIC_EATER:
202         if (command == -3) {
203             return import_magic_device(player_ptr);
204         }
205
206         return (command != -4) || (!cmd_limit_cast(player_ptr) && do_cmd_magic_eater(player_ptr, false, true));
207     case PlayerClassType::BARD:
208         if ((get_singing_song_effect(player_ptr) == 0) && (get_interrupting_song_effect(player_ptr) == 0)) {
209             return false;
210         }
211
212         stop_singing(player_ptr);
213         PlayerEnergy(player_ptr).set_player_turn_energy(10);
214         return true;
215     case PlayerClassType::RED_MAGE:
216         if (cmd_limit_cast(player_ptr)) {
217             return false;
218         }
219
220         handle_stuff(player_ptr);
221         if (!do_cmd_cast(player_ptr)) {
222             return false;
223         }
224
225         if (!player_ptr->effects()->paralysis()->is_paralyzed() && !cmd_limit_cast(player_ptr)) {
226             handle_stuff(player_ptr);
227             command_dir = 0;
228             (void)do_cmd_cast(player_ptr);
229         }
230         return true;
231     case PlayerClassType::SAMURAI:
232         if (command == -3) {
233             concentration(player_ptr);
234             return true;
235         }
236
237         if (command != -4) {
238             return true;
239         }
240
241         if (!has_melee_weapon(player_ptr, INVEN_MAIN_HAND) && !has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
242             msg_print(_("武器を持たないといけません。", "You need to wield a weapon."));
243             return false;
244         }
245
246         if (!choose_samurai_stance(player_ptr)) {
247             return false;
248         }
249
250         RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::BONUS);
251         return true;
252     case PlayerClassType::BLUE_MAGE:
253         set_action(player_ptr, player_ptr->action == ACTION_LEARN ? ACTION_NONE : ACTION_LEARN);
254         PlayerEnergy(player_ptr).reset_player_turn();
255         return true;
256     case PlayerClassType::CAVALRY:
257         return rodeo(player_ptr);
258     case PlayerClassType::BERSERKER:
259         return recall_player(player_ptr, randint0(21) + 15);
260     case PlayerClassType::SMITH:
261         if (player_ptr->lev <= 29) {
262             return ident_spell(player_ptr, true);
263         }
264
265         return identify_fully(player_ptr, true);
266     case PlayerClassType::MIRROR_MASTER: {
267         SpellsMirrorMaster smm(player_ptr);
268         if (command == -3) {
269             smm.remove_all_mirrors(true);
270             return true;
271         }
272
273         if (command == -4) {
274             return smm.mirror_concentration();
275         }
276
277         return true;
278     }
279     case PlayerClassType::NINJA:
280         return hayagake(player_ptr);
281     case PlayerClassType::ELEMENTALIST:
282         if (command == -3) {
283             return clear_mind(player_ptr);
284         }
285         if (command == -4) {
286             return switch_element_execution(player_ptr);
287         }
288         return true;
289     default:
290         return true;
291     }
292 }
293
294 bool switch_mimic_racial_execution(PlayerType *player_ptr)
295 {
296     switch (player_ptr->mimic_form) {
297     case MimicKindType::DEMON:
298     case MimicKindType::DEMON_LORD: {
299         return demonic_breath(player_ptr);
300     }
301     case MimicKindType::VAMPIRE:
302         vampirism(player_ptr);
303         return true;
304     default:
305         return true;
306     }
307 }
308
309 bool switch_race_racial_execution(PlayerType *player_ptr, const int32_t command)
310 {
311     DIRECTION dir = 0;
312     switch (player_ptr->prace) {
313     case PlayerRaceType::DWARF:
314         msg_print(_("周囲を調べた。", "You examine your surroundings."));
315         (void)detect_traps(player_ptr, DETECT_RAD_DEFAULT, true);
316         (void)detect_doors(player_ptr, DETECT_RAD_DEFAULT);
317         (void)detect_stairs(player_ptr, DETECT_RAD_DEFAULT);
318         return true;
319     case PlayerRaceType::HOBBIT:
320         return create_ration(player_ptr);
321     case PlayerRaceType::GNOME:
322         msg_print(_("パッ!", "Blink!"));
323         teleport_player(player_ptr, 10, TELEPORT_SPONTANEOUS);
324         return true;
325     case PlayerRaceType::HALF_ORC:
326         msg_print(_("勇気を出した。", "You play tough."));
327         (void)BadStatusSetter(player_ptr).set_fear(0);
328         return true;
329     case PlayerRaceType::HALF_TROLL:
330         msg_print(_("うがぁぁ!", "RAAAGH!"));
331         (void)berserk(player_ptr, 10 + randint1(player_ptr->lev));
332         return true;
333     case PlayerRaceType::AMBERITE:
334         if (command == -1) {
335             msg_print(_("あなたは歩き周り始めた。", "You start walking around. "));
336             reserve_alter_reality(player_ptr, randint0(21) + 15);
337             return true;
338         }
339
340         if (command != -2) {
341             return true;
342         }
343
344         msg_print(_("あなたは「パターン」を心に描いてその上を歩いた...", "You picture the Pattern in your mind and walk it..."));
345         (void)true_healing(player_ptr, 0);
346         (void)restore_all_status(player_ptr);
347         (void)restore_level(player_ptr);
348         return true;
349     case PlayerRaceType::BARBARIAN:
350         msg_print(_("うぉぉおお!", "Raaagh!"));
351         (void)berserk(player_ptr, 10 + randint1(player_ptr->lev));
352         return true;
353     case PlayerRaceType::HALF_OGRE:
354         msg_print(_("爆発のルーンを慎重に仕掛けた...", "You carefully set an explosive rune..."));
355         (void)create_rune_explosion(player_ptr, player_ptr->y, player_ptr->x);
356         return true;
357     case PlayerRaceType::HALF_GIANT:
358         if (!get_aim_dir(player_ptr, &dir)) {
359             return false;
360         }
361
362         (void)wall_to_mud(player_ptr, dir, 20 + randint1(30));
363         return true;
364     case PlayerRaceType::HALF_TITAN:
365         msg_print(_("敵を調査した...", "You examine your foes..."));
366         (void)probing(player_ptr);
367         return true;
368     case PlayerRaceType::CYCLOPS:
369         if (!get_aim_dir(player_ptr, &dir)) {
370             return false;
371         }
372
373         msg_print(_("巨大な岩を投げた。", "You throw a huge boulder."));
374         (void)fire_bolt(player_ptr, AttributeType::MISSILE, dir, (3 * player_ptr->lev) / 2);
375         return true;
376     case PlayerRaceType::YEEK:
377         if (!get_aim_dir(player_ptr, &dir)) {
378             return false;
379         }
380
381         stop_mouth(player_ptr);
382         msg_print(_("身の毛もよだつ叫び声を上げた!", "You make a horrible scream!"));
383         (void)fear_monster(player_ptr, dir, player_ptr->lev);
384         return true;
385     case PlayerRaceType::KLACKON:
386         if (!get_aim_dir(player_ptr, &dir)) {
387             return false;
388         }
389
390         stop_mouth(player_ptr);
391         msg_print(_("酸を吐いた。", "You spit acid."));
392         if (player_ptr->lev < 25) {
393             (void)fire_bolt(player_ptr, AttributeType::ACID, dir, player_ptr->lev);
394         } else {
395             (void)fire_ball(player_ptr, AttributeType::ACID, dir, player_ptr->lev, 2);
396         }
397
398         return true;
399     case PlayerRaceType::KOBOLD:
400         if (!get_aim_dir(player_ptr, &dir)) {
401             return false;
402         }
403
404         msg_print(_("毒のダーツを投げた。", "You throw a poisoned dart."));
405         (void)fire_bolt(player_ptr, AttributeType::POIS, dir, player_ptr->lev);
406         return true;
407     case PlayerRaceType::NIBELUNG:
408         msg_print(_("周囲を調査した。", "You examine your surroundings."));
409         (void)detect_traps(player_ptr, DETECT_RAD_DEFAULT, true);
410         (void)detect_doors(player_ptr, DETECT_RAD_DEFAULT);
411         (void)detect_stairs(player_ptr, DETECT_RAD_DEFAULT);
412         return true;
413     case PlayerRaceType::DARK_ELF:
414         if (!get_aim_dir(player_ptr, &dir)) {
415             return false;
416         }
417
418         msg_print(_("マジック・ミサイルを放った。", "You cast a magic missile."));
419         (void)fire_bolt_or_beam(player_ptr, 10, AttributeType::MISSILE, dir, damroll(3 + ((player_ptr->lev - 1) / 5), 4));
420         return true;
421     case PlayerRaceType::DRACONIAN:
422         return draconian_breath(player_ptr);
423     case PlayerRaceType::MIND_FLAYER:
424         if (!get_aim_dir(player_ptr, &dir)) {
425             return false;
426         }
427
428         msg_print(_("あなたは集中し、目が赤く輝いた...", "You concentrate and your eyes glow red..."));
429         (void)fire_bolt(player_ptr, AttributeType::PSI, dir, player_ptr->lev);
430         return true;
431     case PlayerRaceType::IMP:
432         if (!get_aim_dir(player_ptr, &dir)) {
433             return false;
434         }
435
436         if (player_ptr->lev >= 30) {
437             msg_print(_("ファイア・ボールを放った。", "You cast a ball of fire."));
438             (void)fire_ball(player_ptr, AttributeType::FIRE, dir, player_ptr->lev, 2);
439         } else {
440             msg_print(_("ファイア・ボルトを放った。", "You cast a bolt of fire."));
441             (void)fire_bolt(player_ptr, AttributeType::FIRE, dir, player_ptr->lev);
442         }
443
444         return true;
445     case PlayerRaceType::GOLEM:
446         (void)set_shield(player_ptr, randint1(20) + 30, false);
447         return true;
448     case PlayerRaceType::SKELETON:
449     case PlayerRaceType::ZOMBIE:
450         msg_print(_("あなたは失ったエネルギーを取り戻そうと試みた。", "You attempt to restore your lost energies."));
451         (void)restore_level(player_ptr);
452         return true;
453     case PlayerRaceType::VAMPIRE:
454         (void)vampirism(player_ptr);
455         return true;
456     case PlayerRaceType::SPECTRE:
457         if (!get_aim_dir(player_ptr, &dir)) {
458             return false;
459         }
460
461         stop_mouth(player_ptr);
462         msg_print(_("あなたはおどろおどろしい叫び声をあげた!", "You emit an eldritch howl!"));
463         (void)fear_monster(player_ptr, dir, player_ptr->lev);
464         return true;
465     case PlayerRaceType::SPRITE:
466         msg_print(_("あなたは魔法の粉を投げつけた...", "You throw some magic dust..."));
467         if (player_ptr->lev < 25) {
468             (void)sleep_monsters_touch(player_ptr);
469         } else {
470             (void)sleep_monsters(player_ptr, player_ptr->lev);
471         }
472
473         return true;
474     case PlayerRaceType::BALROG:
475         return demonic_breath(player_ptr);
476     case PlayerRaceType::KUTAR:
477         (void)set_leveling(player_ptr, randint1(20) + 30, false);
478         return true;
479     case PlayerRaceType::ANDROID:
480         return android_inside_weapon(player_ptr);
481     default:
482         msg_print(_("この種族は特殊な能力を持っていません。", "This race has no bonus power."));
483         PlayerEnergy(player_ptr).reset_player_turn();
484         return true;
485     }
486 }