2 #include "player-damage.h"
6 * @brief アイテムが酸で破損するかどうかを判定する
7 * @param o_ptr アイテムの情報参照ポインタ
8 * @return 破損するならばTRUEを返す
9 * Note that amulets, rods, and high-level spell books are immune
10 * to "inventory damage" of any kind. Also sling ammo and shovels.
11 * Does a given class of objects (usually) hate acid?
12 * Note that acid can either melt or corrode something.
14 bool hates_acid(object_type *o_ptr)
16 /* Analyze the type */
39 /* Staffs/Scrolls are wood/paper */
66 * @brief アイテムが電撃で破損するかどうかを判定する /
67 * Does a given object (usually) hate electricity?
68 * @param o_ptr アイテムの情報参照ポインタ
69 * @return 破損するならばTRUEを返す
71 bool hates_elec(object_type *o_ptr)
87 * @brief アイテムが火炎で破損するかどうかを判定する /
88 * Does a given object (usually) hate fire?
89 * @param o_ptr アイテムの情報参照ポインタ
90 * @return 破損するならばTRUEを返す
92 * Hafted/Polearm weapons have wooden shafts.
93 * Arrows/Bows are mostly wooden.
95 bool hates_fire(object_type *o_ptr)
97 /* Analyze the type */
116 case TV_SORCERY_BOOK:
124 case TV_CRUSADE_BOOK:
126 case TV_HISSATSU_BOOK:
138 /* Staffs/Scrolls burn */
151 * @brief アイテムが冷気で破損するかどうかを判定する /
152 * Does a given object (usually) hate cold?
153 * @param o_ptr アイテムの情報参照ポインタ
154 * @return 破損するならばTRUEを返す
156 bool hates_cold(object_type *o_ptr)
173 * @brief アイテムが酸で破損するかどうかを判定する(メインルーチン) /
175 * @param o_ptr アイテムの情報参照ポインタ
176 * @return 破損するならばTRUEを返す
179 int set_acid_destroy(object_type *o_ptr)
181 BIT_FLAGS flgs[TR_FLAG_SIZE];
182 if (!hates_acid(o_ptr)) return (FALSE);
183 object_flags(o_ptr, flgs);
184 if (have_flag(flgs, TR_IGNORE_ACID)) return (FALSE);
190 * @brief アイテムが電撃で破損するかどうかを判定する(メインルーチン) /
192 * @param o_ptr アイテムの情報参照ポインタ
193 * @return 破損するならばTRUEを返す
196 int set_elec_destroy(object_type *o_ptr)
198 BIT_FLAGS flgs[TR_FLAG_SIZE];
199 if (!hates_elec(o_ptr)) return (FALSE);
200 object_flags(o_ptr, flgs);
201 if (have_flag(flgs, TR_IGNORE_ELEC)) return (FALSE);
207 * @brief アイテムが火炎で破損するかどうかを判定する(メインルーチン) /
209 * @param o_ptr アイテムの情報参照ポインタ
210 * @return 破損するならばTRUEを返す
213 int set_fire_destroy(object_type *o_ptr)
215 BIT_FLAGS flgs[TR_FLAG_SIZE];
216 if (!hates_fire(o_ptr)) return (FALSE);
217 object_flags(o_ptr, flgs);
218 if (have_flag(flgs, TR_IGNORE_FIRE)) return (FALSE);
224 * @brief アイテムが冷気で破損するかどうかを判定する(メインルーチン) /
226 * @param o_ptr アイテムの情報参照ポインタ
227 * @return 破損するならばTRUEを返す
230 int set_cold_destroy(object_type *o_ptr)
232 BIT_FLAGS flgs[TR_FLAG_SIZE];
233 if (!hates_cold(o_ptr)) return (FALSE);
234 object_flags(o_ptr, flgs);
235 if (have_flag(flgs, TR_IGNORE_COLD)) return (FALSE);
241 * @brief アイテムが指定確率で破損するかどうかを判定する /
242 * Destroys a type of item on a given percent chance
243 * @param typ 破損判定関数ポインタ
247 * Note that missiles are no longer necessarily all destroyed
248 * Destruction taken from "melee.c" code for "stealing".
249 * New-style wands and rods handled correctly. -LM-
250 * Returns number of items destroyed.
252 int inven_damage(inven_func typ, int perc)
257 GAME_TEXT o_name[MAX_NLEN];
259 if (CHECK_MULTISHADOW()) return 0;
261 if (p_ptr->inside_arena) return 0;
263 /* Count the casualties */
266 /* Scan through the slots backwards */
267 for (i = 0; i < INVEN_PACK; i++)
269 o_ptr = &inventory[i];
271 /* Skip non-objects */
272 if (!o_ptr->k_idx) continue;
274 /* Hack -- for now, skip artifacts */
275 if (object_is_artifact(o_ptr)) continue;
277 /* Give this item slot a shot at death */
280 /* Count the casualties */
281 for (amt = j = 0; j < o_ptr->number; ++j)
283 if (randint0(100) < perc) amt++;
286 /* Some casualities */
289 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
291 msg_format(_("%s(%c)が%s壊れてしまった!", "%sour %s (%c) %s destroyed!"),
293 o_name, index_to_label(i), ((o_ptr->number > 1) ?
294 ((amt == o_ptr->number) ? "全部" : (amt > 1 ? "何個か" : "一個")) : ""));
296 ((o_ptr->number > 1) ? ((amt == o_ptr->number) ? "All of y" :
297 (amt > 1 ? "Some of y" : "One of y")) : "Y"), o_name, index_to_label(i), ((amt > 1) ? "were" : "was"));
301 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
302 msg_print("やりやがったな!");
303 else if ((p_ptr->pseikaku == SEIKAKU_CHARGEMAN))
305 if (randint0(2) == 0) msg_print(_("ジュラル星人め!", ""));
306 else msg_print(_("弱い者いじめは止めるんだ!", ""));
310 /* Potions smash open */
311 if (object_is_potion(o_ptr))
313 (void)potion_smash_effect(0, p_ptr->y, p_ptr->x, o_ptr->k_idx);
316 /* Reduce the charges of rods/wands */
317 reduce_charges(o_ptr, amt);
319 /* Destroy "amt" items */
320 inven_item_increase(i, -amt);
321 inven_item_optimize(i);
323 /* Count the casualties */
329 /* Return the casualty count */
335 * @brief 酸攻撃による装備のAC劣化処理 /
336 * Acid has hit the player, attempt to affect some armor.
337 * @return 装備による軽減があったならTRUEを返す
339 * Note that the "base armor" of an object never changes.
340 * If any armor is damaged (or resists), the player takes less damage.
342 static bool acid_minus_ac(void)
344 object_type *o_ptr = NULL;
345 BIT_FLAGS flgs[TR_FLAG_SIZE];
346 GAME_TEXT o_name[MAX_NLEN];
348 /* Pick a (possibly empty) inventory slot */
351 case 1: o_ptr = &inventory[INVEN_RARM]; break;
352 case 2: o_ptr = &inventory[INVEN_LARM]; break;
353 case 3: o_ptr = &inventory[INVEN_BODY]; break;
354 case 4: o_ptr = &inventory[INVEN_OUTER]; break;
355 case 5: o_ptr = &inventory[INVEN_HANDS]; break;
356 case 6: o_ptr = &inventory[INVEN_HEAD]; break;
357 case 7: o_ptr = &inventory[INVEN_FEET]; break;
360 if (!o_ptr->k_idx) return (FALSE);
361 if (!object_is_armour(o_ptr)) return (FALSE);
363 /* No damage left to be done */
364 if (o_ptr->ac + o_ptr->to_a <= 0)
366 msg_format(_("%sは既にボロボロだ!", "Your %s is already crumble!"), o_name);
369 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
370 object_flags(o_ptr, flgs);
373 if (have_flag(flgs, TR_IGNORE_ACID))
375 msg_format(_("しかし%sには効果がなかった!", "Your %s is unaffected!"), o_name);
379 msg_format(_("%sが酸で腐食した!", "Your %s is corroded!"), o_name);
381 /* Damage the item */
384 /* Calculate bonuses */
385 p_ptr->update |= (PU_BONUS);
386 p_ptr->window |= (PW_EQUIP | PW_PLAYER);
390 /* Item was damaged */
396 * @brief 酸属性によるプレイヤー損害処理 /
397 * Hurt the player with Acid
399 * @param kb_str ダメージ原因記述
400 * @param monspell 原因となったモンスター特殊攻撃ID
401 * @param aura オーラよるダメージが原因ならばTRUE
404 HIT_POINT acid_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
406 HIT_POINT get_damage;
407 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
408 bool double_resist = IS_OPPOSE_ACID();
411 if (p_ptr->immune_acid || (dam <= 0))
413 learn_spell(monspell);
417 /* Vulnerability (Ouch!) */
418 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
419 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
421 /* Resist the damage */
422 if (p_ptr->resist_acid) dam = (dam + 2) / 3;
423 if (double_resist) dam = (dam + 2) / 3;
425 if (aura || !CHECK_MULTISHADOW())
427 if ((!(double_resist || p_ptr->resist_acid)) &&
428 one_in_(HURT_CHANCE))
429 (void)do_dec_stat(A_CHR);
431 /* If any armor gets hit, defend the player */
432 if (acid_minus_ac()) dam = (dam + 1) / 2;
435 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
437 /* Inventory damage */
438 if (!aura && !(double_resist && p_ptr->resist_acid))
439 inven_damage(set_acid_destroy, inv);
445 * @brief 電撃属性によるプレイヤー損害処理 /
446 * Hurt the player with electricity
448 * @param kb_str ダメージ原因記述
449 * @param monspell 原因となったモンスター特殊攻撃ID
450 * @param aura オーラよるダメージが原因ならばTRUE
453 HIT_POINT elec_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
455 HIT_POINT get_damage;
456 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
457 bool double_resist = IS_OPPOSE_ELEC();
460 if (p_ptr->immune_elec || (dam <= 0))
462 learn_spell(monspell);
466 /* Vulnerability (Ouch!) */
467 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
468 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
469 if (prace_is_(RACE_ANDROID)) dam += dam / 3;
471 /* Resist the damage */
472 if (p_ptr->resist_elec) dam = (dam + 2) / 3;
473 if (double_resist) dam = (dam + 2) / 3;
475 if (aura || !CHECK_MULTISHADOW())
477 if ((!(double_resist || p_ptr->resist_elec)) &&
478 one_in_(HURT_CHANCE))
479 (void)do_dec_stat(A_DEX);
482 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
484 /* Inventory damage */
485 if (!aura && !(double_resist && p_ptr->resist_elec))
486 inven_damage(set_elec_destroy, inv);
493 * @brief 火炎属性によるプレイヤー損害処理 /
494 * Hurt the player with Fire
496 * @param kb_str ダメージ原因記述
497 * @param monspell 原因となったモンスター特殊攻撃ID
498 * @param aura オーラよるダメージが原因ならばTRUE
501 HIT_POINT fire_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
503 HIT_POINT get_damage;
504 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
505 bool double_resist = IS_OPPOSE_FIRE();
508 if (p_ptr->immune_fire || (dam <= 0))
510 learn_spell(monspell);
514 /* Vulnerability (Ouch!) */
515 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
516 if (prace_is_(RACE_ENT)) dam += dam / 3;
517 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
519 /* Resist the damage */
520 if (p_ptr->resist_fire) dam = (dam + 2) / 3;
521 if (double_resist) dam = (dam + 2) / 3;
523 if (aura || !CHECK_MULTISHADOW())
525 if ((!(double_resist || p_ptr->resist_fire)) &&
526 one_in_(HURT_CHANCE))
527 (void)do_dec_stat(A_STR);
530 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
532 /* Inventory damage */
533 if (!aura && !(double_resist && p_ptr->resist_fire))
534 inven_damage(set_fire_destroy, inv);
541 * @brief 冷気属性によるプレイヤー損害処理 /
542 * Hurt the player with Cold
544 * @param kb_str ダメージ原因記述
545 * @param monspell 原因となったモンスター特殊攻撃ID
546 * @param aura オーラよるダメージが原因ならばTRUE
549 HIT_POINT cold_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
551 HIT_POINT get_damage;
552 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
553 bool double_resist = IS_OPPOSE_COLD();
556 if (p_ptr->immune_cold || (dam <= 0))
558 learn_spell(monspell);
562 /* Vulnerability (Ouch!) */
563 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
564 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
566 /* Resist the damage */
567 if (p_ptr->resist_cold) dam = (dam + 2) / 3;
568 if (double_resist) dam = (dam + 2) / 3;
570 if (aura || !CHECK_MULTISHADOW())
572 if ((!(double_resist || p_ptr->resist_cold)) &&
573 one_in_(HURT_CHANCE))
574 (void)do_dec_stat(A_STR);
577 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
579 /* Inventory damage */
580 if (!aura && !(double_resist && p_ptr->resist_cold))
581 inven_damage(set_cold_destroy, inv);