X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmelee1.c;h=64a4b2a213c8b1d4f4e92c86a00e849988b36b93;hb=5d3509382b96bb3cecc04023caa87c22da6f5943;hp=b52c4a8ac7d13aad78b6202cafc88625c50aa67e;hpb=9d00d657aae72232a5561679f76f74695749d4da;p=hengband%2Fhengband.git diff --git a/src/melee1.c b/src/melee1.c index b52c4a8ac..64a4b2a21 100644 --- a/src/melee1.c +++ b/src/melee1.c @@ -1,154 +1,1533 @@ -/* File: melee1.c */ +/*! + * @file melee1.c + * @brief モンスターの打撃処理 / Monster attacks + * @date 2014/01/17 + * @author + * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n + * This software may be copied and distributed for educational, research,\n + * and not for profit purposes provided that this copyright and statement\n + * are included in all such copies. Other copyrights may also apply.\n + * 2014 Deskull rearranged comment for Doxygen.\n + * @details + */ + +#include "angband.h" +#include "cmd-pet.h" +#include "player-damage.h" + + + + /*! + * @brief プレイヤーからモンスターへの打撃命中判定 / + * Determine if the player "hits" a monster (normal combat). + * @param chance 基本命中値 + * @param ac モンスターのAC + * @param vis 目標を視界に捕らえているならばTRUEを指定 + * @return 命中と判定された場合TRUEを返す + * @note Always miss 5%, always hit 5%, otherwise random. + */ +bool test_hit_norm(int chance, ARMOUR_CLASS ac, int vis) +{ + int k; + + /* Percentile dice */ + k = randint0(100); + + /* Hack -- Instant miss or hit */ + if (k < 10) return (k < 5); + + if (p_ptr->pseikaku == SEIKAKU_NAMAKE) + if (one_in_(20)) return (FALSE); + + /* Wimpy attack never hits */ + if (chance <= 0) return (FALSE); + + /* Penalize invisible targets */ + if (!vis) chance = (chance + 1) / 2; + + /* Power must defeat armor */ + if (randint0(chance) < (ac * 3 / 4)) return (FALSE); + + /* Assume hit */ + return (TRUE); +} + + +/*! +* @brief プレイヤーからモンスターへの打撃クリティカル判定 / +* Critical hits (by player) Factor in weapon weight, total plusses, player melee bonus +* @param weight 矢弾の重量 +* @param plus 武器の命中修正 +* @param dam 現在算出中のダメージ値 +* @param meichuu 打撃の基本命中力 +* @param mode オプションフラグ +* @return クリティカル修正が入ったダメージ値 +*/ +HIT_POINT critical_norm(WEIGHT weight, int plus, HIT_POINT dam, s16b meichuu, BIT_FLAGS mode) +{ + int i, k; + + /* Extract "blow" power */ + i = (weight + (meichuu * 3 + plus * 5) + p_ptr->skill_thn); + + /* Chance */ + if ((randint1((p_ptr->pclass == CLASS_NINJA) ? 4444 : 5000) <= i) || (mode == HISSATSU_MAJIN) || (mode == HISSATSU_3DAN)) + { + k = weight + randint1(650); + if ((mode == HISSATSU_MAJIN) || (mode == HISSATSU_3DAN)) k += randint1(650); + + if (k < 400) + { + msg_print(_("手ごたえがあった!", "It was a good hit!")); + + dam = 2 * dam + 5; + } + else if (k < 700) + { + msg_print(_("かなりの手ごたえがあった!", "It was a great hit!")); + dam = 2 * dam + 10; + } + else if (k < 900) + { + msg_print(_("会心の一撃だ!", "It was a superb hit!")); + dam = 3 * dam + 15; + } + else if (k < 1300) + { + msg_print(_("最高の会心の一撃だ!", "It was a *GREAT* hit!")); + dam = 3 * dam + 20; + } + else + { + msg_print(_("比類なき最高の会心の一撃だ!", "It was a *SUPERB* hit!")); + dam = ((7 * dam) / 2) + 25; + } + } + + return (dam); +} + +/*! + * @brief モンスター打撃のクリティカルランクを返す / + * Critical blow. All hits that do 95% of total possible damage, + * @param dice モンスター打撃のダイス数 + * @param sides モンスター打撃の最大ダイス目 + * @param dam プレイヤーに与えたダメージ + * @details + * and which also do at least 20 damage, or, sometimes, N damage. + * This is used only to determine "cuts" and "stuns". + */ +static int monster_critical(DICE_NUMBER dice, DICE_SID sides, HIT_POINT dam) +{ + int max = 0; + int total = dice * sides; + + /* Must do at least 95% of perfect */ + if (dam < total * 19 / 20) return (0); + + /* Weak blows rarely work */ + if ((dam < 20) && (randint0(100) >= dam)) return (0); + + /* Perfect damage */ + if ((dam >= total) && (dam >= 40)) max++; + + /* Super-charge */ + if (dam >= 20) + { + while (randint0(100) < 2) max++; + } + + /* Critical damage */ + if (dam > 45) return (6 + max); + if (dam > 33) return (5 + max); + if (dam > 25) return (4 + max); + if (dam > 18) return (3 + max); + if (dam > 11) return (2 + max); + return (1 + max); +} + +/*! + * @brief モンスター打撃の命中を判定する / + * Determine if a monster attack against the player succeeds. + * @param power 打撃属性毎の基本命中値 + * @param level モンスターのレベル + * @param stun モンスターの朦朧値 + * @return TRUEならば命中判定 + * @details + * Always miss 5% of the time, Always hit 5% of the time. + * Otherwise, match monster power against player armor. + */ +static int check_hit(int power, DEPTH level, int stun) +{ + int i, k, ac; + + /* Percentile dice */ + k = randint0(100); + + if (stun && one_in_(2)) return FALSE; + + /* Hack -- Always miss or hit */ + if (k < 10) return (k < 5); + + /* Calculate the "attack quality" */ + i = (power + (level * 3)); + + /* Total armor */ + ac = p_ptr->ac + p_ptr->to_a; + if (p_ptr->special_attack & ATTACK_SUIKEN) ac += (p_ptr->lev * 2); + + /* Power and Level compete against Armor */ + if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE); + + /* Assume miss */ + return (FALSE); +} + + + +/*! モンスターの侮辱行為メッセージテーブル / Hack -- possible "insult" messages */ +static cptr desc_insult[] = +{ +#ifdef JP + "があなたを侮辱した!", + "があなたの母を侮辱した!", + "があなたを軽蔑した!", + "があなたを辱めた!", + "があなたを汚した!", + "があなたの回りで踊った!", + "が猥褻な身ぶりをした!", + "があなたをぼんやりと見た!!!", + "があなたをパラサイト呼ばわりした!", + "があなたをサイボーグ扱いした!" +#else + "insults you!", + "insults your mother!", + "gives you the finger!", + "humiliates you!", + "defiles you!", + "dances around you!", + "makes obscene gestures!", + "moons you!!!" + "calls you a parasite!", + "calls you a cyborg!" +#endif + +}; + + +/*! マゴットのぼやきメッセージテーブル / Hack -- possible "insult" messages */ +static cptr desc_moan[] = +{ +#ifdef JP + "は何かを悲しんでいるようだ。", + "が彼の飼い犬を見なかったかと尋ねている。", + "が縄張りから出て行けと言っている。", + "はキノコがどうとか呟いている。" +#else + "seems sad about something.", + "asks if you have seen his dogs.", + "tells you to get off his land.", + "mumbles something about mushrooms." +#endif + +}; + + +/*! +* @brief 敵オーラによるプレイヤーのダメージ処理(補助) +* @param m_ptr オーラを持つモンスターの構造体参照ポインタ +* @param immune ダメージを回避できる免疫フラグ +* @param flags_offset オーラフラグ配列の参照オフセット +* @param r_flags_offset モンスターの耐性配列の参照オフセット +* @param aura_flag オーラフラグ配列 +* @param dam_func ダメージ処理を行う関数の参照ポインタ +* @param message オーラダメージを受けた際のメッセージ +* @return なし +*/ +static void touch_zap_player_aux(monster_type *m_ptr, bool immune, int flags_offset, int r_flags_offset, u32b aura_flag, + HIT_POINT(*dam_func)(HIT_POINT dam, cptr kb_str, int monspell, bool aura), cptr message) +{ + monster_race *r_ptr = &r_info[m_ptr->r_idx]; + + if ((atoffset(u32b, r_ptr, flags_offset) & aura_flag) && !immune) + { + char mon_name[80]; + int aura_damage = damroll(1 + (r_ptr->level / 26), 1 + (r_ptr->level / 17)); + + /* Hack -- Get the "died from" name */ + monster_desc(mon_name, m_ptr, MD_IGNORE_HALLU | MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE); + + msg_print(message); + + dam_func(aura_damage, mon_name, -1, TRUE); + + if (is_original_ap_and_seen(m_ptr)) + { + atoffset(u32b, r_ptr, r_flags_offset) |= aura_flag; + } + + handle_stuff(); + } +} + + + + +/*! +* @brief 敵オーラによるプレイヤーのダメージ処理(メイン) +* @param m_ptr オーラを持つモンスターの構造体参照ポインタ +* @return なし +*/ +static void touch_zap_player(monster_type *m_ptr) +{ + touch_zap_player_aux(m_ptr, p_ptr->immune_fire, offsetof(monster_race, flags2), offsetof(monster_race, r_flags2), RF2_AURA_FIRE, + fire_dam, _("突然とても熱くなった!", "You are suddenly very hot!")); + touch_zap_player_aux(m_ptr, p_ptr->immune_cold, offsetof(monster_race, flags3), offsetof(monster_race, r_flags3), RF3_AURA_COLD, + cold_dam, _("突然とても寒くなった!", "You are suddenly very cold!")); + touch_zap_player_aux(m_ptr, p_ptr->immune_elec, offsetof(monster_race, flags2), offsetof(monster_race, r_flags2), RF2_AURA_ELEC, + elec_dam, _("電撃をくらった!", "You get zapped!")); +} + +/*! +* @brief プレイヤーの変異要素による打撃処理 +* @param m_idx 攻撃目標となったモンスターの参照ID +* @param attack 変異要素による攻撃要素の種類 +* @param fear 攻撃を受けたモンスターが恐慌状態に陥ったかを返す参照ポインタ +* @param mdeath 攻撃を受けたモンスターが死亡したかを返す参照ポインタ +* @return なし +*/ +static void natural_attack(s16b m_idx, int attack, bool *fear, bool *mdeath) +{ + HIT_POINT k; + int bonus, chance; + int n_weight = 0; + monster_type *m_ptr = &m_list[m_idx]; + monster_race *r_ptr = &r_info[m_ptr->r_idx]; + char m_name[80]; + + int dice_num, dice_side; + + cptr atk_desc; + + switch (attack) + { + case MUT2_SCOR_TAIL: + dice_num = 3; + dice_side = 7; + n_weight = 5; + atk_desc = _("尻尾", "tail"); + + break; + case MUT2_HORNS: + dice_num = 2; + dice_side = 6; + n_weight = 15; + atk_desc = _("角", "horns"); + + break; + case MUT2_BEAK: + dice_num = 2; + dice_side = 4; + n_weight = 5; + atk_desc = _("クチバシ", "beak"); + + break; + case MUT2_TRUNK: + dice_num = 1; + dice_side = 4; + n_weight = 35; + atk_desc = _("象の鼻", "trunk"); + + break; + case MUT2_TENTACLES: + dice_num = 2; + dice_side = 5; + n_weight = 5; + atk_desc = _("触手", "tentacles"); + + break; + default: + dice_num = dice_side = n_weight = 1; + atk_desc = _("未定義の部位", "undefined body part"); + + } + + /* Extract monster name (or "it") */ + monster_desc(m_name, m_ptr, 0); + + + /* Calculate the "attack quality" */ + bonus = p_ptr->to_h_m; + bonus += (p_ptr->lev * 6 / 5); + chance = (p_ptr->skill_thn + (bonus * BTH_PLUS_ADJ)); + + /* Test for hit */ + if ((!(r_ptr->flags2 & RF2_QUANTUM) || !randint0(2)) && test_hit_norm(chance, r_ptr->ac, m_ptr->ml)) + { + sound(SOUND_HIT); + msg_format(_("%sを%sで攻撃した。", "You hit %s with your %s."), m_name, atk_desc); + + k = damroll(dice_num, dice_side); + k = critical_norm(n_weight, bonus, k, (s16b)bonus, 0); + + /* Apply the player damage bonuses */ + k += p_ptr->to_d_m; + + /* No negative damage */ + if (k < 0) k = 0; + + /* Modify the damage */ + k = mon_damage_mod(m_ptr, k, FALSE); + + /* Complex message */ + msg_format_wizard(CHEAT_MONSTER, + _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"), + k, m_ptr->hp - k, m_ptr->maxhp, m_ptr->max_maxhp); + + /* Anger the monster */ + if (k > 0) anger_monster(m_ptr); + + /* Damage, check for fear and mdeath */ + switch (attack) + { + case MUT2_SCOR_TAIL: + project(0, 0, m_ptr->fy, m_ptr->fx, k, GF_POIS, PROJECT_KILL, -1); + *mdeath = (m_ptr->r_idx == 0); + break; + case MUT2_HORNS: + *mdeath = mon_take_hit(m_idx, k, fear, NULL); + break; + case MUT2_BEAK: + *mdeath = mon_take_hit(m_idx, k, fear, NULL); + break; + case MUT2_TRUNK: + *mdeath = mon_take_hit(m_idx, k, fear, NULL); + break; + case MUT2_TENTACLES: + *mdeath = mon_take_hit(m_idx, k, fear, NULL); + break; + default: + *mdeath = mon_take_hit(m_idx, k, fear, NULL); + } + + touch_zap_player(m_ptr); + } + /* Player misses */ + else + { + sound(SOUND_MISS); + + msg_format(_("ミス! %sにかわされた。", "You miss %s."), m_name); + } +} + +/*! +* @brief プレイヤーの打撃処理サブルーチン / +* Player attacks a (poor, defenseless) creature -RAK- +* @param y 攻撃目標のY座標 +* @param x 攻撃目標のX座標 +* @param fear 攻撃を受けたモンスターが恐慌状態に陥ったかを返す参照ポインタ +* @param mdeath 攻撃を受けたモンスターが死亡したかを返す参照ポインタ +* @param hand 攻撃を行うための武器を持つ手 +* @param mode 発動中の剣術ID +* @return なし +* @details +* If no "weapon" is available, then "punch" the monster one time. +*/ +static void py_attack_aux(POSITION y, POSITION x, bool *fear, bool *mdeath, s16b hand, BIT_FLAGS mode) +{ + int num = 0, bonus, chance, vir; + HIT_POINT k; + + cave_type *c_ptr = &cave[y][x]; + + monster_type *m_ptr = &m_list[c_ptr->m_idx]; + monster_race *r_ptr = &r_info[m_ptr->r_idx]; + + /* Access the weapon */ + object_type *o_ptr = &inventory[INVEN_RARM + hand]; + + char m_name[80]; + + bool success_hit = FALSE; + bool backstab = FALSE; + bool vorpal_cut = FALSE; + int chaos_effect = 0; + bool stab_fleeing = FALSE; + bool fuiuchi = FALSE; + bool monk_attack = FALSE; + bool do_quake = FALSE; + bool weak = FALSE; + bool drain_msg = TRUE; + int drain_result = 0, drain_heal = 0; + bool can_drain = FALSE; + int num_blow; + int drain_left = MAX_VAMPIRIC_DRAIN; + BIT_FLAGS flgs[TR_FLAG_SIZE]; /* A massive hack -- life-draining weapons */ + bool is_human = (r_ptr->d_char == 'p'); + bool is_lowlevel = (r_ptr->level < (p_ptr->lev - 15)); + bool zantetsu_mukou, e_j_mukou; + + switch (p_ptr->pclass) + { + case CLASS_ROGUE: + case CLASS_NINJA: + if (buki_motteruka(INVEN_RARM + hand) && !p_ptr->icky_wield[hand]) + { + int tmp = p_ptr->lev * 6 + (p_ptr->skill_stl + 10) * 4; + if (p_ptr->monlite && (mode != HISSATSU_NYUSIN)) tmp /= 3; + if (p_ptr->cursed & TRC_AGGRAVATE) tmp /= 2; + if (r_ptr->level > (p_ptr->lev * p_ptr->lev / 20 + 10)) tmp /= 3; + if (MON_CSLEEP(m_ptr) && m_ptr->ml) + { + /* Can't backstab creatures that we can't see, right? */ + backstab = TRUE; + } + else if ((p_ptr->special_defense & NINJA_S_STEALTH) && (randint0(tmp) > (r_ptr->level + 20)) && m_ptr->ml && !(r_ptr->flagsr & RFR_RES_ALL)) + { + fuiuchi = TRUE; + } + else if (MON_MONFEAR(m_ptr) && m_ptr->ml) + { + stab_fleeing = TRUE; + } + } + break; + + case CLASS_MONK: + case CLASS_FORCETRAINER: + case CLASS_BERSERKER: + if ((empty_hands(TRUE) & EMPTY_HAND_RARM) && !p_ptr->riding) monk_attack = TRUE; + break; + } + + if (!o_ptr->k_idx) /* Empty hand */ + { + if ((r_ptr->level + 10) > p_ptr->lev) + { + if (p_ptr->skill_exp[GINOU_SUDE] < s_info[p_ptr->pclass].s_max[GINOU_SUDE]) + { + if (p_ptr->skill_exp[GINOU_SUDE] < WEAPON_EXP_BEGINNER) + p_ptr->skill_exp[GINOU_SUDE] += 40; + else if ((p_ptr->skill_exp[GINOU_SUDE] < WEAPON_EXP_SKILLED)) + p_ptr->skill_exp[GINOU_SUDE] += 5; + else if ((p_ptr->skill_exp[GINOU_SUDE] < WEAPON_EXP_EXPERT) && (p_ptr->lev > 19)) + p_ptr->skill_exp[GINOU_SUDE] += 1; + else if ((p_ptr->lev > 34)) + if (one_in_(3)) p_ptr->skill_exp[GINOU_SUDE] += 1; + p_ptr->update |= (PU_BONUS); + } + } + } + else if (object_is_melee_weapon(o_ptr)) + { + if ((r_ptr->level + 10) > p_ptr->lev) + { + OBJECT_TYPE_VALUE tval = inventory[INVEN_RARM + hand].tval - TV_WEAPON_BEGIN; + OBJECT_SUBTYPE_VALUE sval = inventory[INVEN_RARM + hand].sval; + int now_exp = p_ptr->weapon_exp[tval][sval]; + if (now_exp < s_info[p_ptr->pclass].w_max[tval][sval]) + { + SUB_EXP amount = 0; + if (now_exp < WEAPON_EXP_BEGINNER) amount = 80; + else if (now_exp < WEAPON_EXP_SKILLED) amount = 10; + else if ((now_exp < WEAPON_EXP_EXPERT) && (p_ptr->lev > 19)) amount = 1; + else if ((p_ptr->lev > 34) && one_in_(2)) amount = 1; + p_ptr->weapon_exp[tval][sval] += amount; + p_ptr->update |= (PU_BONUS); + } + } + } + + /* Disturb the monster */ + (void)set_monster_csleep(c_ptr->m_idx, 0); + + /* Extract monster name (or "it") */ + monster_desc(m_name, m_ptr, 0); + + /* Calculate the "attack quality" */ + bonus = p_ptr->to_h[hand] + o_ptr->to_h; + chance = (p_ptr->skill_thn + (bonus * BTH_PLUS_ADJ)); + if (mode == HISSATSU_IAI) chance += 60; + if (p_ptr->special_defense & KATA_KOUKIJIN) chance += 150; + + if (p_ptr->sutemi) chance = MAX(chance * 3 / 2, chance + 60); + + vir = virtue_number(V_VALOUR); + if (vir) + { + chance += (p_ptr->virtues[vir - 1] / 10); + } + + zantetsu_mukou = ((o_ptr->name1 == ART_ZANTETSU) && (r_ptr->d_char == 'j')); + e_j_mukou = ((o_ptr->name1 == ART_EXCALIBUR_J) && (r_ptr->d_char == 'S')); + + if ((mode == HISSATSU_KYUSHO) || (mode == HISSATSU_MINEUCHI) || (mode == HISSATSU_3DAN) || (mode == HISSATSU_IAI)) num_blow = 1; + else if (mode == HISSATSU_COLD) num_blow = p_ptr->num_blow[hand] + 2; + else num_blow = p_ptr->num_blow[hand]; + + /* Hack -- DOKUBARI always hit once */ + if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DOKUBARI)) num_blow = 1; + + /* Attack once for each legal blow */ + while ((num++ < num_blow) && !p_ptr->is_dead) + { + if (((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DOKUBARI)) || (mode == HISSATSU_KYUSHO)) + { + int n = 1; + + if (p_ptr->migite && p_ptr->hidarite) + { + n *= 2; + } + if (mode == HISSATSU_3DAN) + { + n *= 2; + } + + success_hit = one_in_(n); + } + else if ((p_ptr->pclass == CLASS_NINJA) && ((backstab || fuiuchi) && !(r_ptr->flagsr & RFR_RES_ALL))) success_hit = TRUE; + else success_hit = test_hit_norm(chance, r_ptr->ac, m_ptr->ml); + + if (mode == HISSATSU_MAJIN) + { + if (one_in_(2)) + success_hit = FALSE; + } + + /* Test for hit */ + if (success_hit) + { + int vorpal_chance = ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)) ? 2 : 4; + + sound(SOUND_HIT); + + if (backstab) msg_format(_("あなたは冷酷にも眠っている無力な%sを突き刺した!", "You cruelly stab the helpless, sleeping %s!"), m_name); + else if (fuiuchi) msg_format(_("不意を突いて%sに強烈な一撃を喰らわせた!", "You make surprise attack, and hit %s with a powerful blow!"), m_name); + else if (stab_fleeing) msg_format(_("逃げる%sを背中から突き刺した!", "You backstab the fleeing %s!"), m_name); + else if (!monk_attack) msg_format(_("%sを攻撃した。", "You hit %s."), m_name); + + /* Hack -- bare hands do one damage */ + k = 1; + + object_flags(o_ptr, flgs); + + /* Select a chaotic effect (50% chance) */ + if ((have_flag(flgs, TR_CHAOTIC)) && one_in_(2)) + { + if (one_in_(10)) + chg_virtue(V_CHANCE, 1); + + if (randint1(5) < 3) + { + /* Vampiric (20%) */ + chaos_effect = 1; + } + else if (one_in_(250)) + { + /* Quake (0.12%) */ + chaos_effect = 2; + } + else if (!one_in_(10)) + { + /* Confusion (26.892%) */ + chaos_effect = 3; + } + else if (one_in_(2)) + { + /* Teleport away (1.494%) */ + chaos_effect = 4; + } + else + { + /* Polymorph (1.494%) */ + chaos_effect = 5; + } + } + + /* Vampiric drain */ + if ((have_flag(flgs, TR_VAMPIRIC)) || (chaos_effect == 1) || (mode == HISSATSU_DRAIN) || hex_spelling(HEX_VAMP_BLADE)) + { + /* Only drain "living" monsters */ + if (monster_living(r_ptr)) + can_drain = TRUE; + else + can_drain = FALSE; + } + + if ((have_flag(flgs, TR_VORPAL) || hex_spelling(HEX_RUNESWORD)) && (randint1(vorpal_chance * 3 / 2) == 1) && !zantetsu_mukou) + vorpal_cut = TRUE; + else vorpal_cut = FALSE; + + if (monk_attack) + { + int special_effect = 0, stun_effect = 0, times = 0, max_times; + int min_level = 1; + const martial_arts *ma_ptr = &ma_blows[0], *old_ptr = &ma_blows[0]; + int resist_stun = 0; + WEIGHT weight = 8; + + if (r_ptr->flags1 & RF1_UNIQUE) resist_stun += 88; + if (r_ptr->flags3 & RF3_NO_STUN) resist_stun += 66; + if (r_ptr->flags3 & RF3_NO_CONF) resist_stun += 33; + if (r_ptr->flags3 & RF3_NO_SLEEP) resist_stun += 33; + if ((r_ptr->flags3 & RF3_UNDEAD) || (r_ptr->flags3 & RF3_NONLIVING)) + resist_stun += 66; + + if (p_ptr->special_defense & KAMAE_BYAKKO) + max_times = (p_ptr->lev < 3 ? 1 : p_ptr->lev / 3); + else if (p_ptr->special_defense & KAMAE_SUZAKU) + max_times = 1; + else if (p_ptr->special_defense & KAMAE_GENBU) + max_times = 1; + else + max_times = (p_ptr->lev < 7 ? 1 : p_ptr->lev / 7); + /* Attempt 'times' */ + for (times = 0; times < max_times; times++) + { + do + { + ma_ptr = &ma_blows[randint0(MAX_MA)]; + if ((p_ptr->pclass == CLASS_FORCETRAINER) && (ma_ptr->min_level > 1)) min_level = ma_ptr->min_level + 3; + else min_level = ma_ptr->min_level; + } while ((min_level > p_ptr->lev) || + (randint1(p_ptr->lev) < ma_ptr->chance)); + + /* keep the highest level attack available we found */ + if ((ma_ptr->min_level > old_ptr->min_level) && + !p_ptr->stun && !p_ptr->confused) + { + old_ptr = ma_ptr; + + if (p_ptr->wizard && cheat_xtra) + { + msg_print(_("攻撃を再選択しました。", "Attack re-selected.")); + } + } + else + { + ma_ptr = old_ptr; + } + } + + if (p_ptr->pclass == CLASS_FORCETRAINER) min_level = MAX(1, ma_ptr->min_level - 3); + else min_level = ma_ptr->min_level; + k = damroll(ma_ptr->dd + p_ptr->to_dd[hand], ma_ptr->ds + p_ptr->to_ds[hand]); + if (p_ptr->special_attack & ATTACK_SUIKEN) k *= 2; + + if (ma_ptr->effect == MA_KNEE) + { + if (r_ptr->flags1 & RF1_MALE) + { + msg_format(_("%sに金的膝蹴りをくらわした!", "You hit %s in the groin with your knee!"), m_name); + sound(SOUND_PAIN); + special_effect = MA_KNEE; + } + else + msg_format(ma_ptr->desc, m_name); + } + + else if (ma_ptr->effect == MA_SLOW) + { + if (!((r_ptr->flags1 & RF1_NEVER_MOVE) || + my_strchr("~#{}.UjmeEv$,DdsbBFIJQSXclnw!=?", r_ptr->d_char))) + { + msg_format(_("%sの足首に関節蹴りをくらわした!", "You kick %s in the ankle."), m_name); + special_effect = MA_SLOW; + } + else msg_format(ma_ptr->desc, m_name); + } + else + { + if (ma_ptr->effect) + { + stun_effect = (ma_ptr->effect / 2) + randint1(ma_ptr->effect / 2); + } + + msg_format(ma_ptr->desc, m_name); + } + + if (p_ptr->special_defense & KAMAE_SUZAKU) weight = 4; + if ((p_ptr->pclass == CLASS_FORCETRAINER) && P_PTR_KI) + { + weight += (P_PTR_KI / 30); + if (weight > 20) weight = 20; + } + + k = critical_norm(p_ptr->lev * weight, min_level, k, p_ptr->to_h[0], 0); + + if ((special_effect == MA_KNEE) && ((k + p_ptr->to_d[hand]) < m_ptr->hp)) + { + msg_format(_("%^sは苦痛にうめいている!", "%^s moans in agony!"), m_name); + stun_effect = 7 + randint1(13); + resist_stun /= 3; + } + + else if ((special_effect == MA_SLOW) && ((k + p_ptr->to_d[hand]) < m_ptr->hp)) + { + if (!(r_ptr->flags1 & RF1_UNIQUE) && + (randint1(p_ptr->lev) > r_ptr->level) && + m_ptr->mspeed > 60) + { + msg_format(_("%^sは足をひきずり始めた。", "%^s starts limping slower."), m_name); + m_ptr->mspeed -= 10; + } + } + + if (stun_effect && ((k + p_ptr->to_d[hand]) < m_ptr->hp)) + { + if (p_ptr->lev > randint1(r_ptr->level + resist_stun + 10)) + { + if (set_monster_stunned(c_ptr->m_idx, stun_effect + MON_STUNNED(m_ptr))) + { + msg_format(_("%^sはフラフラになった。", "%^s is stunned."), m_name); + } + else + { + msg_format(_("%^sはさらにフラフラになった。", "%^s is more stunned."), m_name); + } + } + } + } + + /* Handle normal weapon */ + else if (o_ptr->k_idx) + { + k = damroll(o_ptr->dd + p_ptr->to_dd[hand], o_ptr->ds + p_ptr->to_ds[hand]); + k = tot_dam_aux(o_ptr, k, m_ptr, mode, FALSE); + + if (backstab) + { + k *= (3 + (p_ptr->lev / 20)); + } + else if (fuiuchi) + { + k = k*(5 + (p_ptr->lev * 2 / 25)) / 2; + } + else if (stab_fleeing) + { + k = (3 * k) / 2; + } + + if ((p_ptr->impact[hand] && ((k > 50) || one_in_(7))) || + (chaos_effect == 2) || (mode == HISSATSU_QUAKE)) + { + do_quake = TRUE; + } + + if ((!(o_ptr->tval == TV_SWORD) || !(o_ptr->sval == SV_DOKUBARI)) && !(mode == HISSATSU_KYUSHO)) + k = critical_norm(o_ptr->weight, o_ptr->to_h, k, p_ptr->to_h[hand], mode); + + drain_result = k; + + if (vorpal_cut) + { + int mult = 2; + + if ((o_ptr->name1 == ART_CHAINSWORD) && !one_in_(2)) + { + char chainsword_noise[1024]; + if (!get_rnd_line(_("chainswd_j.txt", "chainswd.txt"), 0, chainsword_noise)) + { + msg_print(chainsword_noise); + } + } + + if (o_ptr->name1 == ART_VORPAL_BLADE) + { + msg_print(_("目にも止まらぬヴォーパルブレード、手錬の早業!", "Your Vorpal Blade goes snicker-snack!")); + } + else + { + msg_format(_("%sをグッサリ切り裂いた!", "Your weapon cuts deep into %s!"), m_name); + } + + /* Try to increase the damage */ + while (one_in_(vorpal_chance)) + { + mult++; + } + + k *= (HIT_POINT)mult; + + /* Ouch! */ + if (((r_ptr->flagsr & RFR_RES_ALL) ? k / 100 : k) > m_ptr->hp) + { + msg_format(_("%sを真っ二つにした!", "You cut %s in half!"), m_name); + } + else + { + switch (mult) + { + case 2: msg_format(_("%sを斬った!", "You gouge %s!"), m_name); break; + case 3: msg_format(_("%sをぶった斬った!", "You maim %s!"), m_name); break; + case 4: msg_format(_("%sをメッタ斬りにした!", "You carve %s!"), m_name); break; + case 5: msg_format(_("%sをメッタメタに斬った!", "You cleave %s!"), m_name); break; + case 6: msg_format(_("%sを刺身にした!", "You smite %s!"), m_name); break; + case 7: msg_format(_("%sを斬って斬って斬りまくった!", "You eviscerate %s!"), m_name); break; + default: msg_format(_("%sを細切れにした!", "You shred %s!"), m_name); break; + } + } + drain_result = drain_result * 3 / 2; + } + + k += o_ptr->to_d; + drain_result += o_ptr->to_d; + } + + /* Apply the player damage bonuses */ + k += p_ptr->to_d[hand]; + drain_result += p_ptr->to_d[hand]; + + if ((mode == HISSATSU_SUTEMI) || (mode == HISSATSU_3DAN)) k *= 2; + if ((mode == HISSATSU_SEKIRYUKA) && !monster_living(r_ptr)) k = 0; + if ((mode == HISSATSU_SEKIRYUKA) && !p_ptr->cut) k /= 2; + + /* No negative damage */ + if (k < 0) k = 0; + + if ((mode == HISSATSU_ZANMA) && !(!monster_living(r_ptr) && (r_ptr->flags3 & RF3_EVIL))) + { + k = 0; + } + + if (zantetsu_mukou) + { + msg_print(_("こんな軟らかいものは切れん!", "You cannot cut such a elastic thing!")); + k = 0; + } + + if (e_j_mukou) + { + msg_print(_("蜘蛛は苦手だ!", "Spiders are difficult for you to deal with!")); + k /= 2; + } + + if (mode == HISSATSU_MINEUCHI) + { + int tmp = (10 + randint1(15) + p_ptr->lev / 5); + + k = 0; + anger_monster(m_ptr); + + if (!(r_ptr->flags3 & (RF3_NO_STUN))) + { + /* Get stunned */ + if (MON_STUNNED(m_ptr)) + { + msg_format(_("%sはひどくもうろうとした。", "%s is more dazed."), m_name); + tmp /= 2; + } + else + { + msg_format(_("%s はもうろうとした。", "%s is dazed."), m_name); + } + + /* Apply stun */ + (void)set_monster_stunned(c_ptr->m_idx, MON_STUNNED(m_ptr) + tmp); + } + else + { + msg_format(_("%s には効果がなかった。", "%s is not effected."), m_name); + } + } + + /* Modify the damage */ + k = mon_damage_mod(m_ptr, k, (bool)(((o_ptr->tval == TV_POLEARM) && (o_ptr->sval == SV_DEATH_SCYTHE)) || ((p_ptr->pclass == CLASS_BERSERKER) && one_in_(2)))); + if (((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DOKUBARI)) || (mode == HISSATSU_KYUSHO)) + { + if ((randint1(randint1(r_ptr->level / 7) + 5) == 1) && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags7 & RF7_UNIQUE2)) + { + k = m_ptr->hp + 1; + msg_format(_("%sの急所を突き刺した!", "You hit %s on a fatal spot!"), m_name); + } + else k = 1; + } + else if ((p_ptr->pclass == CLASS_NINJA) && buki_motteruka(INVEN_RARM + hand) && !p_ptr->icky_wield[hand] && ((p_ptr->cur_lite <= 0) || one_in_(7))) + { + int maxhp = maxroll(r_ptr->hdice, r_ptr->hside); + if (one_in_(backstab ? 13 : (stab_fleeing || fuiuchi) ? 15 : 27)) + { + k *= 5; + drain_result *= 2; + msg_format(_("刃が%sに深々と突き刺さった!", "You critically injured %s!"), m_name); + } + else if (((m_ptr->hp < maxhp / 2) && one_in_((p_ptr->num_blow[0] + p_ptr->num_blow[1] + 1) * 10)) || ((one_in_(666) || ((backstab || fuiuchi) && one_in_(11))) && !(r_ptr->flags1 & RF1_UNIQUE) && !(r_ptr->flags7 & RF7_UNIQUE2))) + { + if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_UNIQUE2) || (m_ptr->hp >= maxhp / 2)) + { + k = MAX(k * 5, m_ptr->hp / 2); + drain_result *= 2; + msg_format(_("%sに致命傷を負わせた!", "You fatally injured %s!"), m_name); + } + else + { + k = m_ptr->hp + 1; + msg_format(_("刃が%sの急所を貫いた!", "You hit %s on a fatal spot!"), m_name); + } + } + } + + msg_format_wizard(CHEAT_MONSTER, + _("%dのダメージを与えた。(残りHP %d/%d(%d))", "You do %d damage. (left HP %d/%d(%d))"), k, + m_ptr->hp - k, m_ptr->maxhp, m_ptr->max_maxhp); + + if (k <= 0) can_drain = FALSE; + + if (drain_result > m_ptr->hp) + drain_result = m_ptr->hp; + + /* Damage, check for fear and death */ + if (mon_take_hit(c_ptr->m_idx, k, fear, NULL)) + { + *mdeath = TRUE; + if ((p_ptr->pclass == CLASS_BERSERKER) && p_ptr->energy_use) + { + if (p_ptr->migite && p_ptr->hidarite) + { + if (hand) p_ptr->energy_use = p_ptr->energy_use * 3 / 5 + p_ptr->energy_use*num * 2 / (p_ptr->num_blow[hand] * 5); + else p_ptr->energy_use = p_ptr->energy_use*num * 3 / (p_ptr->num_blow[hand] * 5); + } + else + { + p_ptr->energy_use = p_ptr->energy_use*num / p_ptr->num_blow[hand]; + } + } + if ((o_ptr->name1 == ART_ZANTETSU) && is_lowlevel) + msg_print(_("またつまらぬものを斬ってしまった...", "Sigh... Another trifling thing I've cut....")); + break; + } + + /* Anger the monster */ + if (k > 0) anger_monster(m_ptr); + + touch_zap_player(m_ptr); + + /* Are we draining it? A little note: If the monster is + dead, the drain does not work... */ + + if (can_drain && (drain_result > 0)) + { + if (o_ptr->name1 == ART_MURAMASA) + { + if (is_human) + { + HIT_PROB to_h = o_ptr->to_h; + HIT_POINT to_d = o_ptr->to_d; + int i, flag; + + flag = 1; + for (i = 0; i < to_h + 3; i++) if (one_in_(4)) flag = 0; + if (flag) to_h++; + + flag = 1; + for (i = 0; i < to_d + 3; i++) if (one_in_(4)) flag = 0; + if (flag) to_d++; + + if (o_ptr->to_h != to_h || o_ptr->to_d != to_d) + { + msg_print(_("妖刀は血を吸って強くなった!", "Muramasa sucked blood, and became more powerful!")); + o_ptr->to_h = to_h; + o_ptr->to_d = to_d; + } + } + } + else + { + if (drain_result > 5) /* Did we really hurt it? */ + { + drain_heal = damroll(2, drain_result / 6); + + /* Hex */ + if (hex_spelling(HEX_VAMP_BLADE)) drain_heal *= 2; + + if (cheat_xtra) + { + msg_format(_("Draining left: %d", "Draining left: %d"), drain_left); + } + + if (drain_left) + { + if (drain_heal < drain_left) + { + drain_left -= drain_heal; + } + else + { + drain_heal = drain_left; + drain_left = 0; + } + + if (drain_msg) + { + msg_format(_("刃が%sから生命力を吸い取った!", "Your weapon drains life from %s!"), m_name); + drain_msg = FALSE; + } + + drain_heal = (drain_heal * mutant_regenerate_mod) / 100; + + hp_player(drain_heal); + /* We get to keep some of it! */ + } + } + } + m_ptr->maxhp -= (k + 7) / 8; + if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp; + if (m_ptr->maxhp < 1) m_ptr->maxhp = 1; + weak = TRUE; + } + can_drain = FALSE; + drain_result = 0; + + /* Confusion attack */ + if ((p_ptr->special_attack & ATTACK_CONFUSE) || (chaos_effect == 3) || (mode == HISSATSU_CONF) || hex_spelling(HEX_CONFUSION)) + { + /* Cancel glowing hands */ + if (p_ptr->special_attack & ATTACK_CONFUSE) + { + p_ptr->special_attack &= ~(ATTACK_CONFUSE); + msg_print(_("手の輝きがなくなった。", "Your hands stop glowing.")); + p_ptr->redraw |= (PR_STATUS); + + } + + /* Confuse the monster */ + if (r_ptr->flags3 & RF3_NO_CONF) + { + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= RF3_NO_CONF; + msg_format(_("%^sには効果がなかった。", "%^s is unaffected."), m_name); + + } + else if (randint0(100) < r_ptr->level) + { + msg_format(_("%^sには効果がなかった。", "%^s is unaffected."), m_name); + } + else + { + msg_format(_("%^sは混乱したようだ。", "%^s appears confused."), m_name); + (void)set_monster_confused(c_ptr->m_idx, MON_CONFUSED(m_ptr) + 10 + randint0(p_ptr->lev) / 5); + } + } -/* Purpose: Monster attacks */ + else if (chaos_effect == 4) + { + bool resists_tele = FALSE; -/* - * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke - * - * This software may be copied and distributed for educational, research, - * and not for profit purposes provided that this copyright and statement - * are included in all such copies. Other copyrights may also apply. - */ + if (r_ptr->flagsr & RFR_RES_TELE) + { + if (r_ptr->flags1 & RF1_UNIQUE) + { + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; + msg_format(_("%^sには効果がなかった。", "%^s is unaffected!"), m_name); + resists_tele = TRUE; + } + else if (r_ptr->level > randint1(100)) + { + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE; + msg_format(_("%^sは抵抗力を持っている!", "%^s resists!"), m_name); + resists_tele = TRUE; + } + } -#include "angband.h" + if (!resists_tele) + { + msg_format(_("%^sは消えた!", "%^s disappears!"), m_name); + teleport_away(c_ptr->m_idx, 50, TELEPORT_PASSIVE); + num = num_blow + 1; /* Can't hit it anymore! */ + *mdeath = TRUE; + } + } + else if ((chaos_effect == 5) && (randint1(90) > r_ptr->level)) + { + if (!(r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) && + !(r_ptr->flagsr & RFR_EFF_RES_CHAO_MASK)) + { + if (polymorph_monster(y, x)) + { + msg_format(_("%^sは変化した!", "%^s changes!"), m_name); + *fear = FALSE; + weak = FALSE; + } + else + { + msg_format(_("%^sには効果がなかった。", "%^s is unaffected."), m_name); + } -/* - * Critical blow. All hits that do 95% of total possible damage, - * and which also do at least 20 damage, or, sometimes, N damage. - * This is used only to determine "cuts" and "stuns". - */ -static int monster_critical(int dice, int sides, int dam) + /* Hack -- Get new monster */ + m_ptr = &m_list[c_ptr->m_idx]; + + /* Oops, we need a different name... */ + monster_desc(m_name, m_ptr, 0); + + /* Hack -- Get new race */ + r_ptr = &r_info[m_ptr->r_idx]; + } + } + else if (o_ptr->name1 == ART_G_HAMMER) + { + monster_type *target_ptr = &m_list[c_ptr->m_idx]; + + if (target_ptr->hold_o_idx) + { + object_type *q_ptr = &o_list[target_ptr->hold_o_idx]; + char o_name[MAX_NLEN]; + + object_desc(o_name, q_ptr, OD_NAME_ONLY); + q_ptr->held_m_idx = 0; + q_ptr->marked = OM_TOUCHED; + target_ptr->hold_o_idx = q_ptr->next_o_idx; + q_ptr->next_o_idx = 0; + msg_format(_("%sを奪った。", "You snatched %s."), o_name); + inven_carry(q_ptr); + } + } + } + + /* Player misses */ + else + { + backstab = FALSE; /* Clumsy! */ + fuiuchi = FALSE; /* Clumsy! */ + + if ((o_ptr->tval == TV_POLEARM) && (o_ptr->sval == SV_DEATH_SCYTHE) && one_in_(3)) + { + u32b flgs_aux[TR_FLAG_SIZE]; + + sound(SOUND_HIT); + + msg_format(_("ミス! %sにかわされた。", "You miss %s."), m_name); + msg_print(_("振り回した大鎌が自分自身に返ってきた!", "Your scythe returns to you!")); + + /* Extract the flags */ + object_flags(o_ptr, flgs_aux); + + k = damroll(o_ptr->dd + p_ptr->to_dd[hand], o_ptr->ds + p_ptr->to_ds[hand]); + { + int mult; + switch (p_ptr->mimic_form) + { + case MIMIC_NONE: + switch (p_ptr->prace) + { + case RACE_YEEK: + case RACE_KLACKON: + case RACE_HUMAN: + case RACE_AMBERITE: + case RACE_DUNADAN: + case RACE_BARBARIAN: + case RACE_BEASTMAN: + mult = 25; break; + case RACE_HALF_ORC: + case RACE_HALF_TROLL: + case RACE_HALF_OGRE: + case RACE_HALF_GIANT: + case RACE_HALF_TITAN: + case RACE_CYCLOPS: + case RACE_IMP: + case RACE_SKELETON: + case RACE_ZOMBIE: + case RACE_VAMPIRE: + case RACE_SPECTRE: + case RACE_DEMON: + case RACE_DRACONIAN: + mult = 30; break; + default: + mult = 10; break; + } + break; + case MIMIC_DEMON: + case MIMIC_DEMON_LORD: + case MIMIC_VAMPIRE: + mult = 30; break; + default: + mult = 10; break; + } + + if (p_ptr->align < 0 && mult < 20) + mult = 20; + if (!(p_ptr->resist_acid || IS_OPPOSE_ACID() || p_ptr->immune_acid) && (mult < 25)) + mult = 25; + if (!(p_ptr->resist_elec || IS_OPPOSE_ELEC() || p_ptr->immune_elec) && (mult < 25)) + mult = 25; + if (!(p_ptr->resist_fire || IS_OPPOSE_FIRE() || p_ptr->immune_fire) && (mult < 25)) + mult = 25; + if (!(p_ptr->resist_cold || IS_OPPOSE_COLD() || p_ptr->immune_cold) && (mult < 25)) + mult = 25; + if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()) && (mult < 25)) + mult = 25; + + if ((p_ptr->pclass != CLASS_SAMURAI) && (have_flag(flgs_aux, TR_FORCE_WEAPON)) && (p_ptr->csp >(p_ptr->msp / 30))) + { + p_ptr->csp -= (1 + (p_ptr->msp / 30)); + p_ptr->redraw |= (PR_MANA); + mult = mult * 3 / 2 + 20; + } + k *= (HIT_POINT)mult; + k /= 10; + } + + k = critical_norm(o_ptr->weight, o_ptr->to_h, k, p_ptr->to_h[hand], mode); + if (one_in_(6)) + { + int mult = 2; + msg_format(_("グッサリ切り裂かれた!", "Your weapon cuts deep into yourself!")); + /* Try to increase the damage */ + while (one_in_(4)) + { + mult++; + } + + k *= (HIT_POINT)mult; + } + k += (p_ptr->to_d[hand] + o_ptr->to_d); + if (k < 0) k = 0; + + take_hit(DAMAGE_FORCE, k, _("死の大鎌", "Death scythe"), -1); + redraw_stuff(); + } + else + { + sound(SOUND_MISS); + + msg_format(_("ミス! %sにかわされた。", "You miss %s."), m_name); + } + } + backstab = FALSE; + fuiuchi = FALSE; + } + + + if (weak && !(*mdeath)) + { + msg_format(_("%sは弱くなったようだ。", "%^s seems weakened."), m_name); + } + if (drain_left != MAX_VAMPIRIC_DRAIN) + { + if (one_in_(4)) + { + chg_virtue(V_UNLIFE, 1); + } + } + /* Mega-Hack -- apply earthquake brand */ + if (do_quake) + { + earthquake(p_ptr->y, p_ptr->x, 10); + if (!cave[y][x].m_idx) *mdeath = TRUE; + } +} + + +/*! +* @brief プレイヤーの打撃処理メインルーチン +* @param y 攻撃目標のY座標 +* @param x 攻撃目標のX座標 +* @param mode 発動中の剣術ID +* @return 実際に攻撃処理が行われた場合TRUEを返す。 +* @details +* If no "weapon" is available, then "punch" the monster one time. +*/ +bool py_attack(POSITION y, POSITION x, BIT_FLAGS mode) { - int max = 0; - int total = dice * sides; + bool fear = FALSE; + bool mdeath = FALSE; + bool stormbringer = FALSE; - /* Must do at least 95% of perfect */ - if (dam < total * 19 / 20) return (0); + cave_type *c_ptr = &cave[y][x]; + monster_type *m_ptr = &m_list[c_ptr->m_idx]; + monster_race *r_ptr = &r_info[m_ptr->r_idx]; + char m_name[80]; - /* Weak blows rarely work */ - if ((dam < 20) && (randint0(100) >= dam)) return (0); + disturb(FALSE, TRUE); - /* Perfect damage */ - if ((dam >= total) && (dam >= 40)) max++; + p_ptr->energy_use = 100; - /* Super-charge */ - if (dam >= 20) + if (!p_ptr->migite && !p_ptr->hidarite && + !(p_ptr->muta2 & (MUT2_HORNS | MUT2_BEAK | MUT2_SCOR_TAIL | MUT2_TRUNK | MUT2_TENTACLES))) { - while (randint0(100) < 2) max++; + msg_format(_("%s攻撃できない。", "You cannot do attacking."), + (empty_hands(FALSE) == EMPTY_HAND_NONE) ? _("両手がふさがって", "") : ""); + return FALSE; } - /* Critical damage */ - if (dam > 45) return (6 + max); - if (dam > 33) return (5 + max); - if (dam > 25) return (4 + max); - if (dam > 18) return (3 + max); - if (dam > 11) return (2 + max); - return (1 + max); -} + /* Extract monster name (or "it") */ + monster_desc(m_name, m_ptr, 0); + if (m_ptr->ml) + { + /* Auto-Recall if possible and visible */ + if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx); + /* Track a new monster */ + health_track(c_ptr->m_idx); + } + if ((r_ptr->flags1 & RF1_FEMALE) && + !(p_ptr->stun || p_ptr->confused || p_ptr->image || !m_ptr->ml)) + { + if ((inventory[INVEN_RARM].name1 == ART_ZANTETSU) || (inventory[INVEN_LARM].name1 == ART_ZANTETSU)) + { + msg_print(_("拙者、おなごは斬れぬ!", "I can not attack women!")); + return FALSE; + } + } + if (d_info[dungeon_type].flags1 & DF1_NO_MELEE) + { + msg_print(_("なぜか攻撃することができない。", "Something prevent you from attacking.")); + return FALSE; + } -/* - * Determine if a monster attack against the player succeeds. - * Always miss 5% of the time, Always hit 5% of the time. - * Otherwise, match monster power against player armor. - */ -static int check_hit(int power, int level, int stun) -{ - int i, k, ac; + /* Stop if friendly */ + if (!is_hostile(m_ptr) && + !(p_ptr->stun || p_ptr->confused || p_ptr->image || + p_ptr->shero || !m_ptr->ml)) + { + if (inventory[INVEN_RARM].name1 == ART_STORMBRINGER) stormbringer = TRUE; + if (inventory[INVEN_LARM].name1 == ART_STORMBRINGER) stormbringer = TRUE; + if (stormbringer) + { + msg_format(_("黒い刃は強欲に%sを攻撃した!", "Your black blade greedily attacks %s!"), m_name); + chg_virtue(V_INDIVIDUALISM, 1); + chg_virtue(V_HONOUR, -1); + chg_virtue(V_JUSTICE, -1); + chg_virtue(V_COMPASSION, -1); + } + else if (p_ptr->pclass != CLASS_BERSERKER) + { + if (get_check(_("本当に攻撃しますか?", "Really hit it? "))) + { + chg_virtue(V_INDIVIDUALISM, 1); + chg_virtue(V_HONOUR, -1); + chg_virtue(V_JUSTICE, -1); + chg_virtue(V_COMPASSION, -1); + } + else + { + msg_format(_("%sを攻撃するのを止めた。", "You stop to avoid hitting %s."), m_name); + return FALSE; + } + } + } - /* Percentile dice */ - k = randint0(100); - if (stun && one_in_(2)) return FALSE; + /* Handle player fear */ + if (p_ptr->afraid) + { + if (m_ptr->ml) + msg_format(_("恐くて%sを攻撃できない!", "You are too afraid to attack %s!"), m_name); + else + msg_format(_("そっちには何か恐いものがいる!", "There is something scary in your way!")); - /* Hack -- Always miss or hit */ - if (k < 10) return (k < 5); + /* Disturb the monster */ + (void)set_monster_csleep(c_ptr->m_idx, 0); - /* Calculate the "attack quality" */ - i = (power + (level * 3)); + return FALSE; + } - /* Total armor */ - ac = p_ptr->ac + p_ptr->to_a; - if (p_ptr->special_attack & ATTACK_SUIKEN) ac += (p_ptr->lev * 2); + if (MON_CSLEEP(m_ptr)) /* It is not honorable etc to attack helpless victims */ + { + if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_COMPASSION, -1); + if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_HONOUR, -1); + } - /* Power and Level compete against Armor */ - if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE); + if (p_ptr->migite && p_ptr->hidarite) + { + if ((p_ptr->skill_exp[GINOU_NITOURYU] < s_info[p_ptr->pclass].s_max[GINOU_NITOURYU]) && ((p_ptr->skill_exp[GINOU_NITOURYU] - 1000) / 200 < r_ptr->level)) + { + if (p_ptr->skill_exp[GINOU_NITOURYU] < WEAPON_EXP_BEGINNER) + p_ptr->skill_exp[GINOU_NITOURYU] += 80; + else if (p_ptr->skill_exp[GINOU_NITOURYU] < WEAPON_EXP_SKILLED) + p_ptr->skill_exp[GINOU_NITOURYU] += 4; + else if (p_ptr->skill_exp[GINOU_NITOURYU] < WEAPON_EXP_EXPERT) + p_ptr->skill_exp[GINOU_NITOURYU] += 1; + else if (p_ptr->skill_exp[GINOU_NITOURYU] < WEAPON_EXP_MASTER) + if (one_in_(3)) p_ptr->skill_exp[GINOU_NITOURYU] += 1; + p_ptr->update |= (PU_BONUS); + } + } - /* Assume miss */ - return (FALSE); -} + /* Gain riding experience */ + if (p_ptr->riding) + { + int cur = p_ptr->skill_exp[GINOU_RIDING]; + int max = s_info[p_ptr->pclass].s_max[GINOU_RIDING]; + if (cur < max) + { + int ridinglevel = r_info[m_list[p_ptr->riding].r_idx].level; + int targetlevel = r_ptr->level; + int inc = 0; + if ((cur / 200 - 5) < targetlevel) + inc += 1; -/* - * Hack -- possible "insult" messages - */ -static cptr desc_insult[] = -{ -#ifdef JP - "¤¬¤¢¤Ê¤¿¤òÉî¿«¤·¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤ÎÊì¤òÉî¿«¤·¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤ò·ÚÊΤ·¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤ò¿«¤á¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤ò±ø¤·¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤Î²ó¤ê¤ÇÍ٤ä¿¡ª", - "¤¬àÐêø¤Ê¿È¤Ö¤ê¤ò¤·¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤ò¤Ü¤ó¤ä¤ê¤È¸«¤¿¡ª¡ª¡ª", - "¤¬¤¢¤Ê¤¿¤ò¥Ñ¥é¥µ¥¤¥È¸Æ¤Ð¤ï¤ê¤·¤¿¡ª", - "¤¬¤¢¤Ê¤¿¤ò¥µ¥¤¥Ü¡¼¥°°·¤¤¤·¤¿¡ª" -#else - "insults you!", - "insults your mother!", - "gives you the finger!", - "humiliates you!", - "defiles you!", - "dances around you!", - "makes obscene gestures!", - "moons you!!!" - "calls you a parasite!", - "calls you a cyborg!" -#endif + /* Extra experience */ + if ((cur / 100) < ridinglevel) + { + if ((cur / 100 + 15) < ridinglevel) + inc += 1 + (ridinglevel - (cur / 100 + 15)); + else + inc += 1; + } -}; + p_ptr->skill_exp[GINOU_RIDING] = MIN(max, cur + inc); + p_ptr->update |= (PU_BONUS); + } + } + riding_t_m_idx = c_ptr->m_idx; + if (p_ptr->migite) py_attack_aux(y, x, &fear, &mdeath, 0, mode); + if (p_ptr->hidarite && !mdeath) py_attack_aux(y, x, &fear, &mdeath, 1, mode); -/* - * Hack -- possible "insult" messages - */ -static cptr desc_moan[] = -{ -#ifdef JP - "¤Ï²¿¤«¤òÈᤷ¤ó¤Ç¤¤¤ë¤è¤¦¤À¡£", - "¤¬Èà¤Î»ô¤¤¸¤¤ò¸«¤Ê¤«¤Ã¤¿¤«¤È¿Ò¤Í¤Æ¤¤¤ë¡£", - "¤¬ÆìÄ¥¤ê¤«¤é½Ð¤Æ¹Ô¤±¤È¸À¤Ã¤Æ¤¤¤ë¡£", - "¤Ï¥­¥Î¥³¤¬¤É¤¦¤È¤«Ò줤¤Æ¤¤¤ë¡£" -#else - "seems sad about something.", - "asks if you have seen his dogs.", - "tells you to get off his land.", - "mumbles something about mushrooms." -#endif + /* Mutations which yield extra 'natural' attacks */ + if (!mdeath) + { + if ((p_ptr->muta2 & MUT2_HORNS) && !mdeath) + natural_attack(c_ptr->m_idx, MUT2_HORNS, &fear, &mdeath); + if ((p_ptr->muta2 & MUT2_BEAK) && !mdeath) + natural_attack(c_ptr->m_idx, MUT2_BEAK, &fear, &mdeath); + if ((p_ptr->muta2 & MUT2_SCOR_TAIL) && !mdeath) + natural_attack(c_ptr->m_idx, MUT2_SCOR_TAIL, &fear, &mdeath); + if ((p_ptr->muta2 & MUT2_TRUNK) && !mdeath) + natural_attack(c_ptr->m_idx, MUT2_TRUNK, &fear, &mdeath); + if ((p_ptr->muta2 & MUT2_TENTACLES) && !mdeath) + natural_attack(c_ptr->m_idx, MUT2_TENTACLES, &fear, &mdeath); + } -}; + /* Hack -- delay fear messages */ + if (fear && m_ptr->ml && !mdeath) + { + sound(SOUND_FLEE); + + msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name); + } + + if ((p_ptr->special_defense & KATA_IAI) && ((mode != HISSATSU_IAI) || mdeath)) + { + set_action(ACTION_NONE); + } + + return mdeath; +} -/* - * Attack the player via physical attacks. +/*! + * @brief モンスターからプレイヤーへの打撃処理 / Attack the player via physical attacks. + * @param m_idx 打撃を行うモンスターのID + * @return 実際に攻撃処理を行った場合TRUEを返す */ -bool make_attack_normal(int m_idx) +bool make_attack_normal(MONSTER_IDX m_idx) { monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; int ap_cnt; - int i, k, tmp, ac, rlev; + INVENTORY_IDX i; + int k, tmp, ac, rlev; int do_cut, do_stun; s32b gold; @@ -165,10 +1544,8 @@ bool make_attack_normal(int m_idx) bool touched = FALSE, fear = FALSE, alive = TRUE; bool explode = FALSE; bool do_silly_attack = (one_in_(2) && p_ptr->image); - int get_damage = 0; -#ifdef JP + HIT_POINT get_damage = 0; int abbreviate = 0; -#endif /* Not allowed to attack */ if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE); @@ -190,18 +1567,13 @@ bool make_attack_normal(int m_idx) if (p_ptr->special_defense & KATA_IAI) { -#ifdef JP - msg_print("Áê¼ê¤¬½±¤¤¤«¤«¤ëÁ°¤ËÁÇÁ᤯Éð´ï¤ò¿¶¤ë¤Ã¤¿¡£"); -#else - msg_format("You took sen, draw and cut in one motion before %s move.", m_name); -#endif + msg_format(_("相手が襲いかかる前に素早く武器を振るった。", "You took sen, draw and cut in one motion before %s move."), m_name); if (py_attack(m_ptr->fy, m_ptr->fx, HISSATSU_IAI)) return TRUE; } if ((p_ptr->special_defense & NINJA_KAWARIMI) && (randint0(55) < (p_ptr->lev*3/5+20))) { - kawarimi(TRUE); - return TRUE; + if (kawarimi(TRUE)) return TRUE; } /* Assume no blink */ @@ -210,11 +1582,10 @@ bool make_attack_normal(int m_idx) /* Scan through all four blows */ for (ap_cnt = 0; ap_cnt < 4; ap_cnt++) { - bool visible = FALSE; bool obvious = FALSE; - int power = 0; - int damage = 0; + HIT_POINT power = 0; + HIT_POINT damage = 0; cptr act = NULL; @@ -238,16 +1609,13 @@ bool make_attack_normal(int m_idx) /* Stop if player is dead or gone */ if (!p_ptr->playing || p_ptr->is_dead) break; - if (distance(py, px, m_ptr->fy, m_ptr->fx) > 1) break; + if (distance(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx) > 1) break; /* Handle "leaving" */ if (p_ptr->leaving) break; if (method == RBM_SHOOT) continue; - /* Extract visibility (before blink) */ - if (m_ptr->ml) visible = TRUE; - /* Extract the attack "power" */ power = mbe_info[effect].power; @@ -255,10 +1623,10 @@ bool make_attack_normal(int m_idx) ac = p_ptr->ac + p_ptr->to_a; /* Monster hits player */ - if (!effect || check_hit(power, rlev, m_ptr->stunned)) + if (!effect || check_hit(power, rlev, MON_STUNNED(m_ptr))) { /* Always disturbing */ - disturb(1, 0); + disturb(TRUE, TRUE); /* Hack -- Apply "protection from evil" */ @@ -268,18 +1636,14 @@ bool make_attack_normal(int m_idx) ((randint0(100) + p_ptr->lev) > 50)) { /* Remember the Evil-ness */ - if (m_ptr->ml) - { - r_ptr->r_flags3 |= RF3_EVIL; - } + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= RF3_EVIL; - /* Message */ #ifdef JP if (abbreviate) - msg_format("·âÂष¤¿¡£"); + msg_format("撃退した。"); else - msg_format("%^s¤Ï·âÂव¤ì¤¿¡£", m_name); - abbreviate = 1;/*£²²óÌܰʹߤϾÊά */ + msg_format("%^sは撃退された。", m_name); + abbreviate = 1;/*2回目以降は省略 */ #else msg_format("%^s is repelled.", m_name); #endif @@ -298,12 +1662,7 @@ bool make_attack_normal(int m_idx) { case RBM_HIT: { -#ifdef JP - act = "²¥¤é¤ì¤¿¡£"; -#else - act = "hits you."; -#endif - + act = _("殴られた。", "hits you."); do_cut = do_stun = 1; touched = TRUE; sound(SOUND_HIT); @@ -312,12 +1671,7 @@ bool make_attack_normal(int m_idx) case RBM_TOUCH: { -#ifdef JP - act = "¿¨¤é¤ì¤¿¡£"; -#else - act = "touches you."; -#endif - + act = _("触られた。", "touches you."); touched = TRUE; sound(SOUND_TOUCH); break; @@ -325,12 +1679,7 @@ bool make_attack_normal(int m_idx) case RBM_PUNCH: { -#ifdef JP - act = "¥Ñ¥ó¥Á¤µ¤ì¤¿¡£"; -#else - act = "punches you."; -#endif - + act = _("パンチされた。", "punches you."); touched = TRUE; do_stun = 1; sound(SOUND_HIT); @@ -339,12 +1688,7 @@ bool make_attack_normal(int m_idx) case RBM_KICK: { -#ifdef JP - act = "½³¤é¤ì¤¿¡£"; -#else - act = "kicks you."; -#endif - + act = _("蹴られた。", "kicks you."); touched = TRUE; do_stun = 1; sound(SOUND_HIT); @@ -353,12 +1697,7 @@ bool make_attack_normal(int m_idx) case RBM_CLAW: { -#ifdef JP - act = "¤Ò¤Ã¤«¤«¤ì¤¿¡£"; -#else - act = "claws you."; -#endif - + act = _("ひっかかれた。", "claws you."); touched = TRUE; do_cut = 1; sound(SOUND_CLAW); @@ -367,12 +1706,7 @@ bool make_attack_normal(int m_idx) case RBM_BITE: { -#ifdef JP - act = "³ú¤Þ¤ì¤¿¡£"; -#else - act = "bites you."; -#endif - + act = _("噛まれた。", "bites you."); do_cut = 1; touched = TRUE; sound(SOUND_BITE); @@ -381,12 +1715,7 @@ bool make_attack_normal(int m_idx) case RBM_STING: { -#ifdef JP - act = "»É¤µ¤ì¤¿¡£"; -#else - act = "stings you."; -#endif - + act = _("刺された。", "stings you."); touched = TRUE; sound(SOUND_STING); break; @@ -394,12 +1723,7 @@ bool make_attack_normal(int m_idx) case RBM_SLASH: { -#ifdef JP - act = "»Â¤é¤ì¤¿¡£"; -#else - act = "slashes you."; -#endif - + act = _("斬られた。", "slashes you."); touched = TRUE; do_cut = 1; sound(SOUND_CLAW); @@ -408,26 +1732,16 @@ bool make_attack_normal(int m_idx) case RBM_BUTT: { -#ifdef JP - act = "³Ñ¤ÇÆͤ«¤ì¤¿¡£"; -#else - act = "butts you."; -#endif - + act = _("角で突かれた。", "butts you."); do_stun = 1; touched = TRUE; sound(SOUND_HIT); break; - } - - case RBM_CRUSH: - { -#ifdef JP - act = "ÂÎÅö¤¿¤ê¤µ¤ì¤¿¡£"; -#else - act = "crushes you."; -#endif + } + case RBM_CRUSH: + { + act = _("体当たりされた。", "crushes you."); do_stun = 1; touched = TRUE; sound(SOUND_CRUSH); @@ -436,12 +1750,7 @@ bool make_attack_normal(int m_idx) case RBM_ENGULF: { -#ifdef JP - act = "°û¤ß¹þ¤Þ¤ì¤¿¡£"; -#else - act = "engulfs you."; -#endif - + act = _("飲み込まれた。", "engulfs you."); touched = TRUE; sound(SOUND_CRUSH); break; @@ -449,13 +1758,8 @@ bool make_attack_normal(int m_idx) case RBM_CHARGE: { -#ifdef JP abbreviate = -1; - act = "¤ÏÀÁµá½ñ¤ò¤è¤³¤·¤¿¡£"; -#else - act = "charges you."; -#endif - + act = _("は請求書をよこした。", "charges you."); touched = TRUE; sound(SOUND_BUY); /* Note! This is "charges", not "charges at". */ break; @@ -463,13 +1767,8 @@ bool make_attack_normal(int m_idx) case RBM_CRAWL: { -#ifdef JP abbreviate = -1; - act = "¤¬ÂΤξå¤òÇ礤²ó¤Ã¤¿¡£"; -#else - act = "crawls on you."; -#endif - + act = _("が体の上を這い回った。", "crawls on you."); touched = TRUE; sound(SOUND_SLIME); break; @@ -477,96 +1776,56 @@ bool make_attack_normal(int m_idx) case RBM_DROOL: { -#ifdef JP - act = "¤è¤À¤ì¤ò¤¿¤é¤µ¤ì¤¿¡£"; -#else - act = "drools on you."; -#endif - + act = _("よだれをたらされた。", "drools on you."); sound(SOUND_SLIME); break; } case RBM_SPIT: { -#ifdef JP - act = "ÂäòÅǤ«¤ì¤¿¡£"; -#else - act = "spits on you."; -#endif - + act = _("唾を吐かれた。", "spits on you."); sound(SOUND_SLIME); break; } case RBM_EXPLODE: { -#ifdef JP abbreviate = -1; - act = "¤ÏÇúȯ¤·¤¿¡£"; -#else - act = "explodes."; -#endif - + act = _("は爆発した。", "explodes."); explode = TRUE; break; } case RBM_GAZE: { -#ifdef JP - act = "¤Ë¤é¤Þ¤ì¤¿¡£"; -#else - act = "gazes at you."; -#endif - + act = _("にらまれた。", "gazes at you."); break; } case RBM_WAIL: { -#ifdef JP - act = "µã¤­¶«¤Ð¤ì¤¿¡£"; -#else - act = "wails at you."; -#endif - + act = _("泣き叫ばれた。", "wails at you."); sound(SOUND_WAIL); break; } case RBM_SPORE: { -#ifdef JP - act = "˦»Ò¤òÈô¤Ð¤µ¤ì¤¿¡£"; -#else - act = "releases spores at you."; -#endif - + act = _("胞子を飛ばされた。", "releases spores at you."); sound(SOUND_SLIME); break; } case RBM_XXX4: { -#ifdef JP abbreviate = -1; - act = "¤¬ XXX4 ¤òȯ¼Í¤·¤¿¡£"; -#else - act = "projects XXX4's at you."; -#endif - + act = _("が XXX4 を発射した。", "projects XXX4's at you."); break; } case RBM_BEG: { -#ifdef JP - act = "¶â¤ò¤»¤¬¤Þ¤ì¤¿¡£"; -#else - act = "begs you for money."; -#endif - + act = _("金をせがまれた。", "begs you for money."); sound(SOUND_MOAN); break; } @@ -604,43 +1863,43 @@ bool make_attack_normal(int m_idx) case 1: case 6: case 11: - act = "¡Ö¢ö¤ª¡Á¤ì¤Ï¥¸¥ã¥¤¥¢¥ó¡Á¡Á¥¬¡Á¥­¤À¤¤¤·¤ç¤¦¡Á¡×"; + act = "「♪お~れはジャイアン~~ガ~キだいしょう~」"; break; case 2: - act = "¡Ö¢ö¤Æ¡Á¤ó¤«¤à¡Á¤Æ¤­¤Î¤ª¡Á¤È¤³¤À¤¼¡Á¡Á¡×"; + act = "「♪て~んかむ~てきのお~とこだぜ~~」"; break; case 3: - act = "¡Ö¢ö¤Î¡Á¤ÓÂÀ¥¹¥ÍÉפϥᤸ¤ã¤Ê¤¤¤è¡Á¡Á¡×"; + act = "「♪の~び太スネ夫はメじゃないよ~~」"; break; case 4: - act = "¡Ö¢ö¤±¡Á¤ó¤«¥¹¥Ý¡Á¥Ä¡Á¤É¤ó¤È¤³¤¤¡Á¡×"; + act = "「♪け~んかスポ~ツ~どんとこい~」"; break; case 5: - act = "¡Ö¢ö¤¦¤¿¡Á¤â¡Á¡Á¤¦¡Á¤Þ¤¤¤¼¡Á¤Þ¤«¤·¤È¤±¡Á¡×"; + act = "「♪うた~も~~う~まいぜ~まかしとけ~」"; break; case 7: - act = "¡Ö¢ö¤Þ¡Á¤Á¤¤¤Á¤Ð¡Á¤ó¤Î¤Ë¡Á¤ó¤­¤â¤Î¡Á¡Á¡×"; + act = "「♪ま~ちいちば~んのに~んきもの~~」"; break; case 8: - act = "¡Ö¢ö¤Ù¤ó¤­¤ç¤¦¤·¤å¤¯¤À¤¤¥á¤¸¤ã¤Ê¤¤¤è¡Á¡Á¡×"; + act = "「♪べんきょうしゅくだいメじゃないよ~~」"; break; case 9: - act = "¡Ö¢ö¤­¤Ï¤ä¤µ¤·¡Á¤¯¤Æ¡Á¤Á¡Á¤«¤é¤â¤Á¡Á¡×"; + act = "「♪きはやさし~くて~ち~からもち~」"; break; case 10: - act = "¡Ö¢ö¤«¤ª¡Á¤â¡Á¡Á¥¹¥¿¥¤¥ë¤â¡Á¥Ð¥Ä¥°¥ó¤µ¡Á¡×"; + act = "「♪かお~も~~スタイルも~バツグンさ~」"; break; case 12: - act = "¡Ö¢ö¤¬¤Ã¤³¤¦¤¤¡Á¤Á¤Î¡Á¤¢¡Á¤Ð¤ì¤ó¤Ü¤¦¡Á¡Á¡×"; + act = "「♪がっこうい~ちの~あ~ばれんぼう~~」"; break; case 13: - act = "¡Ö¢ö¥É¡Á¥é¤â¥É¥é¥ß¤â¥á¤¸¤ã¤Ê¤¤¤è¡Á¡Á¡×"; + act = "「♪ド~ラもドラミもメじゃないよ~~」"; break; case 14: - act = "¡Ö¢ö¤è¤¸¤²¤ó¤Ý¤±¤Ã¤È¡Á¤Ê¡Á¤¯¤¿¤Ã¤Æ¡Á¡×"; + act = "「♪よじげんぽけっと~な~くたって~」"; break; case 15: - act = "¡Ö¢ö¤¢¤·¡Á¤Î¡Á¡Á¤Ê¤¬¤µ¡Á¤Ï¡Á¤Þ¤±¤Ê¤¤¤¼¡Á¡×"; + act = "「♪あし~の~~ながさ~は~まけないぜ~」"; break; } #else @@ -651,9 +1910,9 @@ bool make_attack_normal(int m_idx) { if (one_in_(3)) #ifdef JP - act = "¤Ï¢öËͤé¤Ï³Ú¤·¤¤²È²¢ö¤È²Î¤Ã¤Æ¤¤¤ë¡£"; + act = "は♪僕らは楽しい家族♪と歌っている。"; else - act = "¤Ï¢ö¥¢¥¤ ¥é¥Ö ¥æ¡¼¡¢¥æ¡¼ ¥é¥Ö ¥ß¡¼¢ö¤È²Î¤Ã¤Æ¤¤¤ë¡£"; + act = "は♪アイ ラブ ユー、ユー ラブ ミー♪と歌っている。"; #else act = "sings 'We are a happy family.'"; else @@ -666,7 +1925,6 @@ bool make_attack_normal(int m_idx) } } - /* Message */ if (act) { if (do_silly_attack) @@ -678,12 +1936,12 @@ bool make_attack_normal(int m_idx) } #ifdef JP if (abbreviate == 0) - msg_format("%^s¤Ë%s", m_name, act); + msg_format("%^sに%s", m_name, act); else if (abbreviate == 1) msg_format("%s", act); else /* if (abbreviate == -1) */ msg_format("%^s%s", m_name, act); - abbreviate = 1;/*£²²óÌܰʹߤϾÊά */ + abbreviate = 1;/*2回目以降は省略 */ #else msg_format("%^s %s%s", m_name, act, do_silly_attack ? " you." : ""); #endif @@ -717,30 +1975,23 @@ bool make_attack_normal(int m_idx) case RBE_SUPERHURT: { - if ((randint1(rlev*2+300) > (ac+200)) || one_in_(13)) { - int tmp_damage = damage-(damage*((ac < 150) ? ac : 150)/250); -#ifdef JP - msg_print("Ä˺¨¤Î°ì·â¡ª"); -#else - msg_print("It was a critical hit!"); -#endif - + if (((randint1(rlev*2+300) > (ac+200)) || one_in_(13)) && !CHECK_MULTISHADOW()) + { + int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250); + msg_print(_("痛恨の一撃!", "It was a critical hit!")); tmp_damage = MAX(damage, tmp_damage*2); - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, tmp_damage, ddesc, -1); break; } } case RBE_HURT: { - /* Obvious */ obvious = TRUE; /* Hack -- Player armor reduces total damage */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); break; @@ -751,7 +2002,7 @@ bool make_attack_normal(int m_idx) if (explode) break; /* Take "poison" effect */ - if (!(p_ptr->resist_pois || IS_OPPOSE_POIS())) + if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()) && !CHECK_MULTISHADOW()) { if (set_poisoned(p_ptr->poisoned + randint1(rlev) + 5)) { @@ -773,7 +2024,7 @@ bool make_attack_normal(int m_idx) if (explode) break; /* Allow complete resist */ - if (!p_ptr->resist_disen) + if (!p_ptr->resist_disen && !CHECK_MULTISHADOW()) { /* Apply disenchantment */ if (apply_disenchant(0)) @@ -798,13 +2049,13 @@ bool make_attack_normal(int m_idx) /* Take some damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; /* Find an item */ for (k = 0; k < 10; k++) { /* Pick an item */ - i = randint0(INVEN_PACK); + i = (INVENTORY_IDX)randint0(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; @@ -825,19 +2076,12 @@ bool make_attack_normal(int m_idx) /* Don't heal more than max hp */ heal = MIN(heal, m_ptr->maxhp - m_ptr->hp); - /* Message */ -#ifdef JP - msg_print("¥¶¥Ã¥¯¤«¤é¥¨¥Í¥ë¥®¡¼¤¬µÛ¤¤¼è¤é¤ì¤¿¡ª"); -#else - msg_print("Energy drains from your pack!"); -#endif - + msg_print(_("ザックからエネルギーが吸い取られた!", "Energy drains from your pack!")); - /* Obvious */ obvious = TRUE; /* Heal the monster */ - m_ptr->hp += heal; + m_ptr->hp += (HIT_POINT)heal; /* Redraw (later) if needed */ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); @@ -849,10 +2093,8 @@ bool make_attack_normal(int m_idx) /* Combine / Reorder the pack */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); - /* Window stuff */ p_ptr->window |= (PW_INVEN); - /* Done */ break; } } @@ -866,11 +2108,10 @@ bool make_attack_normal(int m_idx) get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); /* Confused monsters cannot steal successfully. -LM-*/ - if (m_ptr->confused) break; + if (MON_CONFUSED(m_ptr)) break; - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; - /* Obvious */ obvious = TRUE; /* Saving throw (unless paralyzed) based on dex and level */ @@ -879,12 +2120,7 @@ bool make_attack_normal(int m_idx) p_ptr->lev))) { /* Saving throw message */ -#ifdef JP - msg_print("¤·¤«¤·ÁÇÁ᤯ºâÉÛ¤ò¼é¤Ã¤¿¡ª"); -#else - msg_print("You quickly protect your money pouch!"); -#endif - + msg_print(_("しかし素早く財布を守った!", "You quickly protect your money pouch!")); /* Occasional blink anyway */ if (randint0(3)) blinked = TRUE; @@ -900,41 +2136,24 @@ bool make_attack_normal(int m_idx) p_ptr->au -= gold; if (gold <= 0) { -#ifdef JP - msg_print("¤·¤«¤·²¿¤âÅð¤Þ¤ì¤Ê¤«¤Ã¤¿¡£"); -#else - msg_print("Nothing was stolen."); -#endif - + msg_print(_("しかし何も盗まれなかった。", "Nothing was stolen.")); } else if (p_ptr->au) { -#ifdef JP - msg_print("ºâÉÛ¤¬·Ú¤¯¤Ê¤Ã¤¿µ¤¤¬¤¹¤ë¡£"); - msg_format("$%ld ¤Î¤ª¶â¤¬Åð¤Þ¤ì¤¿¡ª", (long)gold); -#else - msg_print("Your purse feels lighter."); - msg_format("%ld coins were stolen!", (long)gold); -#endif + msg_print(_("財布が軽くなった気がする。", "Your purse feels lighter.")); + msg_format(_("$%ld のお金が盗まれた!", "%ld coins were stolen!"), (long)gold); chg_virtue(V_SACRIFICE, 1); } else { -#ifdef JP - msg_print("ºâÉÛ¤¬·Ú¤¯¤Ê¤Ã¤¿µ¤¤¬¤¹¤ë¡£"); - msg_print("¤ª¶â¤¬Á´ÉôÅð¤Þ¤ì¤¿¡ª"); -#else - msg_print("Your purse feels lighter."); - msg_print("All of your coins were stolen!"); -#endif - + msg_print(_("財布が軽くなった気がする。", "Your purse feels lighter.")); + msg_print(_("お金が全部盗まれた!", "All of your coins were stolen!")); chg_virtue(V_SACRIFICE, 2); } /* Redraw gold */ p_ptr->redraw |= (PR_GOLD); - /* Window stuff */ p_ptr->window |= (PW_PLAYER); /* Blink away */ @@ -950,9 +2169,9 @@ bool make_attack_normal(int m_idx) get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); /* Confused monsters cannot steal successfully. -LM-*/ - if (m_ptr->confused) break; + if (MON_CONFUSED(m_ptr)) break; - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; /* Saving throw (unless paralyzed) based on dex and level */ if (!p_ptr->paralyzed && @@ -960,20 +2179,13 @@ bool make_attack_normal(int m_idx) p_ptr->lev))) { /* Saving throw message */ -#ifdef JP - msg_print("¤·¤«¤·¤¢¤ï¤Æ¤Æ¥¶¥Ã¥¯¤ò¼è¤êÊÖ¤·¤¿¡ª"); -#else - msg_print("You grab hold of your backpack!"); -#endif - + msg_print(_("しかしあわててザックを取り返した!", "You grab hold of your backpack!")); /* Occasional "blink" anyway */ blinked = TRUE; - /* Obvious */ obvious = TRUE; - /* Done */ break; } @@ -983,7 +2195,7 @@ bool make_attack_normal(int m_idx) s16b o_idx; /* Pick an item */ - i = randint0(INVEN_PACK); + i = (INVENTORY_IDX)randint0(INVEN_PACK); /* Obtain the item */ o_ptr = &inventory[i]; @@ -992,16 +2204,15 @@ bool make_attack_normal(int m_idx) if (!o_ptr->k_idx) continue; /* Skip artifacts */ - if (artifact_p(o_ptr) || o_ptr->art_name) continue; + if (object_is_artifact(o_ptr)) continue; /* Get a description */ - object_desc(o_name, o_ptr, FALSE, 3); + object_desc(o_name, o_ptr, OD_OMIT_PREFIX); - /* Message */ #ifdef JP - msg_format("%s(%c)¤ò%sÅð¤Þ¤ì¤¿¡ª", + msg_format("%s(%c)を%s盗まれた!", o_name, index_to_label(i), - ((o_ptr->number > 1) ? "°ì¤Ä" : "")); + ((o_ptr->number > 1) ? "一つ" : "")); #else msg_format("%sour %s (%c) was stolen!", ((o_ptr->number > 1) ? "One of y" : "Y"), @@ -1039,7 +2250,7 @@ bool make_attack_normal(int m_idx) } /* Forget mark */ - j_ptr->marked = 0; + j_ptr->marked = OM_TOUCHED; /* Memorize monster */ j_ptr->held_m_idx = m_idx; @@ -1055,13 +2266,11 @@ bool make_attack_normal(int m_idx) inven_item_increase(i, -1); inven_item_optimize(i); - /* Obvious */ obvious = TRUE; /* Blink away */ blinked = TRUE; - /* Done */ break; } @@ -1073,15 +2282,14 @@ bool make_attack_normal(int m_idx) /* Take some damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; /* Steal some food */ for (k = 0; k < 10; k++) { /* Pick an item from the pack */ - i = randint0(INVEN_PACK); + i = (INVENTORY_IDX)randint0(INVEN_PACK); - /* Get the item */ o_ptr = &inventory[i]; /* Skip non-objects */ @@ -1091,28 +2299,20 @@ bool make_attack_normal(int m_idx) if ((o_ptr->tval != TV_FOOD) && !((o_ptr->tval == TV_CORPSE) && (o_ptr->sval))) continue; /* Get a description */ - object_desc(o_name, o_ptr, FALSE, 0); + object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY)); - /* Message */ #ifdef JP - msg_format("%s(%c)¤ò%s¿©¤Ù¤é¤ì¤Æ¤·¤Þ¤Ã¤¿¡ª", - o_name, index_to_label(i), - ((o_ptr->number > 1) ? "°ì¤Ä" : "")); + msg_format("%s(%c)を%s食べられてしまった!", o_name, index_to_label(i), ((o_ptr->number > 1) ? "一つ" : "")); #else - msg_format("%sour %s (%c) was eaten!", - ((o_ptr->number > 1) ? "One of y" : "Y"), - o_name, index_to_label(i)); + msg_format("%sour %s (%c) was eaten!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i)); #endif - /* Steal the items */ inven_item_increase(i, -1); inven_item_optimize(i); - /* Obvious */ obvious = TRUE; - /* Done */ break; } @@ -1127,28 +2327,21 @@ bool make_attack_normal(int m_idx) /* Take some damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; /* Drain fuel */ - if ((o_ptr->xtra4 > 0) && (!artifact_p(o_ptr))) + if ((o_ptr->xtra4 > 0) && (!object_is_fixed_artifact(o_ptr))) { /* Reduce fuel */ - o_ptr->xtra4 -= (250 + randint1(250)); + o_ptr->xtra4 -= (s16b)(250 + randint1(250)); if (o_ptr->xtra4 < 1) o_ptr->xtra4 = 1; - /* Notice */ if (!p_ptr->blind) { -#ifdef JP - msg_print("ÌÀ¤«¤ê¤¬°Å¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿¡£"); -#else - msg_print("Your light dims."); -#endif - + msg_print(_("明かりが暗くなってしまった。", "Your light dims.")); obvious = TRUE; } - /* Window stuff */ p_ptr->window |= (PW_EQUIP); } @@ -1158,19 +2351,12 @@ bool make_attack_normal(int m_idx) case RBE_ACID: { if (explode) break; - /* Obvious */ obvious = TRUE; - /* Message */ -#ifdef JP - msg_print("»À¤òÍá¤Ó¤»¤é¤ì¤¿¡ª"); -#else - msg_print("You are covered in acid!"); -#endif - + msg_print(_("酸を浴びせられた!", "You are covered in acid!")); /* Special damage */ - get_damage += acid_dam(damage, ddesc, -1); + get_damage += acid_dam(damage, ddesc, -1, FALSE); /* Hack -- Update AC */ update_stuff(); @@ -1184,19 +2370,12 @@ bool make_attack_normal(int m_idx) case RBE_ELEC: { if (explode) break; - /* Obvious */ obvious = TRUE; - /* Message */ -#ifdef JP - msg_print("ÅÅ·â¤òÍá¤Ó¤»¤é¤ì¤¿¡ª"); -#else - msg_print("You are struck by electricity!"); -#endif - + msg_print(_("電撃を浴びせられた!", "You are struck by electricity!")); /* Special damage */ - get_damage += elec_dam(damage, ddesc, -1); + get_damage += elec_dam(damage, ddesc, -1, FALSE); /* Learn about the player */ update_smart_learn(m_idx, DRS_ELEC); @@ -1207,19 +2386,12 @@ bool make_attack_normal(int m_idx) case RBE_FIRE: { if (explode) break; - /* Obvious */ obvious = TRUE; - /* Message */ -#ifdef JP - msg_print("Á´¿È¤¬±ê¤ËÊñ¤Þ¤ì¤¿¡ª"); -#else - msg_print("You are enveloped in flames!"); -#endif - + msg_print(_("全身が炎に包まれた!", "You are enveloped in flames!")); /* Special damage */ - get_damage += fire_dam(damage, ddesc, -1); + get_damage += fire_dam(damage, ddesc, -1, FALSE); /* Learn about the player */ update_smart_learn(m_idx, DRS_FIRE); @@ -1230,19 +2402,12 @@ bool make_attack_normal(int m_idx) case RBE_COLD: { if (explode) break; - /* Obvious */ obvious = TRUE; - /* Message */ -#ifdef JP - msg_print("Á´¿È¤¬Î䵤¤Çʤ¤ï¤ì¤¿¡ª"); -#else - msg_print("You are covered with frost!"); -#endif - + msg_print(_("全身が冷気で覆われた!", "You are covered with frost!")); /* Special damage */ - get_damage += cold_dam(damage, ddesc, -1); + get_damage += cold_dam(damage, ddesc, -1, FALSE); /* Learn about the player */ update_smart_learn(m_idx, DRS_COLD); @@ -1252,18 +2417,17 @@ bool make_attack_normal(int m_idx) case RBE_BLIND: { - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); if (p_ptr->is_dead) break; /* Increase "blind" */ - if (!p_ptr->resist_blind) + if (!p_ptr->resist_blind && !CHECK_MULTISHADOW()) { if (set_blind(p_ptr->blind + 10 + randint1(rlev))) { #ifdef JP - if(m_ptr->r_idx == MON_DIO) msg_print("¤É¤¦¤À¥Ã¡ª¤³¤Î·ì¤ÎÌÜÄÙ¤·¤Ï¥Ã¡ª"); + if (m_ptr->r_idx == MON_DIO) msg_print("どうだッ!この血の目潰しはッ!"); #else /* nanka */ #endif @@ -1280,13 +2444,12 @@ bool make_attack_normal(int m_idx) case RBE_CONFUSE: { if (explode) break; - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); if (p_ptr->is_dead) break; /* Increase "confused" */ - if (!p_ptr->resist_conf) + if (!p_ptr->resist_conf && !CHECK_MULTISHADOW()) { if (set_confused(p_ptr->confused + 3 + randint1(rlev))) { @@ -1302,30 +2465,23 @@ bool make_attack_normal(int m_idx) case RBE_TERRIFY: { - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); if (p_ptr->is_dead) break; /* Increase "afraid" */ - if (p_ptr->resist_fear) + if (CHECK_MULTISHADOW()) { -#ifdef JP - msg_print("¤·¤«¤·¶²Éݤ˿¯¤µ¤ì¤Ê¤«¤Ã¤¿¡ª"); -#else - msg_print("You stand your ground!"); -#endif - + /* Do nothing */ + } + else if (p_ptr->resist_fear) + { + msg_print(_("しかし恐怖に侵されなかった!", "You stand your ground!")); obvious = TRUE; } else if (randint0(100 + r_ptr->level/2) < p_ptr->skill_sav) { -#ifdef JP - msg_print("¤·¤«¤·¶²Éݤ˿¯¤µ¤ì¤Ê¤«¤Ã¤¿¡ª"); -#else - msg_print("You stand your ground!"); -#endif - + msg_print(_("しかし恐怖に侵されなかった!", "You stand your ground!")); obvious = TRUE; } else @@ -1344,30 +2500,23 @@ bool make_attack_normal(int m_idx) case RBE_PARALYZE: { - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); if (p_ptr->is_dead) break; /* Increase "paralyzed" */ - if (p_ptr->free_act) + if (CHECK_MULTISHADOW()) { -#ifdef JP - msg_print("¤·¤«¤·¸ú²Ì¤¬¤Ê¤«¤Ã¤¿¡ª"); -#else - msg_print("You are unaffected!"); -#endif - + /* Do nothing */ + } + else if (p_ptr->free_act) + { + msg_print(_("しかし効果がなかった!", "You are unaffected!")); obvious = TRUE; } else if (randint0(100 + r_ptr->level/2) < p_ptr->skill_sav) { -#ifdef JP - msg_print("¤·¤«¤·¸úÎϤòÄ·¤ÍÊÖ¤·¤¿¡ª"); -#else - msg_print("You resist the effects!"); -#endif - + msg_print(_("しかし効力を跳ね返した!", "You resist the effects!")); obvious = TRUE; } else @@ -1389,12 +2538,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_STR: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; - - /* Damage (stat) */ + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; if (do_dec_stat(A_STR)) obvious = TRUE; break; @@ -1402,12 +2548,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_INT: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; - - /* Damage (stat) */ + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; if (do_dec_stat(A_INT)) obvious = TRUE; break; @@ -1415,12 +2558,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_WIS: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; - - /* Damage (stat) */ + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; if (do_dec_stat(A_WIS)) obvious = TRUE; break; @@ -1428,12 +2568,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_DEX: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; - - /* Damage (stat) */ + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; if (do_dec_stat(A_DEX)) obvious = TRUE; break; @@ -1441,12 +2578,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_CON: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; - - /* Damage (stat) */ + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; if (do_dec_stat(A_CON)) obvious = TRUE; break; @@ -1454,12 +2588,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_CHR: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; - - /* Damage (stat) */ + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; if (do_dec_stat(A_CHR)) obvious = TRUE; break; @@ -1467,10 +2598,9 @@ bool make_attack_normal(int m_idx) case RBE_LOSE_ALL: { - /* Damage (physical) */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; /* Damage (stats) */ if (do_dec_stat(A_STR)) obvious = TRUE; @@ -1485,19 +2615,17 @@ bool make_attack_normal(int m_idx) case RBE_SHATTER: { - /* Obvious */ obvious = TRUE; /* Hack -- Reduce damage based on the player armor class */ damage -= (damage * ((ac < 150) ? ac : 150) / 250); - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); /* Radius 8 earthquake centered at the monster */ if (damage > 23 || explode) { - earthquake(m_ptr->fy, m_ptr->fx, 8); + earthquake_aux(m_ptr->fy, m_ptr->fx, 8, m_idx); } break; @@ -1507,13 +2635,11 @@ bool make_attack_normal(int m_idx) { s32b d = damroll(10, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - /* Obvious */ obvious = TRUE; - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; (void)drain_exp(d, d / 10, 95); break; @@ -1523,13 +2649,11 @@ bool make_attack_normal(int m_idx) { s32b d = damroll(20, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - /* Obvious */ obvious = TRUE; - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; (void)drain_exp(d, d / 10, 90); break; @@ -1539,13 +2663,11 @@ bool make_attack_normal(int m_idx) { s32b d = damroll(40, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - /* Obvious */ obvious = TRUE; - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; (void)drain_exp(d, d / 10, 75); break; @@ -1555,13 +2677,11 @@ bool make_attack_normal(int m_idx) { s32b d = damroll(80, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; - /* Obvious */ obvious = TRUE; - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; (void)drain_exp(d, d / 10, 50); break; @@ -1572,7 +2692,7 @@ bool make_attack_normal(int m_idx) /* Take some damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; /* Take "poison" effect */ if (!(p_ptr->resist_pois || IS_OPPOSE_POIS())) @@ -1590,12 +2710,7 @@ bool make_attack_normal(int m_idx) bool perm = one_in_(10); if (dec_stat(A_CON, randint1(10), perm)) { -#ifdef JP - msg_print("ɤ¬¤¢¤Ê¤¿¤ò¿ª¤ó¤Ç¤¤¤ëµ¤¤¬¤¹¤ë¡£"); -#else - msg_print("You feel strange sickness."); -#endif - + msg_print(_("病があなたを蝕んでいる気がする。", "You feel strange sickness.")); obvious = TRUE; } } @@ -1605,19 +2720,14 @@ bool make_attack_normal(int m_idx) case RBE_TIME: { if (explode) break; - if (!p_ptr->resist_time) + if (!p_ptr->resist_time && !CHECK_MULTISHADOW()) { switch (randint1(10)) { case 1: case 2: case 3: case 4: case 5: { if (p_ptr->prace == RACE_ANDROID) break; -#ifdef JP - msg_print("¿ÍÀ¸¤¬µÕÌá¤ê¤·¤¿µ¤¤¬¤¹¤ë¡£"); -#else - msg_print("You feel life has clocked back."); -#endif - + msg_print(_("人生が逆戻りした気がする。", "You feel life has clocked back.")); lose_exp(100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE); break; } @@ -1629,12 +2739,12 @@ bool make_attack_normal(int m_idx) switch (stat) { #ifdef JP - case A_STR: act = "¶¯¤¯"; break; - case A_INT: act = "ÁïÌÀ¤Ç"; break; - case A_WIS: act = "¸­ÌÀ¤Ç"; break; - case A_DEX: act = "´ïÍѤÇ"; break; - case A_CON: act = "·ò¹¯¤Ç"; break; - case A_CHR: act = "Èþ¤·¤¯"; break; + case A_STR: act = "強く"; break; + case A_INT: act = "聡明で"; break; + case A_WIS: act = "賢明で"; break; + case A_DEX: act = "器用で"; break; + case A_CON: act = "健康で"; break; + case A_CHR: act = "美しく"; break; #else case A_STR: act = "strong"; break; case A_INT: act = "bright"; break; @@ -1646,13 +2756,7 @@ bool make_attack_normal(int m_idx) } -#ifdef JP - msg_format("¤¢¤Ê¤¿¤Ï°ÊÁ°¤Û¤É%s¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿...¡£", act); -#else - msg_format("You're not as %s as you used to be...", act); -#endif - - + msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), act); p_ptr->stat_cur[stat] = (p_ptr->stat_cur[stat] * 3) / 4; if (p_ptr->stat_cur[stat] < 3) p_ptr->stat_cur[stat] = 3; p_ptr->update |= (PU_BONUS); @@ -1661,12 +2765,7 @@ bool make_attack_normal(int m_idx) case 10: { -#ifdef JP - msg_print("¤¢¤Ê¤¿¤Ï°ÊÁ°¤Û¤ÉÎ϶¯¤¯¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿...¡£"); -#else - msg_print("You're not as powerful as you used to be..."); -#endif - + msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be...")); for (k = 0; k < 6; k++) { @@ -1682,18 +2781,16 @@ bool make_attack_normal(int m_idx) break; } - case RBE_EXP_VAMP: + case RBE_DR_LIFE: { s32b d = damroll(60, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE; bool resist_drain; - /* Obvious */ obvious = TRUE; - /* Take damage */ get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); - if (p_ptr->is_dead) break; + if (p_ptr->is_dead || CHECK_MULTISHADOW()) break; resist_drain = !drain_exp(d, d / 10, 50); @@ -1736,12 +2833,7 @@ bool make_attack_normal(int m_idx) /* Special message */ if (m_ptr->ml && did_heal) { -#ifdef JP -msg_format("%s¤ÏÂÎÎϤò²óÉü¤·¤¿¤è¤¦¤À¡£", m_name); -#else - msg_format("%^s appears healthier.", m_name); -#endif - + msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name); } } @@ -1749,20 +2841,70 @@ msg_format("%s } case RBE_DR_MANA: { - /* Obvious */ obvious = TRUE; - do_cut = 0; + if (CHECK_MULTISHADOW()) + { + msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, you are unharmed!")); + } + else + { + do_cut = 0; + + p_ptr->csp -= damage; + if (p_ptr->csp < 0) + { + p_ptr->csp = 0; + p_ptr->csp_frac = 0; + } + + p_ptr->redraw |= (PR_MANA); + } + + /* Learn about the player */ + update_smart_learn(m_idx, DRS_MANA); - /* Take damage */ - p_ptr->csp -= damage; - if (p_ptr->csp < 0) + break; + } + case RBE_INERTIA: + { + get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); + + if (p_ptr->is_dead) break; + + /* Decrease speed */ + if (CHECK_MULTISHADOW()) + { + /* Do nothing */ + } + else { - p_ptr->csp = 0; - p_ptr->csp_frac = 0; + if (set_slow((p_ptr->slow + 4 + randint0(rlev / 10)), FALSE)) + { + obvious = TRUE; + } } - p_ptr->redraw |= (PR_MANA); + break; + } + case RBE_STUN: + { + get_damage += take_hit(DAMAGE_ATTACK, damage, ddesc, -1); + + if (p_ptr->is_dead) break; + + /* Decrease speed */ + if (p_ptr->resist_sound || CHECK_MULTISHADOW()) + { + /* Do nothing */ + } + else + { + if (set_stun(p_ptr->stun + 10 + randint1(r_ptr->level / 4))) + { + obvious = TRUE; + } + } break; } @@ -1787,7 +2929,7 @@ msg_format("%s /* Handle cut */ if (do_cut) { - int k = 0; + int cut_plus = 0; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage); @@ -1795,24 +2937,24 @@ msg_format("%s /* Roll for damage */ switch (tmp) { - case 0: k = 0; break; - case 1: k = randint1(5); break; - case 2: k = randint1(5) + 5; break; - case 3: k = randint1(20) + 20; break; - case 4: k = randint1(50) + 50; break; - case 5: k = randint1(100) + 100; break; - case 6: k = 300; break; - default: k = 500; break; + case 0: cut_plus = 0; break; + case 1: cut_plus = randint1(5); break; + case 2: cut_plus = randint1(5) + 5; break; + case 3: cut_plus = randint1(20) + 20; break; + case 4: cut_plus = randint1(50) + 50; break; + case 5: cut_plus = randint1(100) + 100; break; + case 6: cut_plus = 300; break; + default: cut_plus = 500; break; } /* Apply the cut */ - if (k) (void)set_cut(p_ptr->cut + k); + if (cut_plus) (void)set_cut(p_ptr->cut + cut_plus); } /* Handle stun */ if (do_stun) { - int k = 0; + int stun_plus = 0; /* Critical hit (zero if non-critical) */ tmp = monster_critical(d_dice, d_side, damage); @@ -1820,18 +2962,18 @@ msg_format("%s /* Roll for damage */ switch (tmp) { - case 0: k = 0; break; - case 1: k = randint1(5); break; - case 2: k = randint1(5) + 10; break; - case 3: k = randint1(10) + 20; break; - case 4: k = randint1(15) + 30; break; - case 5: k = randint1(20) + 40; break; - case 6: k = 80; break; - default: k = 150; break; + case 0: stun_plus = 0; break; + case 1: stun_plus = randint1(5); break; + case 2: stun_plus = randint1(5) + 10; break; + case 3: stun_plus = randint1(10) + 20; break; + case 4: stun_plus = randint1(15) + 30; break; + case 5: stun_plus = randint1(20) + 40; break; + case 6: stun_plus = 80; break; + default: stun_plus = 150; break; } /* Apply the stun */ - if (k) (void)set_stun(p_ptr->stun + k); + if (stun_plus) (void)set_stun(p_ptr->stun + stun_plus); } if (explode) @@ -1851,15 +2993,15 @@ msg_format("%s { if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)) { - int dam = damroll(2, 6); + HIT_POINT dam = damroll(2, 6); /* Modify the damage */ dam = mon_damage_mod(m_ptr, dam, FALSE); #ifdef JP - msg_format("%^s¤ÏÆÍÁ³Ç®¤¯¤Ê¤Ã¤¿¡ª", m_name); + msg_format("%^sは突然熱くなった!", m_name); if (mon_take_hit(m_idx, dam, &fear, - "¤Ï³¥¤Î»³¤Ë¤Ê¤Ã¤¿¡£")) + "は灰の山になった。")) #else msg_format("%^s is suddenly very hot!", m_name); @@ -1874,7 +3016,7 @@ msg_format("%s } else { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK); } } @@ -1883,15 +3025,15 @@ msg_format("%s { if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)) { - int dam = damroll(2, 6); + HIT_POINT dam = damroll(2, 6); /* Modify the damage */ dam = mon_damage_mod(m_ptr, dam, FALSE); #ifdef JP - msg_format("%^s¤ÏÅÅ·â¤ò¤¯¤é¤Ã¤¿¡ª", m_name); + msg_format("%^sは電撃をくらった!", m_name); if (mon_take_hit(m_idx, dam, &fear, - "¤Ïdz¤¨³Ì¤Î»³¤Ë¤Ê¤Ã¤¿¡£")) + "は燃え殻の山になった。")) #else msg_format("%^s gets zapped!", m_name); @@ -1906,7 +3048,7 @@ msg_format("%s } else { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK); } } @@ -1915,15 +3057,15 @@ msg_format("%s { if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)) { - int dam = damroll(2, 6); + HIT_POINT dam = damroll(2, 6); /* Modify the damage */ dam = mon_damage_mod(m_ptr, dam, FALSE); #ifdef JP - msg_format("%^s¤ÏÎ䵤¤ò¤¯¤é¤Ã¤¿¡ª", m_name); + msg_format("%^sは冷気をくらった!", m_name); if (mon_take_hit(m_idx, dam, &fear, - "¤ÏÅà¤ê¤Ä¤¤¤¿¡£")) + "は凍りついた。")) #else msg_format("%^s is very cold!", m_name); @@ -1938,7 +3080,7 @@ msg_format("%s } else { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK); } } @@ -1948,15 +3090,15 @@ msg_format("%s { if (!(r_ptr->flagsr & RFR_EFF_RES_SHAR_MASK)) { - int dam = damroll(2, 6); + HIT_POINT dam = damroll(2, 6); /* Modify the damage */ dam = mon_damage_mod(m_ptr, dam, FALSE); #ifdef JP - msg_format("%^s¤Ï¶À¤ÎÇËÊÒ¤ò¤¯¤é¤Ã¤¿¡ª", m_name); + msg_format("%^sは鏡の破片をくらった!", m_name); if (mon_take_hit(m_idx, dam, &fear, - "¤Ï¥º¥¿¥º¥¿¤Ë¤Ê¤Ã¤¿¡£")) + "はズタズタになった。")) #else msg_format("%^s gets zapped!", m_name); @@ -1970,12 +3112,13 @@ msg_format("%s } else { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_RES_SHAR_MASK); } - if (is_mirror_grid(&cave[py][px])) { - teleport_player(10); + if (is_mirror_grid(&cave[p_ptr->y][p_ptr->x])) + { + teleport_player(10, 0L); } } @@ -1985,15 +3128,15 @@ msg_format("%s { if (!(r_ptr->flagsr & RFR_RES_ALL)) { - int dam = damroll(2, 6); + HIT_POINT dam = damroll(2, 6); /* Modify the damage */ dam = mon_damage_mod(m_ptr, dam, FALSE); #ifdef JP - msg_format("%^s¤ÏÀ»¤Ê¤ë¥ª¡¼¥é¤Ç½ý¤Ä¤¤¤¿¡ª", m_name); + msg_format("%^sは聖なるオーラで傷ついた!", m_name); if (mon_take_hit(m_idx, dam, &fear, - "¤ÏÅݤ줿¡£")) + "は倒れた。")) #else msg_format("%^s is injured by holy power!", m_name); @@ -2004,12 +3147,12 @@ msg_format("%s blinked = FALSE; alive = FALSE; } - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= RF3_EVIL; } else { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_ALL; } } @@ -2019,15 +3162,15 @@ msg_format("%s { if (!(r_ptr->flagsr & RFR_RES_ALL)) { - int dam = damroll(2, 6); + HIT_POINT dam = damroll(2, 6); /* Modify the damage */ dam = mon_damage_mod(m_ptr, dam, FALSE); #ifdef JP - msg_format("%^s¤¬±Ô¤¤Æ®µ¤¤Î¥ª¡¼¥é¤Ç½ý¤Ä¤¤¤¿¡ª", m_name); + msg_format("%^sが鋭い闘気のオーラで傷ついた!", m_name); if (mon_take_hit(m_idx, dam, &fear, - "¤ÏÅݤ줿¡£")) + "は倒れた。")) #else msg_format("%^s is injured by the Force", m_name); @@ -2042,10 +3185,69 @@ msg_format("%s } else { - if (m_ptr->ml) + if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_ALL; } } + + if (hex_spelling(HEX_SHADOW_CLOAK) && alive && !p_ptr->is_dead) + { + HIT_POINT dam = 1; + object_type *o_armed_ptr = &inventory[INVEN_RARM]; + + if (!(r_ptr->flagsr & RFR_RES_ALL || r_ptr->flagsr & RFR_RES_DARK)) + { + if (o_armed_ptr->k_idx) + { + int basedam = ((o_armed_ptr->dd + p_ptr->to_dd[0]) * (o_armed_ptr->ds + p_ptr->to_ds[0] + 1)); + dam = basedam / 2 + o_armed_ptr->to_d + p_ptr->to_d[0]; + } + + /* Cursed armor makes damages doubled */ + o_armed_ptr = &inventory[INVEN_BODY]; + if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr)) dam *= 2; + + /* Modify the damage */ + dam = mon_damage_mod(m_ptr, dam, FALSE); + +#ifdef JP + msg_format("影のオーラが%^sに反撃した!", m_name); + if (mon_take_hit(m_idx, dam, &fear, "は倒れた。")) +#else + msg_format("Enveloped shadows attack %^s.", m_name); + + if (mon_take_hit(m_idx, dam, &fear, " is destroyed.")) +#endif + { + blinked = FALSE; + alive = FALSE; + } + else /* monster does not dead */ + { + int j; + BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL; + EFFECT_ID typ[4][2] = { + { INVEN_HEAD, GF_OLD_CONF }, + { INVEN_LARM, GF_OLD_SLEEP }, + { INVEN_HANDS, GF_TURN_ALL }, + { INVEN_FEET, GF_OLD_SLOW } + }; + + /* Some cursed armours gives an extra effect */ + for (j = 0; j < 4; j++) + { + o_armed_ptr = &inventory[typ[j][0]]; + if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr) && object_is_armour(o_armed_ptr)) + project(0, 0, m_ptr->fy, m_ptr->fx, (p_ptr->lev * 2), typ[j][1], flg, -1); + } + } + } + else + { + if (is_original_ap_and_seen(m_ptr)) + r_ptr->r_flagsr |= (RFR_RES_ALL | RFR_RES_DARK); + } + } } } @@ -2072,15 +3274,14 @@ msg_format("%s if (m_ptr->ml) { /* Disturbing */ - disturb(1, 0); + disturb(TRUE, TRUE); - /* Message */ #ifdef JP if (abbreviate) - msg_format("%s¤«¤ï¤·¤¿¡£", (p_ptr->special_attack & ATTACK_SUIKEN) ? "´ñ̯¤ÊÆ°¤­¤Ç" : ""); + msg_format("%sかわした。", (p_ptr->special_attack & ATTACK_SUIKEN) ? "奇妙な動きで" : ""); else - msg_format("%s%^s¤Î¹¶·â¤ò¤«¤ï¤·¤¿¡£", (p_ptr->special_attack & ATTACK_SUIKEN) ? "´ñ̯¤ÊÆ°¤­¤Ç" : "", m_name); - abbreviate = 1;/*£²²óÌܰʹߤϾÊά */ + msg_format("%s%^sの攻撃をかわした。", (p_ptr->special_attack & ATTACK_SUIKEN) ? "奇妙な動きで" : "", m_name); + abbreviate = 1;/*2回目以降は省略 */ #else msg_format("%^s misses you.", m_name); #endif @@ -2094,7 +3295,7 @@ msg_format("%s /* Analyze "visible" monsters only */ - if (visible && !do_silly_attack) + if (is_original_ap_and_seen(m_ptr) && !do_silly_attack) { /* Count "obvious" attacks (and ones that cause damage) */ if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) @@ -2109,28 +3310,28 @@ msg_format("%s if (p_ptr->riding && damage) { - char m_name[80]; - monster_desc(m_name, &m_list[p_ptr->riding], 0); + char m_steed_name[80]; + monster_desc(m_steed_name, &m_list[p_ptr->riding], 0); if (rakuba((damage > 200) ? 200 : damage, FALSE)) { -#ifdef JP -msg_format("%^s¤«¤éÍî¤Á¤Æ¤·¤Þ¤Ã¤¿¡ª", m_name); -#else - msg_format("You have fallen from %s.", m_name); -#endif + msg_format(_("%^sから落ちてしまった!", "You have fallen from %s."), m_steed_name); } } + if (p_ptr->special_defense & NINJA_KAWARIMI) { - kawarimi(FALSE); - return TRUE; + if (kawarimi(FALSE)) return TRUE; } } - if (p_ptr->tim_eyeeye && get_damage > 0 && !p_ptr->is_dead) + /* Hex - revenge damage stored */ + revenge_store(get_damage); + + if ((p_ptr->tim_eyeeye || hex_spelling(HEX_EYE_FOR_EYE)) + && get_damage > 0 && !p_ptr->is_dead) { #ifdef JP - msg_format("¹¶·â¤¬%s¼«¿È¤ò½ý¤Ä¤±¤¿¡ª", m_name); + msg_format("攻撃が%s自身を傷つけた!", m_name); #else char m_name_self[80]; @@ -2140,35 +3341,35 @@ msg_format("%^s msg_format("The attack of %s has wounded %s!", m_name, m_name_self); #endif project(0, 0, m_ptr->fy, m_ptr->fx, get_damage, GF_MISSILE, PROJECT_KILL, -1); - set_tim_eyeeye(p_ptr->tim_eyeeye-5, TRUE); + if (p_ptr->tim_eyeeye) set_tim_eyeeye(p_ptr->tim_eyeeye-5, TRUE); } - if ((p_ptr->counter || (p_ptr->special_defense & KATA_MUSOU)) && alive && !p_ptr->is_dead && m_ptr->ml && (p_ptr->csp > 7)) { - char m_name[80]; - monster_desc(m_name, m_ptr, 0); + char m_target_name[80]; + monster_desc(m_target_name, m_ptr, 0); p_ptr->csp -= 7; -#ifdef JP - msg_format("%^s¤ËÈ¿·â¤·¤¿¡ª", m_name); -#else - msg_format("Your counterattack to %s!", m_name); -#endif + msg_format(_("%^sに反撃した!", "Your counterattack to %s!"), m_target_name); py_attack(m_ptr->fy, m_ptr->fx, HISSATSU_COUNTER); fear = FALSE; + + /* Redraw mana */ + p_ptr->redraw |= (PR_MANA); } /* Blink away */ if (blinked && alive && !p_ptr->is_dead) { -#ifdef JP - msg_print("Å¥ËÀ¤Ï¾Ð¤Ã¤Æƨ¤²¤¿¡ª"); -#else - msg_print("The thief flees laughing!"); -#endif - - teleport_away(m_idx, MAX_SIGHT * 2 + 5, FALSE); + if (teleport_barrier(m_idx)) + { + msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But magic barrier obstructs it.")); + } + else + { + msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!")); + teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L); + } } @@ -2181,12 +3382,7 @@ msg_format("%^s if (m_ptr->ml && fear && alive && !p_ptr->is_dead) { sound(SOUND_FLEE); -#ifdef JP - msg_format("%^s¤Ï¶²ÉݤÇƨ¤²½Ð¤·¤¿¡ª", m_name); -#else - msg_format("%^s flees in terror!", m_name); -#endif - + msg_format(_("%^sは恐怖で逃げ出した!", "%^s flees in terror!"), m_name); } if (p_ptr->special_defense & KATA_IAI)