2 #include "player-damage.h"
7 * @brief アイテムが酸で破損するかどうかを判定する
8 * @param o_ptr アイテムの情報参照ポインタ
9 * @return 破損するならばTRUEを返す
10 * Note that amulets, rods, and high-level spell books are immune
11 * to "inventory damage" of any kind. Also sling ammo and shovels.
12 * Does a given class of objects (usually) hate acid?
13 * Note that acid can either melt or corrode something.
15 bool hates_acid(object_type *o_ptr)
17 /* Analyze the type */
40 /* Staffs/Scrolls are wood/paper */
67 * @brief アイテムが電撃で破損するかどうかを判定する /
68 * Does a given object (usually) hate electricity?
69 * @param o_ptr アイテムの情報参照ポインタ
70 * @return 破損するならばTRUEを返す
72 bool hates_elec(object_type *o_ptr)
88 * @brief アイテムが火炎で破損するかどうかを判定する /
89 * Does a given object (usually) hate fire?
90 * @param o_ptr アイテムの情報参照ポインタ
91 * @return 破損するならばTRUEを返す
93 * Hafted/Polearm weapons have wooden shafts.
94 * Arrows/Bows are mostly wooden.
96 bool hates_fire(object_type *o_ptr)
98 /* Analyze the type */
117 case TV_SORCERY_BOOK:
125 case TV_CRUSADE_BOOK:
127 case TV_HISSATSU_BOOK:
139 /* Staffs/Scrolls burn */
152 * @brief アイテムが冷気で破損するかどうかを判定する /
153 * Does a given object (usually) hate cold?
154 * @param o_ptr アイテムの情報参照ポインタ
155 * @return 破損するならばTRUEを返す
157 bool hates_cold(object_type *o_ptr)
174 * @brief アイテムが酸で破損するかどうかを判定する(メインルーチン) /
176 * @param o_ptr アイテムの情報参照ポインタ
177 * @return 破損するならばTRUEを返す
180 int set_acid_destroy(object_type *o_ptr)
182 BIT_FLAGS flgs[TR_FLAG_SIZE];
183 if (!hates_acid(o_ptr)) return (FALSE);
184 object_flags(o_ptr, flgs);
185 if (have_flag(flgs, TR_IGNORE_ACID)) return (FALSE);
191 * @brief アイテムが電撃で破損するかどうかを判定する(メインルーチン) /
193 * @param o_ptr アイテムの情報参照ポインタ
194 * @return 破損するならばTRUEを返す
197 int set_elec_destroy(object_type *o_ptr)
199 BIT_FLAGS flgs[TR_FLAG_SIZE];
200 if (!hates_elec(o_ptr)) return (FALSE);
201 object_flags(o_ptr, flgs);
202 if (have_flag(flgs, TR_IGNORE_ELEC)) return (FALSE);
208 * @brief アイテムが火炎で破損するかどうかを判定する(メインルーチン) /
210 * @param o_ptr アイテムの情報参照ポインタ
211 * @return 破損するならばTRUEを返す
214 int set_fire_destroy(object_type *o_ptr)
216 BIT_FLAGS flgs[TR_FLAG_SIZE];
217 if (!hates_fire(o_ptr)) return (FALSE);
218 object_flags(o_ptr, flgs);
219 if (have_flag(flgs, TR_IGNORE_FIRE)) return (FALSE);
225 * @brief アイテムが冷気で破損するかどうかを判定する(メインルーチン) /
227 * @param o_ptr アイテムの情報参照ポインタ
228 * @return 破損するならばTRUEを返す
231 int set_cold_destroy(object_type *o_ptr)
233 BIT_FLAGS flgs[TR_FLAG_SIZE];
234 if (!hates_cold(o_ptr)) return (FALSE);
235 object_flags(o_ptr, flgs);
236 if (have_flag(flgs, TR_IGNORE_COLD)) return (FALSE);
242 * @brief アイテムが指定確率で破損するかどうかを判定する /
243 * Destroys a type of item on a given percent chance
244 * @param typ 破損判定関数ポインタ
248 * Note that missiles are no longer necessarily all destroyed
249 * Destruction taken from "melee.c" code for "stealing".
250 * New-style wands and rods handled correctly. -LM-
251 * Returns number of items destroyed.
253 int inven_damage(inven_func typ, int perc)
258 GAME_TEXT o_name[MAX_NLEN];
260 if (CHECK_MULTISHADOW()) return 0;
262 if (p_ptr->inside_arena) return 0;
264 /* Count the casualties */
267 /* Scan through the slots backwards */
268 for (i = 0; i < INVEN_PACK; i++)
270 o_ptr = &inventory[i];
272 /* Skip non-objects */
273 if (!o_ptr->k_idx) continue;
275 /* Hack -- for now, skip artifacts */
276 if (object_is_artifact(o_ptr)) continue;
278 /* Give this item slot a shot at death */
281 /* Count the casualties */
282 for (amt = j = 0; j < o_ptr->number; ++j)
284 if (randint0(100) < perc) amt++;
287 /* Some casualities */
290 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
292 msg_format(_("%s(%c)が%s壊れてしまった!", "%sour %s (%c) %s destroyed!"),
294 o_name, index_to_label(i), ((o_ptr->number > 1) ?
295 ((amt == o_ptr->number) ? "全部" : (amt > 1 ? "何個か" : "一個")) : ""));
297 ((o_ptr->number > 1) ? ((amt == o_ptr->number) ? "All of y" :
298 (amt > 1 ? "Some of y" : "One of y")) : "Y"), o_name, index_to_label(i), ((amt > 1) ? "were" : "was"));
302 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
303 msg_print("やりやがったな!");
304 else if ((p_ptr->pseikaku == SEIKAKU_CHARGEMAN))
306 if (randint0(2) == 0) msg_print(_("ジュラル星人め!", ""));
307 else msg_print(_("弱い者いじめは止めるんだ!", ""));
311 /* Potions smash open */
312 if (object_is_potion(o_ptr))
314 (void)potion_smash_effect(0, p_ptr->y, p_ptr->x, o_ptr->k_idx);
317 /* Reduce the charges of rods/wands */
318 reduce_charges(o_ptr, amt);
320 /* Destroy "amt" items */
321 inven_item_increase(i, -amt);
322 inven_item_optimize(i);
324 /* Count the casualties */
330 /* Return the casualty count */
336 * @brief 酸攻撃による装備のAC劣化処理 /
337 * Acid has hit the player, attempt to affect some armor.
338 * @return 装備による軽減があったならTRUEを返す
340 * Note that the "base armor" of an object never changes.
341 * If any armor is damaged (or resists), the player takes less damage.
343 static bool acid_minus_ac(void)
345 object_type *o_ptr = NULL;
346 BIT_FLAGS flgs[TR_FLAG_SIZE];
347 GAME_TEXT o_name[MAX_NLEN];
349 /* Pick a (possibly empty) inventory slot */
352 case 1: o_ptr = &inventory[INVEN_RARM]; break;
353 case 2: o_ptr = &inventory[INVEN_LARM]; break;
354 case 3: o_ptr = &inventory[INVEN_BODY]; break;
355 case 4: o_ptr = &inventory[INVEN_OUTER]; break;
356 case 5: o_ptr = &inventory[INVEN_HANDS]; break;
357 case 6: o_ptr = &inventory[INVEN_HEAD]; break;
358 case 7: o_ptr = &inventory[INVEN_FEET]; break;
361 if (!o_ptr->k_idx) return (FALSE);
362 if (!object_is_armour(o_ptr)) return (FALSE);
364 /* No damage left to be done */
365 if (o_ptr->ac + o_ptr->to_a <= 0)
367 msg_format(_("%sは既にボロボロだ!", "Your %s is already crumble!"), o_name);
370 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
371 object_flags(o_ptr, flgs);
374 if (have_flag(flgs, TR_IGNORE_ACID))
376 msg_format(_("しかし%sには効果がなかった!", "Your %s is unaffected!"), o_name);
380 msg_format(_("%sが酸で腐食した!", "Your %s is corroded!"), o_name);
382 /* Damage the item */
385 /* Calculate bonuses */
386 p_ptr->update |= (PU_BONUS);
387 p_ptr->window |= (PW_EQUIP | PW_PLAYER);
391 /* Item was damaged */
397 * @brief 酸属性によるプレイヤー損害処理 /
398 * Hurt the player with Acid
400 * @param kb_str ダメージ原因記述
401 * @param monspell 原因となったモンスター特殊攻撃ID
402 * @param aura オーラよるダメージが原因ならばTRUE
405 HIT_POINT acid_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
407 HIT_POINT get_damage;
408 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
409 bool double_resist = IS_OPPOSE_ACID();
412 if (p_ptr->immune_acid || (dam <= 0))
414 learn_spell(monspell);
418 /* Vulnerability (Ouch!) */
419 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
420 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
422 /* Resist the damage */
423 if (p_ptr->resist_acid) dam = (dam + 2) / 3;
424 if (double_resist) dam = (dam + 2) / 3;
426 if (aura || !CHECK_MULTISHADOW())
428 if ((!(double_resist || p_ptr->resist_acid)) &&
429 one_in_(HURT_CHANCE))
430 (void)do_dec_stat(A_CHR);
432 /* If any armor gets hit, defend the player */
433 if (acid_minus_ac()) dam = (dam + 1) / 2;
436 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
438 /* Inventory damage */
439 if (!aura && !(double_resist && p_ptr->resist_acid))
440 inven_damage(set_acid_destroy, inv);
446 * @brief 電撃属性によるプレイヤー損害処理 /
447 * Hurt the player with electricity
449 * @param kb_str ダメージ原因記述
450 * @param monspell 原因となったモンスター特殊攻撃ID
451 * @param aura オーラよるダメージが原因ならばTRUE
454 HIT_POINT elec_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
456 HIT_POINT get_damage;
457 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
458 bool double_resist = IS_OPPOSE_ELEC();
461 if (p_ptr->immune_elec || (dam <= 0))
463 learn_spell(monspell);
467 /* Vulnerability (Ouch!) */
468 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
469 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
470 if (prace_is_(RACE_ANDROID)) dam += dam / 3;
472 /* Resist the damage */
473 if (p_ptr->resist_elec) dam = (dam + 2) / 3;
474 if (double_resist) dam = (dam + 2) / 3;
476 if (aura || !CHECK_MULTISHADOW())
478 if ((!(double_resist || p_ptr->resist_elec)) &&
479 one_in_(HURT_CHANCE))
480 (void)do_dec_stat(A_DEX);
483 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
485 /* Inventory damage */
486 if (!aura && !(double_resist && p_ptr->resist_elec))
487 inven_damage(set_elec_destroy, inv);
494 * @brief 火炎属性によるプレイヤー損害処理 /
495 * Hurt the player with Fire
497 * @param kb_str ダメージ原因記述
498 * @param monspell 原因となったモンスター特殊攻撃ID
499 * @param aura オーラよるダメージが原因ならばTRUE
502 HIT_POINT fire_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
504 HIT_POINT get_damage;
505 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
506 bool double_resist = IS_OPPOSE_FIRE();
509 if (p_ptr->immune_fire || (dam <= 0))
511 learn_spell(monspell);
515 /* Vulnerability (Ouch!) */
516 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
517 if (prace_is_(RACE_ENT)) dam += dam / 3;
518 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
520 /* Resist the damage */
521 if (p_ptr->resist_fire) dam = (dam + 2) / 3;
522 if (double_resist) dam = (dam + 2) / 3;
524 if (aura || !CHECK_MULTISHADOW())
526 if ((!(double_resist || p_ptr->resist_fire)) &&
527 one_in_(HURT_CHANCE))
528 (void)do_dec_stat(A_STR);
531 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
533 /* Inventory damage */
534 if (!aura && !(double_resist && p_ptr->resist_fire))
535 inven_damage(set_fire_destroy, inv);
542 * @brief 冷気属性によるプレイヤー損害処理 /
543 * Hurt the player with Cold
545 * @param kb_str ダメージ原因記述
546 * @param monspell 原因となったモンスター特殊攻撃ID
547 * @param aura オーラよるダメージが原因ならばTRUE
550 HIT_POINT cold_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
552 HIT_POINT get_damage;
553 int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
554 bool double_resist = IS_OPPOSE_COLD();
557 if (p_ptr->immune_cold || (dam <= 0))
559 learn_spell(monspell);
563 /* Vulnerability (Ouch!) */
564 if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
565 if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
567 /* Resist the damage */
568 if (p_ptr->resist_cold) dam = (dam + 2) / 3;
569 if (double_resist) dam = (dam + 2) / 3;
571 if (aura || !CHECK_MULTISHADOW())
573 if ((!(double_resist || p_ptr->resist_cold)) &&
574 one_in_(HURT_CHANCE))
575 (void)do_dec_stat(A_STR);
578 get_damage = take_hit(aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
580 /* Inventory damage */
581 if (!aura && !(double_resist && p_ptr->resist_cold))
582 inven_damage(set_cold_destroy, inv);