+ if ((have_flag(flgs, p->slay_flag)) &&
+ (atoffset(BIT_FLAGS, r_ptr, p->flag_offset) & p->affect_race_flag))
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ atoffset(BIT_FLAGS, r_ptr, p->r_flag_offset) |= p->affect_race_flag;
+ }
+
+ mult = MAX(mult, p->slay_mult);
+ }
+ }
+
+ return mult;
+}
+
+/*!
+ * @brief プレイヤー攻撃の属性スレイング倍率計算
+ * @param mult 算出前の基本倍率(/10倍)
+ * @param flgs スレイフラグ配列
+ * @param m_ptr 目標モンスターの構造体参照ポインタ
+ * @return スレイング加味後の倍率(/10倍)
+ */
+static MULTIPLY mult_brand(MULTIPLY mult, const BIT_FLAGS* flgs, const monster_type* m_ptr)
+{
+ static const struct brand_table_t {
+ int brand_flag;
+ BIT_FLAGS resist_mask;
+ BIT_FLAGS hurt_flag;
+ } brand_table[] = {
+ {TR_BRAND_ACID, RFR_EFF_IM_ACID_MASK, 0U },
+ {TR_BRAND_ELEC, RFR_EFF_IM_ELEC_MASK, 0U },
+ {TR_BRAND_FIRE, RFR_EFF_IM_FIRE_MASK, RF3_HURT_FIRE},
+ {TR_BRAND_COLD, RFR_EFF_IM_COLD_MASK, RF3_HURT_COLD},
+ {TR_BRAND_POIS, RFR_EFF_IM_POIS_MASK, 0U },
+ };
+ int i;
+ monster_race* r_ptr = &r_info[m_ptr->r_idx];
+
+ for (i = 0; i < sizeof(brand_table) / sizeof(brand_table[0]); ++i)
+ {
+ const struct brand_table_t* p = &brand_table[i];
+
+ if (have_flag(flgs, p->brand_flag))
+ {
+ /* Notice immunity */
+ if (r_ptr->flagsr & p->resist_mask)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flagsr |= (r_ptr->flagsr & p->resist_mask);
+ }
+ }
+
+ /* Otherwise, take the damage */
+ else if (r_ptr->flags3 & p->hurt_flag)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= p->hurt_flag;
+ }
+
+ mult = MAX(mult, 50);
+ }
+ else
+ {
+ mult = MAX(mult, 25);
+ }
+ }
+ }
+
+ return mult;
+}
+
+/*!
+ * @brief 剣術のスレイ倍率計算を行う /
+ * Calcurate magnification of hissatsu technics
+ * @param mult 剣術のスレイ効果以前に算出している多要素の倍率(/10倍)
+ * @param flgs 剣術に使用する武器のスレイフラグ配列
+ * @param m_ptr 目標となるモンスターの構造体参照ポインタ
+ * @param mode 剣術のスレイ型ID
+ * @return スレイの倍率(/10倍)
+ */
+static MULTIPLY mult_hissatsu(MULTIPLY mult, BIT_FLAGS *flgs, monster_type *m_ptr, BIT_FLAGS mode)
+{
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+
+ /* Burning Strike (Fire) */
+ if (mode == HISSATSU_FIRE)
+ {
+ /* Notice immunity */
+ if (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
+ }
+ }
+
+ /* Otherwise, take the damage */
+ else if (have_flag(flgs, TR_BRAND_FIRE))
+ {
+ if (r_ptr->flags3 & RF3_HURT_FIRE)
+ {
+ if (mult < 70) mult = 70;
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= RF3_HURT_FIRE;
+ }
+ }
+ else if (mult < 35) mult = 35;
+ }
+ else
+ {
+ if (r_ptr->flags3 & RF3_HURT_FIRE)
+ {
+ if (mult < 50) mult = 50;
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= RF3_HURT_FIRE;
+ }
+ }
+ else if (mult < 25) mult = 25;
+ }
+ }
+
+ /* Serpent's Tongue (Poison) */
+ if (mode == HISSATSU_POISON)
+ {
+ /* Notice immunity */
+ if (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_POIS_MASK);
+ }
+ }
+
+ /* Otherwise, take the damage */
+ else if (have_flag(flgs, TR_BRAND_POIS))
+ {
+ if (mult < 35) mult = 35;
+ }
+ else
+ {
+ if (mult < 25) mult = 25;
+ }
+ }
+
+ /* Zammaken (Nonliving Evil) */
+ if (mode == HISSATSU_ZANMA)
+ {
+ if (!monster_living(m_ptr->r_idx) && (r_ptr->flags3 & RF3_EVIL))
+ {
+ if (mult < 15) mult = 25;
+ else if (mult < 50) mult = MIN(50, mult + 20);
+ }
+ }
+
+ /* Rock Smash (Hurt Rock) */
+ if (mode == HISSATSU_HAGAN)
+ {
+ if (r_ptr->flags3 & RF3_HURT_ROCK)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= RF3_HURT_ROCK;
+ }
+ if (mult == 10) mult = 40;
+ else if (mult < 60) mult = 60;
+ }
+ }
+
+ /* Midare-Setsugekka (Cold) */
+ if (mode == HISSATSU_COLD)
+ {
+ /* Notice immunity */
+ if (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
+ }
+ }
+ /* Otherwise, take the damage */
+ else if (have_flag(flgs, TR_BRAND_COLD))
+ {
+ if (r_ptr->flags3 & RF3_HURT_COLD)
+ {
+ if (mult < 70) mult = 70;
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= RF3_HURT_COLD;
+ }
+ }
+ else if (mult < 35) mult = 35;
+ }
+ else
+ {
+ if (r_ptr->flags3 & RF3_HURT_COLD)
+ {
+ if (mult < 50) mult = 50;
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= RF3_HURT_COLD;
+ }
+ }
+ else if (mult < 25) mult = 25;
+ }
+ }
+
+ /* Lightning Eagle (Elec) */
+ if (mode == HISSATSU_ELEC)
+ {
+ /* Notice immunity */
+ if (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
+ }
+ }
+
+ /* Otherwise, take the damage */
+ else if (have_flag(flgs, TR_BRAND_ELEC))
+ {
+ if (mult < 70) mult = 70;
+ }
+ else
+ {
+ if (mult < 50) mult = 50;
+ }
+ }
+
+ /* Bloody Maelstrom */
+ if ((mode == HISSATSU_SEKIRYUKA) && p_ptr->cut && monster_living(m_ptr->r_idx))
+ {
+ MULTIPLY tmp = MIN(100, MAX(10, p_ptr->cut / 10));
+ if (mult < tmp) mult = tmp;
+ }
+
+ /* Keiun-Kininken */
+ if (mode == HISSATSU_UNDEAD)
+ {
+ if (r_ptr->flags3 & RF3_UNDEAD)
+ {
+ if (is_original_ap_and_seen(m_ptr))
+ {
+ r_ptr->r_flags3 |= RF3_UNDEAD;
+ }
+ if (mult == 10) mult = 70;
+ else if (mult < 140) mult = MIN(140, mult + 60);
+ }
+ if (mult == 10) mult = 40;
+ else if (mult < 60) mult = MIN(60, mult + 30);
+ }
+
+ if (mult > 150) mult = 150;
+
+ return mult;
+}
+
+/*!
+ * @brief ダメージにスレイ要素を加える総合処理ルーチン /
+ * Extract the "total damage" from a given object hitting a given monster.
+ * @param o_ptr 使用武器オブジェクトの構造体参照ポインタ
+ * @param tdam 現在算出途中のダメージ値
+ * @param m_ptr 目標モンスターの構造体参照ポインタ
+ * @param mode 剣術のID
+ * @param thrown 投擲処理ならばTRUEを指定する
+ * @return 総合的なスレイを加味したダメージ値
+ * @note
+ * Note that "flasks of oil" do NOT do fire damage, although they\n
+ * certainly could be made to do so. XXX XXX\n
+ *\n
+ * Note that most brands and slays are x3, except Slay Animal (x2),\n
+ * Slay Evil (x2), and Kill dragon (x5).\n
+ */
+HIT_POINT tot_dam_aux(object_type *o_ptr, HIT_POINT tdam, monster_type *m_ptr, BIT_FLAGS mode, bool thrown)
+{
+ MULTIPLY mult = 10;
+
+ BIT_FLAGS flgs[TR_FLAG_SIZE];
+ object_flags(o_ptr, flgs);
+ torch_flags(o_ptr, flgs); /* torches has secret flags */
+
+ if (!thrown)
+ {
+ if (p_ptr->special_attack & (ATTACK_ACID)) add_flag(flgs, TR_BRAND_ACID);
+ if (p_ptr->special_attack & (ATTACK_COLD)) add_flag(flgs, TR_BRAND_COLD);
+ if (p_ptr->special_attack & (ATTACK_ELEC)) add_flag(flgs, TR_BRAND_ELEC);
+ if (p_ptr->special_attack & (ATTACK_FIRE)) add_flag(flgs, TR_BRAND_FIRE);
+ if (p_ptr->special_attack & (ATTACK_POIS)) add_flag(flgs, TR_BRAND_POIS);
+ }
+
+ if (hex_spelling(HEX_RUNESWORD)) add_flag(flgs, TR_SLAY_GOOD);
+
+ switch (o_ptr->tval)
+ {
+ case TV_SHOT:
+ case TV_ARROW:
+ case TV_BOLT:
+ case TV_HAFTED:
+ case TV_POLEARM:
+ case TV_SWORD:
+ case TV_DIGGING:
+ case TV_LITE:
+ {
+ mult = mult_slaying(mult, flgs, m_ptr);
+
+ mult = mult_brand(mult, flgs, m_ptr);
+
+ if (p_ptr->pclass == CLASS_SAMURAI)
+ {
+ mult = mult_hissatsu(mult, flgs, m_ptr, mode);
+ }
+
+ if ((p_ptr->pclass != CLASS_SAMURAI) && (have_flag(flgs, TR_FORCE_WEAPON)) && (p_ptr->csp > (o_ptr->dd * o_ptr->ds / 5)))
+ {
+ p_ptr->csp -= (1 + (o_ptr->dd * o_ptr->ds / 5));
+ p_ptr->redraw |= (PR_MANA);
+ mult = mult * 3 / 2 + 20;
+ }
+
+ if ((o_ptr->name1 == ART_NOTHUNG) && (m_ptr->r_idx == MON_FAFNER))
+ mult = 150;
+ break;
+ }
+ }
+ if (mult > 150) mult = 150;
+
+ return (tdam * mult / 10);
+}