OSDN Git Service

c361f5f4339c80bf066e9e17e0bd0b2ed7ad9e38
[hengband/hengband.git] / src / action / activation-execution.c
1 #include "action/activation-execution.h"
2 #include "action/action-limited.h"
3 #include "art-definition/random-art-effects.h"
4 #include "artifact/artifact-info.h"
5 #include "core/window-redrawer.h"
6 #include "effect/spells-effect-util.h"
7 #include "floor/geometry.h"
8 #include "game-option/disturbance-options.h"
9 #include "game-option/input-options.h"
10 #include "main/sound-definitions-table.h"
11 #include "main/sound-of-music.h"
12 #include "monster-floor/monster-generator.h"
13 #include "monster-floor/place-monster-types.h"
14 #include "monster-race/monster-race.h"
15 #include "monster/monster-info.h"
16 #include "monster/monster-util.h"
17 #include "object-activation/activation-switcher.h"
18 #include "object-activation/activation-util.h"
19 #include "object-enchant/object-ego.h"
20 #include "object-hook/hook-enchant.h"
21 #include "object/object-info.h"
22 #include "object/object-kind.h"
23 #include "racial/racial-android.h"
24 #include "specific-object/monster-ball.h"
25 #include "spell-kind/spells-launcher.h"
26 #include "spell-kind/spells-teleport.h"
27 #include "spell-realm/spells-hex.h"
28 #include "spell/spell-types.h"
29 #include "sv-definition/sv-lite-types.h"
30 #include "sv-definition/sv-ring-types.h"
31 #include "system/artifact-type-definition.h"
32 #include "system/floor-type-definition.h"
33 #include "system/monster-type-definition.h"
34 #include "system/object-type-definition.h"
35 #include "target/target-getter.h"
36 #include "term/screen-processor.h"
37 #include "util/quarks.h"
38 #include "util/sort.h"
39 #include "view/display-messages.h"
40 #include "world/world.h"
41
42 static void decide_activation_level(player_type *user_ptr, ae_type *ae_ptr)
43 {
44     if (object_is_fixed_artifact(ae_ptr->o_ptr)) {
45         ae_ptr->lev = a_info[ae_ptr->o_ptr->name1].level;
46         return;
47     }
48
49     if (object_is_random_artifact(ae_ptr->o_ptr)) {
50         const activation_type *const act_ptr = find_activation_info(user_ptr, ae_ptr->o_ptr);
51         if (act_ptr != NULL)
52             ae_ptr->lev = act_ptr->level;
53
54         return;
55     }
56
57     if (((ae_ptr->o_ptr->tval == TV_RING) || (ae_ptr->o_ptr->tval == TV_AMULET)) && ae_ptr->o_ptr->name2)
58         ae_ptr->lev = e_info[ae_ptr->o_ptr->name2].level;
59 }
60
61 static void decide_chance_fail(player_type *user_ptr, ae_type *ae_ptr)
62 {
63     ae_ptr->chance = user_ptr->skill_dev;
64     if (user_ptr->confused)
65         ae_ptr->chance = ae_ptr->chance / 2;
66
67     ae_ptr->fail = ae_ptr->lev + 5;
68     if (ae_ptr->chance > ae_ptr->fail)
69         ae_ptr->fail -= (ae_ptr->chance - ae_ptr->fail) * 2;
70     else
71         ae_ptr->chance -= (ae_ptr->fail - ae_ptr->chance) * 2;
72
73     if (ae_ptr->fail < USE_DEVICE)
74         ae_ptr->fail = USE_DEVICE;
75
76     if (ae_ptr->chance < USE_DEVICE)
77         ae_ptr->chance = USE_DEVICE;
78 }
79
80 static void decide_activation_success(player_type *user_ptr, ae_type *ae_ptr)
81 {
82     if (user_ptr->pclass == CLASS_BERSERKER) {
83         ae_ptr->success = FALSE;
84         return;
85     }
86
87     if (ae_ptr->chance > ae_ptr->fail) {
88         ae_ptr->success = randint0(ae_ptr->chance * 2) >= ae_ptr->fail;
89         return;
90     }
91
92     ae_ptr->success = randint0(ae_ptr->fail * 2) < ae_ptr->chance;
93 }
94
95 static bool check_activation_success(ae_type *ae_ptr)
96 {
97     if (ae_ptr->success)
98         return TRUE;
99
100     if (flush_failure)
101         flush();
102
103     msg_print(_("うまく始動させることができなかった。", "You failed to activate it properly."));
104     sound(SOUND_FAIL);
105     return FALSE;
106 }
107
108 static bool check_activation_conditions(player_type *user_ptr, ae_type *ae_ptr)
109 {
110     if (!check_activation_success(ae_ptr))
111         return FALSE;
112
113     if (ae_ptr->o_ptr->timeout) {
114         msg_print(_("それは微かに音を立て、輝き、消えた...", "It whines, glows and fades..."));
115         return FALSE;
116     }
117
118     if (!ae_ptr->o_ptr->xtra4 && (ae_ptr->o_ptr->tval == TV_FLASK) && ((ae_ptr->o_ptr->sval == SV_LITE_TORCH) || (ae_ptr->o_ptr->sval == SV_LITE_LANTERN))) {
119         msg_print(_("燃料がない。", "It has no fuel."));
120         free_turn(user_ptr);
121         return FALSE;
122     }
123
124     return TRUE;
125 }
126
127 /*!
128  * @brief アイテムの発動効果を処理する。
129  * @param user_ptr プレーヤーへの参照ポインタ
130  * @param o_ptr 対象のオブジェクト構造体ポインタ
131  * @return 発動実行の是非を返す。
132  */
133 static bool activate_artifact(player_type *user_ptr, object_type *o_ptr)
134 {
135     concptr name = k_name + k_info[o_ptr->k_idx].name;
136     const activation_type *const act_ptr = find_activation_info(user_ptr, o_ptr);
137     if (!act_ptr) {
138         msg_print("Activation information is not found.");
139         return FALSE;
140     }
141
142     if (!switch_activation(user_ptr, o_ptr, act_ptr, name))
143         return FALSE;
144
145     if (act_ptr->timeout.constant >= 0) {
146         o_ptr->timeout = (s16b)act_ptr->timeout.constant;
147         if (act_ptr->timeout.dice > 0)
148             o_ptr->timeout += randint1(act_ptr->timeout.dice);
149
150         return TRUE;
151     }
152
153     switch (act_ptr->index) {
154     case ACT_BR_FIRE:
155         o_ptr->timeout = ((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_FLAMES)) ? 200 : 250;
156         return TRUE;
157     case ACT_BR_COLD:
158         o_ptr->timeout = ((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_ICE)) ? 200 : 250;
159         return TRUE;
160     case ACT_TERROR:
161         o_ptr->timeout = 3 * (user_ptr->lev + 10);
162         return TRUE;
163     case ACT_MURAMASA:
164         return TRUE;
165     default:
166         msg_format("Special timeout is not implemented: %d.", act_ptr->index);
167         return FALSE;
168     }
169 }
170
171 static bool activate_whistle(player_type *user_ptr, ae_type *ae_ptr)
172 {
173     if (ae_ptr->o_ptr->tval != TV_WHISTLE)
174         return FALSE;
175
176     if (music_singing_any(user_ptr))
177         stop_singing(user_ptr);
178
179     if (hex_spelling_any(user_ptr))
180         stop_hex_spell_all(user_ptr);
181
182     MONSTER_IDX pet_ctr;
183     MONSTER_IDX *who;
184     int max_pet = 0;
185     C_MAKE(who, current_world_ptr->max_m_idx, MONSTER_IDX);
186     for (pet_ctr = user_ptr->current_floor_ptr->m_max - 1; pet_ctr >= 1; pet_ctr--)
187         if (is_pet(&user_ptr->current_floor_ptr->m_list[pet_ctr]) && (user_ptr->riding != pet_ctr))
188             who[max_pet++] = pet_ctr;
189
190     u16b dummy_why;
191     ang_sort(user_ptr, who, &dummy_why, max_pet, ang_sort_comp_pet, ang_sort_swap_hook);
192     for (MONSTER_IDX i = 0; i < max_pet; i++) {
193         pet_ctr = who[i];
194         teleport_monster_to(user_ptr, pet_ctr, user_ptr->y, user_ptr->x, 100, TELEPORT_PASSIVE);
195     }
196
197     C_KILL(who, current_world_ptr->max_m_idx, MONSTER_IDX);
198     ae_ptr->o_ptr->timeout = 100 + randint1(100);
199     return TRUE;
200 }
201
202 /*!
203  * @brief 装備を発動するコマンドのサブルーチン /
204  * Activate a wielded object.  Wielded objects never stack.
205  * And even if they did, activatable objects never stack.
206  * @param item 発動するオブジェクトの所持品ID
207  * @return なし
208  * @details
209  * <pre>
210  * Currently, only (some) artifacts, and Dragon Scale Mail, can be activated.
211  * But one could, for example, easily make an activatable "Ring of Plasma".
212  * Note that it always takes a turn to activate an artifact, even if
213  * the user hits "escape" at the "direction" prompt.
214  * </pre>
215  */
216 void exe_activate(player_type *user_ptr, INVENTORY_IDX item)
217 {
218     take_turn(user_ptr, 100);
219     ae_type tmp_ae;
220     ae_type *ae_ptr = initialize_ae_type(user_ptr, &tmp_ae, item);
221     decide_activation_level(user_ptr, ae_ptr);
222     decide_chance_fail(user_ptr, ae_ptr);
223     if (cmd_limit_time_walk(user_ptr))
224         return;
225
226     decide_activation_success(user_ptr, ae_ptr);
227     if (!check_activation_conditions(user_ptr, ae_ptr))
228         return;
229
230     msg_print(_("始動させた...", "You activate it..."));
231     sound(SOUND_ZAP);
232     if (activation_index(user_ptr, ae_ptr->o_ptr)) {
233         (void)activate_artifact(user_ptr, ae_ptr->o_ptr);
234         user_ptr->window |= PW_INVEN | PW_EQUIP;
235         return;
236     }
237
238     if (activate_whistle(user_ptr, ae_ptr))
239         return;
240
241     if (exe_monster_capture(user_ptr, ae_ptr))
242         return;
243
244     msg_print(_("おっと、このアイテムは始動できない。", "Oops.  That object cannot be activated."));
245 }