1 #include "cmd-item/cmd-zaprod.h"
2 #include "action/action-limited.h"
3 #include "core/player-update-types.h"
4 #include "core/window-redrawer.h"
5 #include "floor/floor-object.h"
6 #include "game-option/disturbance-options.h"
7 #include "main/sound-definitions-table.h"
8 #include "main/sound-of-music.h"
9 #include "object-enchant/special-object-flags.h"
10 #include "object/item-use-flags.h"
11 #include "object/object-info.h"
12 #include "object/object-kind.h"
13 #include "perception/object-perception.h"
14 #include "player/attack-defense-types.h"
15 #include "player-info/avatar.h"
16 #include "player-status/player-energy.h"
17 #include "player/player-class.h"
18 #include "player/special-defense-types.h"
19 #include "spell-kind/spells-beam.h"
20 #include "spell-kind/spells-detection.h"
21 #include "spell-kind/spells-floor.h"
22 #include "spell-kind/spells-launcher.h"
23 #include "spell-kind/spells-lite.h"
24 #include "spell-kind/spells-neighbor.h"
25 #include "spell-kind/spells-perception.h"
26 #include "spell-kind/spells-random.h"
27 #include "spell-kind/spells-sight.h"
28 #include "spell-kind/spells-specific-bolt.h"
29 #include "spell-kind/spells-teleport.h"
30 #include "spell-kind/spells-world.h"
31 #include "spell/spell-types.h"
32 #include "spell/spells-status.h"
33 #include "status/action-setter.h"
34 #include "status/buff-setter.h"
35 #include "status/experience.h"
36 #include "status/shape-changer.h"
37 #include "sv-definition/sv-other-types.h"
38 #include "sv-definition/sv-rod-types.h"
39 #include "system/object-type-definition.h"
40 #include "system/player-type-definition.h"
41 #include "target/target-getter.h"
42 #include "term/screen-processor.h"
43 #include "util/bit-flags-calculator.h"
44 #include "view/display-messages.h"
48 * @param creature_ptr プレーヤーへの参照ポインタ
49 * @param sval オブジェクトのsval
50 * @param dir 発動目標の方向ID
51 * @param use_charge チャージを消費したかどうかを返す参照ポインタ
52 * @param powerful 強力発動上の処理ならばTRUE
53 * @param magic 魔道具術上の処理ならばTRUE
54 * @return 発動により効果内容が確定したならばTRUEを返す
56 int rod_effect(player_type *creature_ptr, OBJECT_SUBTYPE_VALUE sval, DIRECTION dir, bool *use_charge, bool powerful, bool magic)
59 PLAYER_LEVEL lev = powerful ? creature_ptr->lev * 2 : creature_ptr->lev;
60 POSITION detect_rad = powerful ? DETECT_RAD_DEFAULT * 3 / 2 : DETECT_RAD_DEFAULT;
61 POSITION rad = powerful ? 3 : 2;
68 case SV_ROD_DETECT_TRAP: {
69 if (detect_traps(creature_ptr, detect_rad, (bool)(dir ? FALSE : TRUE)))
74 case SV_ROD_DETECT_DOOR: {
75 if (detect_doors(creature_ptr, detect_rad))
77 if (detect_stairs(creature_ptr, detect_rad))
82 case SV_ROD_IDENTIFY: {
84 if (!identify_fully(creature_ptr, FALSE, TV_NONE))
87 if (!ident_spell(creature_ptr, FALSE, TV_NONE))
95 if (!recall_player(creature_ptr, randint0(21) + 15))
101 case SV_ROD_ILLUMINATION: {
102 if (lite_area(creature_ptr, damroll(2, 8), (powerful ? 4 : 2)))
107 case SV_ROD_MAPPING: {
108 map_area(creature_ptr, powerful ? DETECT_RAD_MAP * 3 / 2 : DETECT_RAD_MAP);
113 case SV_ROD_DETECTION: {
114 detect_all(creature_ptr, detect_rad);
119 case SV_ROD_PROBING: {
120 probing(creature_ptr);
125 case SV_ROD_CURING: {
126 if (true_healing(creature_ptr, 0))
128 if (set_shero(creature_ptr, 0, TRUE))
133 case SV_ROD_HEALING: {
134 if (cure_critical_wounds(creature_ptr, powerful ? 750 : 500))
139 case SV_ROD_RESTORATION: {
140 if (restore_level(creature_ptr))
142 if (restore_all_status(creature_ptr))
148 if (set_fast(creature_ptr, randint1(30) + (powerful ? 30 : 15), FALSE))
153 case SV_ROD_PESTICIDE: {
154 if (dispel_monsters(creature_ptr, powerful ? 8 : 4))
159 case SV_ROD_TELEPORT_AWAY: {
160 int distance = MAX_SIGHT * (powerful ? 8 : 5);
161 if (teleport_monster(creature_ptr, dir, distance))
166 case SV_ROD_DISARMING: {
167 if (disarm_trap(creature_ptr, dir))
169 if (powerful && disarm_traps_touch(creature_ptr))
175 HIT_POINT dam = damroll((powerful ? 12 : 6), 8);
176 msg_print(_("青く輝く光線が放たれた。", "A line of blue shimmering light appears."));
177 (void)lite_line(creature_ptr, dir, dam);
182 case SV_ROD_SLEEP_MONSTER: {
183 if (sleep_monster(creature_ptr, dir, lev))
188 case SV_ROD_SLOW_MONSTER: {
189 if (slow_monster(creature_ptr, dir, lev))
194 case SV_ROD_HYPODYNAMIA: {
195 if (hypodynamic_bolt(creature_ptr, dir, 70 + 3 * lev / 2))
200 case SV_ROD_POLYMORPH: {
201 if (poly_monster(creature_ptr, dir, lev))
206 case SV_ROD_ACID_BOLT: {
207 fire_bolt_or_beam(creature_ptr, 10, GF_ACID, dir, damroll(6 + lev / 7, 8));
212 case SV_ROD_ELEC_BOLT: {
213 fire_bolt_or_beam(creature_ptr, 10, GF_ELEC, dir, damroll(4 + lev / 9, 8));
218 case SV_ROD_FIRE_BOLT: {
219 fire_bolt_or_beam(creature_ptr, 10, GF_FIRE, dir, damroll(7 + lev / 6, 8));
224 case SV_ROD_COLD_BOLT: {
225 fire_bolt_or_beam(creature_ptr, 10, GF_COLD, dir, damroll(5 + lev / 8, 8));
230 case SV_ROD_ACID_BALL: {
231 fire_ball(creature_ptr, GF_ACID, dir, 60 + lev, rad);
236 case SV_ROD_ELEC_BALL: {
237 fire_ball(creature_ptr, GF_ELEC, dir, 40 + lev, rad);
242 case SV_ROD_FIRE_BALL: {
243 fire_ball(creature_ptr, GF_FIRE, dir, 70 + lev, rad);
248 case SV_ROD_COLD_BALL: {
249 fire_ball(creature_ptr, GF_COLD, dir, 50 + lev, rad);
255 call_chaos(creature_ptr);
260 case SV_ROD_STONE_TO_MUD: {
261 HIT_POINT dam = powerful ? 40 + randint1(60) : 20 + randint1(30);
262 if (wall_to_mud(creature_ptr, dir, dam))
267 case SV_ROD_AGGRAVATE: {
268 aggravate_monsters(creature_ptr, 0);
277 * @brief ロッドを使うコマンドのサブルーチン /
278 * Activate (zap) a Rod
279 * @param creature_ptr プレーヤーへの参照ポインタ
280 * @param item 使うオブジェクトの所持品ID
284 * Unstack fully charged rods as needed.
285 * Hack -- rods of perception/genocide can be "cancelled"
286 * All rods can be cancelled at the "Direction?" prompt
287 * pvals are defined for each rod in k_info. -LM-
290 void exe_zap_rod(player_type *creature_ptr, INVENTORY_IDX item)
292 int ident, chance, lev, fail;
297 /* Hack -- let perception get aborted */
298 bool use_charge = TRUE;
302 o_ptr = ref_item(creature_ptr, item);
304 /* Mega-Hack -- refuse to zap a pile from the ground */
305 if ((item < 0) && (o_ptr->number > 1)) {
306 msg_print(_("まずはロッドを拾わなければ。", "You must first pick up the rods."));
310 /* Get a direction (unless KNOWN not to need it) */
311 if (((o_ptr->sval >= SV_ROD_MIN_DIRECTION) && (o_ptr->sval != SV_ROD_HAVOC) && (o_ptr->sval != SV_ROD_AGGRAVATE) && (o_ptr->sval != SV_ROD_PESTICIDE))
312 || !object_is_aware(o_ptr)) {
313 /* Get a direction, allow cancel */
314 if (!get_aim_dir(creature_ptr, &dir))
318 PlayerEnergy(creature_ptr).set_player_turn_energy(100);
320 lev = k_info[o_ptr->k_idx].level;
322 /* Base chance of success */
323 chance = creature_ptr->skill_dev;
325 /* Confusion hurts skill */
326 if (creature_ptr->confused)
331 fail -= (chance - fail) * 2;
333 chance -= (fail - chance) * 2;
334 if (fail < USE_DEVICE)
336 if (chance < USE_DEVICE)
339 if (cmd_limit_time_walk(creature_ptr))
342 if (creature_ptr->pclass == CLASS_BERSERKER)
344 else if (chance > fail) {
345 if (randint0(chance * 2) < fail)
350 if (randint0(fail * 2) < chance)
360 msg_print(_("うまくロッドを使えなかった。", "You failed to use the rod properly."));
365 k_ptr = &k_info[o_ptr->k_idx];
367 /* A single rod is still charging */
368 if ((o_ptr->number == 1) && (o_ptr->timeout)) {
371 msg_print(_("このロッドはまだ魔力を充填している最中だ。", "The rod is still charging."));
374 /* A stack of rods lacks enough energy. */
375 else if ((o_ptr->number > 1) && (o_ptr->timeout > k_ptr->pval * (o_ptr->number - 1))) {
378 msg_print(_("そのロッドはまだ充填中です。", "The rods are all still charging."));
384 ident = rod_effect(creature_ptr, o_ptr->sval, dir, &use_charge, FALSE, FALSE);
386 /* Increase the timeout by the rod kind's pval. -LM- */
388 o_ptr->timeout += k_ptr->pval;
389 creature_ptr->update |= (PU_COMBINE | PU_REORDER);
391 if (!(object_is_aware(o_ptr))) {
392 chg_virtue(creature_ptr, V_PATIENCE, -1);
393 chg_virtue(creature_ptr, V_CHANCE, 1);
394 chg_virtue(creature_ptr, V_KNOWLEDGE, -1);
397 /* Tried the object */
400 /* Successfully determined the object function */
401 if (ident && !object_is_aware(o_ptr)) {
402 object_aware(creature_ptr, o_ptr);
403 gain_exp(creature_ptr, (lev + (creature_ptr->lev >> 1)) / creature_ptr->lev);
406 set_bits(creature_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST);
410 * @brief ロッドを使うコマンドのメインルーチン /
411 * @param creature_ptr プレーヤーへの参照ポインタ
414 void do_cmd_zap_rod(player_type *creature_ptr)
419 if (creature_ptr->wild_mode) {
423 if (cmd_limit_arena(creature_ptr))
426 if (creature_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN)) {
427 set_action(creature_ptr, ACTION_NONE);
430 q = _("どのロッドを振りますか? ", "Zap which rod? ");
431 s = _("使えるロッドがない。", "You have no rod to zap.");
433 if (!choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), TV_ROD))
437 exe_zap_rod(creature_ptr, item);