1 #include "effect/effect-player-resist-hurt.h"
2 #include "art-definition/art-sword-types.h"
3 #include "inventory/inventory-damage.h"
4 #include "mind/mind-mirror-master.h"
5 #include "monster-race/race-indice-types.h"
6 #include "mspell/mspells3.h"
7 #include "mutation/mutation.h"
8 #include "object/object-broken.h"
9 #include "status/bad-status-setter.h"
10 #include "player/player-damage.h"
11 #include "player/player-effects.h"
12 #include "player/player-race-types.h"
13 #include "player/player-race.h"
14 #include "spell-kind/spells-teleport.h"
15 #include "spell/spells-status.h"
16 #include "spell/spells3.h"
17 #include "status/element-resistance.h"
18 #include "system/object-type-definition.h"
19 #include "view/display-messages.h"
20 #include "world/world.h"
23 void effect_player_elements(
24 player_type *target_ptr, effect_player_type *ep_ptr, concptr attack_message, HIT_POINT (*damage_func)(player_type *, HIT_POINT, concptr, int, bool))
26 if (target_ptr->blind)
27 msg_print(attack_message);
29 ep_ptr->get_damage = (*damage_func)(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
32 void effect_player_poison(player_type *target_ptr, effect_player_type *ep_ptr)
34 bool double_resist = is_oppose_pois(target_ptr);
35 if (target_ptr->blind)
36 msg_print(_("毒で攻撃された!", "You are hit by poison!"));
38 if (target_ptr->resist_pois)
39 ep_ptr->dam = (ep_ptr->dam + 2) / 3;
41 ep_ptr->dam = (ep_ptr->dam + 2) / 3;
43 if ((!(double_resist || target_ptr->resist_pois)) && one_in_(HURT_CHANCE) && !check_multishadow(target_ptr)) {
44 do_dec_stat(target_ptr, A_CON);
47 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
49 if (!(double_resist || target_ptr->resist_pois) && !check_multishadow(target_ptr))
50 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
53 void effect_player_nuke(player_type *target_ptr, effect_player_type *ep_ptr)
55 bool double_resist = is_oppose_pois(target_ptr);
56 if (target_ptr->blind)
57 msg_print(_("放射能で攻撃された!", "You are hit by radiation!"));
59 if (target_ptr->resist_pois)
60 ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
62 ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
64 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
65 if ((double_resist || target_ptr->resist_pois) || check_multishadow(target_ptr))
68 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
69 if (one_in_(5)) /* 6 */
71 msg_print(_("奇形的な変身を遂げた!", "You undergo a freakish metamorphosis!"));
72 if (one_in_(4)) /* 4 */
73 do_poly_self(target_ptr);
75 status_shuffle(target_ptr);
79 inventory_damage(target_ptr, set_acid_destroy, 2);
82 void effect_player_missile(player_type *target_ptr, effect_player_type *ep_ptr)
84 if (target_ptr->blind)
85 msg_print(_("何かで攻撃された!", "You are hit by something!"));
87 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
90 void effect_player_holy_fire(player_type *target_ptr, effect_player_type *ep_ptr)
92 if (target_ptr->blind)
93 msg_print(_("何かで攻撃された!", "You are hit by something!"));
95 if (target_ptr->align > 10)
97 else if (target_ptr->align < -10)
100 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
103 void effect_player_hell_fire(player_type *target_ptr, effect_player_type *ep_ptr)
105 if (target_ptr->blind)
106 msg_print(_("何かで攻撃された!", "You are hit by something!"));
108 if (target_ptr->align > 10)
111 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
114 void effect_player_arrow(player_type *target_ptr, effect_player_type *ep_ptr)
116 if (target_ptr->blind) {
117 msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
118 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
122 if ((target_ptr->inventory_list[INVEN_RARM].name1 == ART_ZANTETSU) || (target_ptr->inventory_list[INVEN_LARM].name1 == ART_ZANTETSU)) {
123 msg_print(_("矢を斬り捨てた!", "You cut down the arrow!"));
127 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
130 void effect_player_plasma(player_type *target_ptr, effect_player_type *ep_ptr)
132 if (target_ptr->blind)
133 msg_print(_("何かとても熱いもので攻撃された!", "You are hit by something *HOT*!"));
135 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
137 if (!target_ptr->resist_sound && !check_multishadow(target_ptr)) {
138 int plus_stun = (randint1((ep_ptr->dam > 40) ? 35 : (ep_ptr->dam * 3 / 4 + 5)));
139 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
142 if (!(target_ptr->resist_fire || is_oppose_fire(target_ptr) || target_ptr->immune_fire))
143 inventory_damage(target_ptr, set_acid_destroy, 3);
146 void effect_player_nether(player_type *target_ptr, effect_player_type *ep_ptr)
148 if (target_ptr->blind)
149 msg_print(_("地獄の力で攻撃された!", "You are hit by nether forces!"));
151 if (target_ptr->resist_neth) {
152 if (!is_specific_player_race(target_ptr, RACE_SPECTRE))
154 ep_ptr->dam /= (randint1(4) + 7);
155 } else if (!check_multishadow(target_ptr))
156 drain_exp(target_ptr, 200 + (target_ptr->exp / 100), 200 + (target_ptr->exp / 1000), 75);
158 if (!is_specific_player_race(target_ptr, RACE_SPECTRE) || check_multishadow(target_ptr)) {
159 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
163 msg_print(_("気分がよくなった。", "You feel invigorated!"));
164 hp_player(target_ptr, ep_ptr->dam / 4);
165 learn_spell(target_ptr, ep_ptr->monspell);
168 void effect_player_water(player_type *target_ptr, effect_player_type *ep_ptr)
170 if (target_ptr->blind)
171 msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
172 if (check_multishadow(target_ptr)) {
173 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
177 if (!target_ptr->resist_sound && !target_ptr->resist_water) {
178 set_stun(target_ptr, target_ptr->stun + randint1(40));
180 if (!target_ptr->resist_conf && !target_ptr->resist_water) {
181 set_confused(target_ptr, target_ptr->confused + randint1(5) + 5);
184 if (one_in_(5) && !target_ptr->resist_water) {
185 inventory_damage(target_ptr, set_cold_destroy, 3);
188 if (target_ptr->resist_water)
189 ep_ptr->get_damage /= 4;
191 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
194 void effect_player_chaos(player_type *target_ptr, effect_player_type *ep_ptr)
196 if (target_ptr->blind)
197 msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
198 if (target_ptr->resist_chaos) {
200 ep_ptr->dam /= (randint1(4) + 7);
203 if (check_multishadow(target_ptr)) {
204 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
208 if (!target_ptr->resist_conf) {
209 (void)set_confused(target_ptr, target_ptr->confused + randint0(20) + 10);
211 if (!target_ptr->resist_chaos) {
212 (void)set_image(target_ptr, target_ptr->image + randint1(10));
214 msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
215 (void)gain_mutation(target_ptr, 0);
218 if (!target_ptr->resist_neth && !target_ptr->resist_chaos) {
219 drain_exp(target_ptr, 5000 + (target_ptr->exp / 100), 500 + (target_ptr->exp / 1000), 75);
222 if (!target_ptr->resist_chaos || one_in_(9)) {
223 inventory_damage(target_ptr, set_elec_destroy, 2);
224 inventory_damage(target_ptr, set_fire_destroy, 2);
227 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
230 void effect_player_shards(player_type *target_ptr, effect_player_type *ep_ptr)
232 if (target_ptr->blind)
233 msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
234 if (target_ptr->resist_shard) {
236 ep_ptr->dam /= (randint1(4) + 7);
237 } else if (!check_multishadow(target_ptr)) {
238 (void)set_cut(target_ptr, target_ptr->cut + ep_ptr->dam);
241 if (!target_ptr->resist_shard || one_in_(13))
242 inventory_damage(target_ptr, set_cold_destroy, 2);
244 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
247 void effect_player_sound(player_type *target_ptr, effect_player_type *ep_ptr)
249 if (target_ptr->blind)
250 msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
251 if (target_ptr->resist_sound) {
253 ep_ptr->dam /= (randint1(4) + 7);
254 } else if (!check_multishadow(target_ptr)) {
255 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
256 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
259 if (!target_ptr->resist_sound || one_in_(13))
260 inventory_damage(target_ptr, set_cold_destroy, 2);
262 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
265 void effect_player_confusion(player_type *target_ptr, effect_player_type *ep_ptr)
267 if (target_ptr->blind)
268 msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
269 if (target_ptr->resist_conf) {
271 ep_ptr->dam /= (randint1(4) + 7);
272 } else if (!check_multishadow(target_ptr)) {
273 (void)set_confused(target_ptr, target_ptr->confused + randint1(20) + 10);
276 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
279 void effect_player_disenchant(player_type *target_ptr, effect_player_type *ep_ptr)
281 if (target_ptr->blind)
282 msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
283 if (target_ptr->resist_disen) {
285 ep_ptr->dam /= (randint1(4) + 7);
286 } else if (!check_multishadow(target_ptr)) {
287 (void)apply_disenchant(target_ptr, 0);
290 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
293 void effect_player_nexus(player_type *target_ptr, effect_player_type *ep_ptr)
295 if (target_ptr->blind)
296 msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
297 if (target_ptr->resist_nexus) {
299 ep_ptr->dam /= (randint1(4) + 7);
300 } else if (!check_multishadow(target_ptr)) {
301 apply_nexus(ep_ptr->m_ptr, target_ptr);
304 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
307 void effect_player_force(player_type *target_ptr, effect_player_type *ep_ptr)
309 if (target_ptr->blind)
310 msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
311 if (!target_ptr->resist_sound && !check_multishadow(target_ptr)) {
312 (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
315 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
318 void effect_player_rocket(player_type *target_ptr, effect_player_type *ep_ptr)
320 if (target_ptr->blind)
321 msg_print(_("爆発があった!", "There is an explosion!"));
322 if (!target_ptr->resist_sound && !check_multishadow(target_ptr)) {
323 (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
326 if (target_ptr->resist_shard) {
328 } else if (!check_multishadow(target_ptr)) {
329 (void)set_cut(target_ptr, target_ptr->cut + (ep_ptr->dam / 2));
332 if (!target_ptr->resist_shard || one_in_(12)) {
333 inventory_damage(target_ptr, set_cold_destroy, 3);
336 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
339 void effect_player_inertial(player_type *target_ptr, effect_player_type *ep_ptr)
341 if (target_ptr->blind)
342 msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
343 if (!check_multishadow(target_ptr))
344 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
346 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
349 void effect_player_lite(player_type *target_ptr, effect_player_type *ep_ptr)
351 if (target_ptr->blind)
352 msg_print(_("何かで攻撃された!", "You are hit by something!"));
353 if (target_ptr->resist_lite) {
355 ep_ptr->dam /= (randint1(4) + 7);
356 } else if (!target_ptr->blind && !target_ptr->resist_blind && !check_multishadow(target_ptr)) {
357 (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
360 if (is_specific_player_race(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE)) {
361 if (!check_multishadow(target_ptr))
362 msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
364 } else if (is_specific_player_race(target_ptr, RACE_S_FAIRY)) {
365 ep_ptr->dam = ep_ptr->dam * 4 / 3;
368 if (target_ptr->wraith_form)
370 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
372 if (!target_ptr->wraith_form || check_multishadow(target_ptr))
375 target_ptr->wraith_form = 0;
376 msg_print(_("閃光のため非物質的な影の存在でいられなくなった。", "The light forces you out of your incorporeal shadow form."));
378 target_ptr->redraw |= (PR_MAP | PR_STATUS);
379 target_ptr->update |= (PU_MONSTERS);
380 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
383 void effect_player_dark(player_type *target_ptr, effect_player_type *ep_ptr)
385 if (target_ptr->blind)
386 msg_print(_("何かで攻撃された!", "You are hit by something!"));
387 if (target_ptr->resist_dark) {
389 ep_ptr->dam /= (randint1(4) + 7);
391 if (is_specific_player_race(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE) || target_ptr->wraith_form)
393 } else if (!target_ptr->blind && !target_ptr->resist_blind && !check_multishadow(target_ptr)) {
394 (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
397 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
400 static void effect_player_time_one_disability(player_type *target_ptr)
404 switch (randint1(6)) {
407 act = _("強く", "strong");
411 act = _("聡明で", "bright");
415 act = _("賢明で", "wise");
419 act = _("器用で", "agile");
423 act = _("健康で", "hale");
427 act = _("美しく", "beautiful");
431 msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), act);
432 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 3) / 4;
433 if (target_ptr->stat_cur[k] < 3)
434 target_ptr->stat_cur[k] = 3;
436 target_ptr->update |= (PU_BONUS);
439 static void effect_player_time_all_disabilities(player_type *target_ptr)
441 msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
442 for (int k = 0; k < A_MAX; k++) {
443 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 7) / 8;
444 if (target_ptr->stat_cur[k] < 3)
445 target_ptr->stat_cur[k] = 3;
448 target_ptr->update |= (PU_BONUS);
451 static void effect_player_time_addition(player_type *target_ptr)
453 switch (randint1(10)) {
459 if (target_ptr->prace == RACE_ANDROID)
462 msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
463 lose_exp(target_ptr, 100 + (target_ptr->exp / 100) * MON_DRAIN_LIFE);
470 effect_player_time_one_disability(target_ptr);
473 effect_player_time_all_disabilities(target_ptr);
478 void effect_player_time(player_type *target_ptr, effect_player_type *ep_ptr)
480 if (target_ptr->blind)
481 msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
483 if (target_ptr->resist_time) {
485 ep_ptr->dam /= (randint1(4) + 7);
486 msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
487 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
491 if (check_multishadow(target_ptr)) {
492 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
496 effect_player_time_addition(target_ptr);
497 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
500 void effect_player_gravity(player_type *target_ptr, effect_player_type *ep_ptr)
502 if (target_ptr->blind)
503 msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
504 msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
506 if (!check_multishadow(target_ptr)) {
507 teleport_player(target_ptr, 5, TELEPORT_PASSIVE);
508 if (!target_ptr->levitation)
509 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
510 if (!(target_ptr->resist_sound || target_ptr->levitation)) {
511 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
512 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
516 if (target_ptr->levitation) {
517 ep_ptr->dam = (ep_ptr->dam * 2) / 3;
520 if (!target_ptr->levitation || one_in_(13)) {
521 inventory_damage(target_ptr, set_cold_destroy, 2);
524 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
527 void effect_player_disintegration(player_type *target_ptr, effect_player_type *ep_ptr)
529 if (target_ptr->blind)
530 msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
532 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);