From d5624ec6fee6e7b477a52de809506e0b84666645 Mon Sep 17 00:00:00 2001 From: Deskull Date: Mon, 10 Sep 2018 19:51:29 +0900 Subject: [PATCH] =?utf8?q?[Refactor]=20#37353=E3=80=80=E3=83=88=E3=83=A9?= =?utf8?q?=E3=83=83=E3=83=97=E5=87=A6=E7=90=86=E3=82=92=20cmd1.c=20?= =?utf8?q?=E3=81=8B=E3=82=89=20trap.c/h=20=E3=81=B8=E5=88=86=E9=9B=A2?= =?utf8?q?=E3=80=82=20Separate=20player's=20summoning=20from=20cmd1.c=20to?= =?utf8?q?=20trap.c/h.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Hengband_vcs2015/Hengband/Hengband.vcxproj | 2 + Hengband_vcs2015/Hengband/Hengband.vcxproj.filters | 6 + src/cmd1.c | 449 +-------------------- src/trap.c | 449 +++++++++++++++++++++ src/trap.h | 2 + 5 files changed, 460 insertions(+), 448 deletions(-) create mode 100644 src/trap.c create mode 100644 src/trap.h diff --git a/Hengband_vcs2015/Hengband/Hengband.vcxproj b/Hengband_vcs2015/Hengband/Hengband.vcxproj index d55461a3e..400caf1d4 100644 --- a/Hengband_vcs2015/Hengband/Hengband.vcxproj +++ b/Hengband_vcs2015/Hengband/Hengband.vcxproj @@ -205,6 +205,7 @@ + @@ -244,6 +245,7 @@ + diff --git a/Hengband_vcs2015/Hengband/Hengband.vcxproj.filters b/Hengband_vcs2015/Hengband/Hengband.vcxproj.filters index a8b2b0c36..5cda13382 100644 --- a/Hengband_vcs2015/Hengband/Hengband.vcxproj.filters +++ b/Hengband_vcs2015/Hengband/Hengband.vcxproj.filters @@ -241,6 +241,9 @@ Source + + Source + @@ -349,6 +352,9 @@ Header + + Header + diff --git a/src/cmd1.c b/src/cmd1.c index 82bbf4203..f6a6fdb93 100644 --- a/src/cmd1.c +++ b/src/cmd1.c @@ -141,6 +141,7 @@ #include "angband.h" +#include "trap.h" /*! @@ -906,454 +907,6 @@ void carry(bool pickup) } -/*! - * @brief プレイヤーへのトラップ命中判定 / - * Determine if a trap affects the player. - * @param power 基本回避難度 - * @return トラップが命中した場合TRUEを返す。 - * @details - * Always miss 5% of the time, Always hit 5% of the time. - * Otherwise, match trap power against player armor. - */ -static int check_hit(int power) -{ - int k, ac; - - /* Percentile dice */ - k = randint0(100); - - /* Hack -- 5% hit, 5% miss */ - if (k < 10) return (k < 5); - - if (p_ptr->pseikaku == SEIKAKU_NAMAKE) - if (one_in_(20)) return (TRUE); - - /* Paranoia -- No power */ - if (power <= 0) return (FALSE); - - /* Total armor */ - ac = p_ptr->ac + p_ptr->to_a; - - /* Power competes against Armor */ - if (randint1(power) > ((ac * 3) / 4)) return (TRUE); - - /* Assume miss */ - return (FALSE); -} - - -/*! - * @brief 落とし穴系トラップの判定とプレイヤーの被害処理 - * @param trap_feat_type トラップの種別ID - * @return なし - */ -static void hit_trap_pit(int trap_feat_type) -{ - HIT_POINT dam; - cptr trap_name = ""; - cptr spike_name = ""; - - switch (trap_feat_type) - { - case TRAP_PIT: - trap_name = _("落とし穴", "a pit trap"); - break; - case TRAP_SPIKED_PIT: - trap_name = _("スパイクが敷かれた落とし穴", "a spiked pit"); - spike_name = _("スパイク", "spikes"); - break; - case TRAP_POISON_PIT: - trap_name = _("スパイクが敷かれた落とし穴", "a spiked pit"); - spike_name = _("毒を塗られたスパイク", "poisonous spikes"); - break; - default: - return; - } - - if (p_ptr->levitation) - { - msg_format(_("%sを飛び越えた。", "You fly over %s."), trap_name); - return; - } - - msg_format(_("%sに落ちてしまった!", "You have fallen into %s!"), trap_name); - - /* Base damage */ - dam = damroll(2, 6); - - /* Extra spike damage */ - if ((trap_feat_type == TRAP_SPIKED_PIT || trap_feat_type == TRAP_POISON_PIT) && - one_in_(2)) - { - msg_format(_("%sが刺さった!", "You are impaled on %s!"), spike_name); - - dam = dam * 2; - (void)set_cut(p_ptr->cut + randint1(dam)); - - if (trap_feat_type == TRAP_POISON_PIT) { - if (p_ptr->resist_pois || IS_OPPOSE_POIS()) - { - msg_print(_("しかし毒の影響はなかった!", "The poison does not affect you!")); - } - else - { - dam = dam * 2; - (void)set_poisoned(p_ptr->poisoned + randint1(dam)); - } - } - } - - /* Take the damage */ - take_hit(DAMAGE_NOESCAPE, dam, trap_name, -1); -} - -/*! - * @brief ダーツ系トラップ(通常ダメージ)の判定とプレイヤーの被害処理 - * @return ダーツが命中した場合TRUEを返す - */ -static bool hit_trap_dart(void) -{ - bool hit = FALSE; - - if (check_hit(125)) - { - msg_print(_("小さなダーツが飛んできて刺さった!", "A small dart hits you!")); - - take_hit(DAMAGE_ATTACK, damroll(1, 4), _("ダーツの罠", "a dart trap"), -1); - - if (!CHECK_MULTISHADOW()) hit = TRUE; - } - else - { - msg_print(_("小さなダーツが飛んできた!が、運良く当たらなかった。", "A small dart barely misses you.")); - } - - return hit; -} - -/*! - * @brief ダーツ系トラップ(通常ダメージ+能力値減少)の判定とプレイヤーの被害処理 - * @param stat 低下する能力値ID - * @return なし - */ -static void hit_trap_lose_stat(int stat) -{ - if (hit_trap_dart()) - { - do_dec_stat(stat); - } -} - -/*! - * @brief ダーツ系トラップ(通常ダメージ+減速)の判定とプレイヤーの被害処理 - * @return なし - */ -static void hit_trap_slow(void) -{ - if (hit_trap_dart()) - { - set_slow(p_ptr->slow + randint0(20) + 20, FALSE); - } -} - -/*! - * @brief ダーツ系トラップ(通常ダメージ+状態異常)の判定とプレイヤーの被害処理 - * @param trap_message メッセージの補完文字列 - * @param resist 状態異常に抵抗する判定が出たならTRUE - * @param set_status 状態異常を指定する関数ポインタ - * @param turn 状態異常の追加ターン量 - * @return なし - */ -static void hit_trap_set_abnormal_status(cptr trap_message, bool resist, bool (*set_status)(IDX), IDX turn_aux) -{ - msg_print(trap_message); - - if (!resist) - { - set_status(turn_aux); - } -} - -/*! - * @brief プレイヤーへのトラップ作動処理メインルーチン / - * Handle player hitting a real trap - * @param break_trap 作動後のトラップ破壊が確定しているならばTRUE - * @return なし - */ -static void hit_trap(bool break_trap) -{ - int i, num, dam; - int x = p_ptr->x, y = p_ptr->y; - - /* Get the cave grid */ - cave_type *c_ptr = &cave[y][x]; - feature_type *f_ptr = &f_info[c_ptr->feat]; - int trap_feat_type = have_flag(f_ptr->flags, FF_TRAP) ? f_ptr->subtype : NOT_TRAP; - cptr name = _("トラップ", "a trap"); - - /* Disturb the player */ - disturb(0, 1); - - cave_alter_feat(y, x, FF_HIT_TRAP); - - /* Analyze XXX XXX XXX */ - switch (trap_feat_type) - { - case TRAP_TRAPDOOR: - { - if (p_ptr->levitation) - { - msg_print(_("落とし戸を飛び越えた。", "You fly over a trap door.")); - } - else - { - msg_print(_("落とし戸に落ちた!", "You have fallen through a trap door!")); - if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print(_("くっそ~!", "")); - - sound(SOUND_FALL); - dam = damroll(2, 8); - name = _("落とし戸", "a trap door"); - - take_hit(DAMAGE_NOESCAPE, dam, name, -1); - - /* Still alive and autosave enabled */ - if (autosave_l && (p_ptr->chp >= 0)) - do_cmd_save_game(TRUE); - - do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("落とし戸に落ちた", "You have fallen through a trap door!")); - prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT); - - /* Leaving */ - p_ptr->leaving = TRUE; - } - break; - } - - case TRAP_PIT: - case TRAP_SPIKED_PIT: - case TRAP_POISON_PIT: - { - hit_trap_pit(trap_feat_type); - break; - } - - case TRAP_TY_CURSE: - { - msg_print(_("何かがピカッと光った!", "There is a flash of shimmering light!")); - num = 2 + randint1(3); - for (i = 0; i < num; i++) - { - (void)summon_specific(0, y, x, dun_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); - } - - if (dun_level > randint1(100)) /* No nasty effect for low levels */ - { - bool stop_ty = FALSE; - int count = 0; - - do - { - stop_ty = activate_ty_curse(stop_ty, &count); - } - while (one_in_(6)); - } - break; - } - - case TRAP_TELEPORT: - { - msg_print(_("テレポート・トラップにひっかかった!", "You hit a teleport trap!")); - teleport_player(100, TELEPORT_PASSIVE); - break; - } - - case TRAP_FIRE: - { - msg_print(_("炎に包まれた!", "You are enveloped in flames!")); - dam = damroll(4, 6); - (void)fire_dam(dam, _("炎のトラップ", "a fire trap"), -1, FALSE); - break; - } - - case TRAP_ACID: - { - msg_print(_("酸が吹きかけられた!", "You are splashed with acid!")); - dam = damroll(4, 6); - (void)acid_dam(dam, _("酸のトラップ", "an acid trap"), -1, FALSE); - break; - } - - case TRAP_SLOW: - { - hit_trap_slow(); - break; - } - - case TRAP_LOSE_STR: - { - hit_trap_lose_stat(A_STR); - break; - } - - case TRAP_LOSE_DEX: - { - hit_trap_lose_stat(A_DEX); - break; - } - - case TRAP_LOSE_CON: - { - hit_trap_lose_stat(A_CON); - break; - } - - case TRAP_BLIND: - { - hit_trap_set_abnormal_status( - _("黒いガスに包み込まれた!", "A black gas surrounds you!"), - p_ptr->resist_blind, - set_blind, p_ptr->blind + (TIME_EFFECT)randint0(50) + 25); - break; - } - - case TRAP_CONFUSE: - { - hit_trap_set_abnormal_status( - _("きらめくガスに包み込まれた!", "A gas of scintillating colors surrounds you!"), - p_ptr->resist_conf, - set_confused, p_ptr->confused + (TIME_EFFECT)randint0(20) + 10); - break; - } - - case TRAP_POISON: - { - hit_trap_set_abnormal_status( - _("刺激的な緑色のガスに包み込まれた!", "A pungent green gas surrounds you!"), - p_ptr->resist_pois || IS_OPPOSE_POIS(), - set_poisoned, p_ptr->poisoned + (TIME_EFFECT)randint0(20) + 10); - break; - } - - case TRAP_SLEEP: - { - msg_print(_("奇妙な白い霧に包まれた!", "A strange white mist surrounds you!")); - if (!p_ptr->free_act) - { - msg_print(_("あなたは眠りに就いた。", "You fall asleep.")); - - if (ironman_nightmare) - { - msg_print(_("身の毛もよだつ光景が頭に浮かんだ。", "A horrible vision enters your mind.")); - - /* Have some nightmares */ - sanity_blast(NULL, FALSE); - - } - (void)set_paralyzed(p_ptr->paralyzed + randint0(10) + 5); - } - break; - } - - case TRAP_TRAPS: - { - msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!")); - /* Make some new traps */ - project(0, 1, y, x, 0, GF_MAKE_TRAP, PROJECT_HIDE | PROJECT_JUMP | PROJECT_GRID, -1); - - break; - } - - case TRAP_ALARM: - { - msg_print(_("けたたましい音が鳴り響いた!", "An alarm sounds!")); - - aggravate_monsters(0); - - break; - } - - case TRAP_OPEN: - { - msg_print(_("大音響と共にまわりの壁が崩れた!", "Suddenly, surrounding walls are opened!")); - (void)project(0, 3, y, x, 0, GF_DISINTEGRATE, PROJECT_GRID | PROJECT_HIDE, -1); - (void)project(0, 3, y, x - 4, 0, GF_DISINTEGRATE, PROJECT_GRID | PROJECT_HIDE, -1); - (void)project(0, 3, y, x + 4, 0, GF_DISINTEGRATE, PROJECT_GRID | PROJECT_HIDE, -1); - aggravate_monsters(0); - - break; - } - - case TRAP_ARMAGEDDON: - { - static int levs[10] = {0, 0, 20, 10, 5, 3, 2, 1, 1, 1}; - int evil_idx = 0, good_idx = 0; - - int lev; - msg_print(_("突然天界の戦争に巻き込まれた!", "Suddenly, you are surrounded by immotal beings!")); - - /* Summon Demons and Angels */ - for (lev = dun_level; lev >= 20; lev -= 1 + lev/16) - { - num = levs[MIN(lev/10, 9)]; - for (i = 0; i < num; i++) - { - int x1 = rand_spread(x, 7); - int y1 = rand_spread(y, 5); - - /* Skip illegal grids */ - if (!in_bounds(y1, x1)) continue; - - /* Require line of projection */ - if (!projectable(p_ptr->y, p_ptr->x, y1, x1)) continue; - - if (summon_specific(0, y1, x1, lev, SUMMON_ARMAGE_EVIL, (PM_NO_PET))) - evil_idx = hack_m_idx_ii; - - if (summon_specific(0, y1, x1, lev, SUMMON_ARMAGE_GOOD, (PM_NO_PET))) - { - good_idx = hack_m_idx_ii; - } - - /* Let them fight each other */ - if (evil_idx && good_idx) - { - monster_type *evil_ptr = &m_list[evil_idx]; - monster_type *good_ptr = &m_list[good_idx]; - evil_ptr->target_y = good_ptr->fy; - evil_ptr->target_x = good_ptr->fx; - good_ptr->target_y = evil_ptr->fy; - good_ptr->target_x = evil_ptr->fx; - } - } - } - break; - } - - case TRAP_PIRANHA: - { - msg_print(_("突然壁から水が溢れ出した!ピラニアがいる!", "Suddenly, the room is filled with water with piranhas!")); - - /* Water fills room */ - fire_ball_hide(GF_WATER_FLOW, 0, 1, 10); - - /* Summon Piranhas */ - num = 1 + dun_level/20; - for (i = 0; i < num; i++) - { - (void)summon_specific(0, y, x, dun_level, SUMMON_PIRANHAS, (PM_ALLOW_GROUP | PM_NO_PET)); - } - break; - } - } - - if (break_trap && is_trap(c_ptr->feat)) - { - cave_alter_feat(y, x, FF_DISARM); - msg_print(_("トラップを粉砕した。", "You destroyed the trap.")); - } -} - /*! * @brief 敵オーラによるプレイヤーのダメージ処理(補助) diff --git a/src/trap.c b/src/trap.c new file mode 100644 index 000000000..a8c13b4e0 --- /dev/null +++ b/src/trap.c @@ -0,0 +1,449 @@ +#include "angband.h" + + +/*! +* @brief ƒvƒŒƒCƒ„[‚ւ̃gƒ‰ƒbƒv–½’†”»’è / +* Determine if a trap affects the player. +* @param power Šî–{‰ñ”ð“ï“x +* @return ƒgƒ‰ƒbƒv‚ª–½’†‚µ‚½ê‡TRUE‚ð•Ô‚·B +* @details +* Always miss 5% of the time, Always hit 5% of the time. +* Otherwise, match trap power against player armor. +*/ +static int check_hit(int power) +{ + int k, ac; + + /* Percentile dice */ + k = randint0(100); + + /* Hack -- 5% hit, 5% miss */ + if (k < 10) return (k < 5); + + if (p_ptr->pseikaku == SEIKAKU_NAMAKE) + if (one_in_(20)) return (TRUE); + + /* Paranoia -- No power */ + if (power <= 0) return (FALSE); + + /* Total armor */ + ac = p_ptr->ac + p_ptr->to_a; + + /* Power competes against Armor */ + if (randint1(power) > ((ac * 3) / 4)) return (TRUE); + + /* Assume miss */ + return (FALSE); +} + + +/*! +* @brief —Ž‚Æ‚µŒŠŒnƒgƒ‰ƒbƒv‚Ì”»’è‚ƃvƒŒƒCƒ„[‚Ì”íŠQˆ— +* @param trap_feat_type ƒgƒ‰ƒbƒv‚ÌŽí•ÊID +* @return ‚È‚µ +*/ +static void hit_trap_pit(int trap_feat_type) +{ + HIT_POINT dam; + cptr trap_name = ""; + cptr spike_name = ""; + + switch (trap_feat_type) + { + case TRAP_PIT: + trap_name = _("—Ž‚Æ‚µŒŠ", "a pit trap"); + break; + case TRAP_SPIKED_PIT: + trap_name = _("ƒXƒpƒCƒN‚ª•~‚©‚ꂽ—Ž‚Æ‚µŒŠ", "a spiked pit"); + spike_name = _("ƒXƒpƒCƒN", "spikes"); + break; + case TRAP_POISON_PIT: + trap_name = _("ƒXƒpƒCƒN‚ª•~‚©‚ꂽ—Ž‚Æ‚µŒŠ", "a spiked pit"); + spike_name = _("“Å‚ð“h‚ç‚ꂽƒXƒpƒCƒN", "poisonous spikes"); + break; + default: + return; + } + + if (p_ptr->levitation) + { + msg_format(_("%s‚ð”ò‚щz‚¦‚½B", "You fly over %s."), trap_name); + return; + } + + msg_format(_("%s‚É—Ž‚¿‚Ä‚µ‚Ü‚Á‚½I", "You have fallen into %s!"), trap_name); + + /* Base damage */ + dam = damroll(2, 6); + + /* Extra spike damage */ + if ((trap_feat_type == TRAP_SPIKED_PIT || trap_feat_type == TRAP_POISON_PIT) && + one_in_(2)) + { + msg_format(_("%s‚ªŽh‚³‚Á‚½I", "You are impaled on %s!"), spike_name); + + dam = dam * 2; + (void)set_cut(p_ptr->cut + randint1(dam)); + + if (trap_feat_type == TRAP_POISON_PIT) { + if (p_ptr->resist_pois || IS_OPPOSE_POIS()) + { + msg_print(_("‚µ‚©‚µ“ł̉e‹¿‚Í‚È‚©‚Á‚½I", "The poison does not affect you!")); + } + else + { + dam = dam * 2; + (void)set_poisoned(p_ptr->poisoned + randint1(dam)); + } + } + } + + /* Take the damage */ + take_hit(DAMAGE_NOESCAPE, dam, trap_name, -1); +} + +/*! +* @brief ƒ_[ƒcŒnƒgƒ‰ƒbƒvi’ʏíƒ_ƒ[ƒWj‚Ì”»’è‚ƃvƒŒƒCƒ„[‚Ì”íŠQˆ— +* @return ƒ_[ƒc‚ª–½’†‚µ‚½ê‡TRUE‚ð•Ô‚· +*/ +static bool hit_trap_dart(void) +{ + bool hit = FALSE; + + if (check_hit(125)) + { + msg_print(_("¬‚³‚ȃ_[ƒc‚ª”ò‚ñ‚Å‚«‚ÄŽh‚³‚Á‚½I", "A small dart hits you!")); + + take_hit(DAMAGE_ATTACK, damroll(1, 4), _("ƒ_[ƒc‚Ìã©", "a dart trap"), -1); + + if (!CHECK_MULTISHADOW()) hit = TRUE; + } + else + { + msg_print(_("¬‚³‚ȃ_[ƒc‚ª”ò‚ñ‚Å‚«‚½I‚ªA‰^—Ç‚­“–‚½‚ç‚È‚©‚Á‚½B", "A small dart barely misses you.")); + } + + return hit; +} + +/*! +* @brief ƒ_[ƒcŒnƒgƒ‰ƒbƒvi’ʏíƒ_ƒ[ƒW{”\—Í’lŒ¸­j‚Ì”»’è‚ƃvƒŒƒCƒ„[‚Ì”íŠQˆ— +* @param stat ’ቺ‚·‚é”\—Í’lID +* @return ‚È‚µ +*/ +static void hit_trap_lose_stat(int stat) +{ + if (hit_trap_dart()) + { + do_dec_stat(stat); + } +} + +/*! +* @brief ƒ_[ƒcŒnƒgƒ‰ƒbƒvi’ʏíƒ_ƒ[ƒW{Œ¸‘¬j‚Ì”»’è‚ƃvƒŒƒCƒ„[‚Ì”íŠQˆ— +* @return ‚È‚µ +*/ +static void hit_trap_slow(void) +{ + if (hit_trap_dart()) + { + set_slow(p_ptr->slow + randint0(20) + 20, FALSE); + } +} + +/*! +* @brief ƒ_[ƒcŒnƒgƒ‰ƒbƒvi’ʏíƒ_ƒ[ƒW{ó‘Ԉُíj‚Ì”»’è‚ƃvƒŒƒCƒ„[‚Ì”íŠQˆ— +* @param trap_message ƒƒbƒZ[ƒW‚̕⊮•¶Žš—ñ +* @param resist ó‘Ԉُí‚É’ïR‚·‚é”»’肪o‚½‚È‚çTRUE +* @param set_status ó‘Ԉُí‚ðŽw’è‚·‚éŠÖ”ƒ|ƒCƒ“ƒ^ +* @param turn ó‘Ԉُí‚̒ljÁƒ^[ƒ“—Ê +* @return ‚È‚µ +*/ +static void hit_trap_set_abnormal_status(cptr trap_message, bool resist, bool(*set_status)(IDX), IDX turn_aux) +{ + msg_print(trap_message); + + if (!resist) + { + set_status(turn_aux); + } +} + +/*! +* @brief ƒvƒŒƒCƒ„[‚ւ̃gƒ‰ƒbƒvì“®ˆ—ƒƒCƒ“ƒ‹[ƒ`ƒ“ / +* Handle player hitting a real trap +* @param break_trap ì“®Œã‚̃gƒ‰ƒbƒv”j‰ó‚ªŠm’肵‚Ä‚¢‚é‚È‚ç‚ÎTRUE +* @return ‚È‚µ +*/ +void hit_trap(bool break_trap) +{ + int i, num, dam; + int x = p_ptr->x, y = p_ptr->y; + + /* Get the cave grid */ + cave_type *c_ptr = &cave[y][x]; + feature_type *f_ptr = &f_info[c_ptr->feat]; + int trap_feat_type = have_flag(f_ptr->flags, FF_TRAP) ? f_ptr->subtype : NOT_TRAP; + cptr name = _("ƒgƒ‰ƒbƒv", "a trap"); + + /* Disturb the player */ + disturb(0, 1); + + cave_alter_feat(y, x, FF_HIT_TRAP); + + /* Analyze XXX XXX XXX */ + switch (trap_feat_type) + { + case TRAP_TRAPDOOR: + { + if (p_ptr->levitation) + { + msg_print(_("—Ž‚Æ‚µŒË‚ð”ò‚щz‚¦‚½B", "You fly over a trap door.")); + } + else + { + msg_print(_("—Ž‚Æ‚µŒË‚É—Ž‚¿‚½I", "You have fallen through a trap door!")); + if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) + msg_print(_("‚­‚Á‚»`I", "")); + + sound(SOUND_FALL); + dam = damroll(2, 8); + name = _("—Ž‚Æ‚µŒË", "a trap door"); + + take_hit(DAMAGE_NOESCAPE, dam, name, -1); + + /* Still alive and autosave enabled */ + if (autosave_l && (p_ptr->chp >= 0)) + do_cmd_save_game(TRUE); + + do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("—Ž‚Æ‚µŒË‚É—Ž‚¿‚½", "You have fallen through a trap door!")); + prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT); + + /* Leaving */ + p_ptr->leaving = TRUE; + } + break; + } + + case TRAP_PIT: + case TRAP_SPIKED_PIT: + case TRAP_POISON_PIT: + { + hit_trap_pit(trap_feat_type); + break; + } + + case TRAP_TY_CURSE: + { + msg_print(_("‰½‚©‚ªƒsƒJƒb‚ÆŒõ‚Á‚½I", "There is a flash of shimmering light!")); + num = 2 + randint1(3); + for (i = 0; i < num; i++) + { + (void)summon_specific(0, y, x, dun_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET)); + } + + if (dun_level > randint1(100)) /* No nasty effect for low levels */ + { + bool stop_ty = FALSE; + int count = 0; + + do + { + stop_ty = activate_ty_curse(stop_ty, &count); + } while (one_in_(6)); + } + break; + } + + case TRAP_TELEPORT: + { + msg_print(_("ƒeƒŒƒ|[ƒgEƒgƒ‰ƒbƒv‚ɂЂÁ‚©‚©‚Á‚½I", "You hit a teleport trap!")); + teleport_player(100, TELEPORT_PASSIVE); + break; + } + + case TRAP_FIRE: + { + msg_print(_("‰Š‚É•ï‚܂ꂽI", "You are enveloped in flames!")); + dam = damroll(4, 6); + (void)fire_dam(dam, _("‰Š‚̃gƒ‰ƒbƒv", "a fire trap"), -1, FALSE); + break; + } + + case TRAP_ACID: + { + msg_print(_("Ž_‚ª‚«‚©‚¯‚ç‚ꂽI", "You are splashed with acid!")); + dam = damroll(4, 6); + (void)acid_dam(dam, _("Ž_‚̃gƒ‰ƒbƒv", "an acid trap"), -1, FALSE); + break; + } + + case TRAP_SLOW: + { + hit_trap_slow(); + break; + } + + case TRAP_LOSE_STR: + { + hit_trap_lose_stat(A_STR); + break; + } + + case TRAP_LOSE_DEX: + { + hit_trap_lose_stat(A_DEX); + break; + } + + case TRAP_LOSE_CON: + { + hit_trap_lose_stat(A_CON); + break; + } + + case TRAP_BLIND: + { + hit_trap_set_abnormal_status( + _("•‚¢ƒKƒX‚É•ï‚ݍž‚܂ꂽI", "A black gas surrounds you!"), + p_ptr->resist_blind, + set_blind, p_ptr->blind + (TIME_EFFECT)randint0(50) + 25); + break; + } + + case TRAP_CONFUSE: + { + hit_trap_set_abnormal_status( + _("‚«‚ç‚ß‚­ƒKƒX‚É•ï‚ݍž‚܂ꂽI", "A gas of scintillating colors surrounds you!"), + p_ptr->resist_conf, + set_confused, p_ptr->confused + (TIME_EFFECT)randint0(20) + 10); + break; + } + + case TRAP_POISON: + { + hit_trap_set_abnormal_status( + _("ŽhŒƒ“I‚ȗΐF‚̃KƒX‚É•ï‚ݍž‚܂ꂽI", "A pungent green gas surrounds you!"), + p_ptr->resist_pois || IS_OPPOSE_POIS(), + set_poisoned, p_ptr->poisoned + (TIME_EFFECT)randint0(20) + 10); + break; + } + + case TRAP_SLEEP: + { + msg_print(_("Šï–­‚È”’‚¢–¶‚É•ï‚܂ꂽI", "A strange white mist surrounds you!")); + if (!p_ptr->free_act) + { + msg_print(_("‚ ‚È‚½‚Í–°‚è‚ɏA‚¢‚½B", "You fall asleep.")); + + if (ironman_nightmare) + { + msg_print(_("g‚Ì–Ñ‚à‚悾‚ÂŒõŒi‚ª“ª‚É•‚‚©‚ñ‚¾B", "A horrible vision enters your mind.")); + + /* Have some nightmares */ + sanity_blast(NULL, FALSE); + + } + (void)set_paralyzed(p_ptr->paralyzed + randint0(10) + 5); + } + break; + } + + case TRAP_TRAPS: + { + msg_print(_("‚܂΂䂢‘MŒõ‚ª‘–‚Á‚½I", "There is a bright flash of light!")); + /* Make some new traps */ + project(0, 1, y, x, 0, GF_MAKE_TRAP, PROJECT_HIDE | PROJECT_JUMP | PROJECT_GRID, -1); + + break; + } + + case TRAP_ALARM: + { + msg_print(_("‚¯‚½‚½‚Ü‚µ‚¢‰¹‚ª–‚苿‚¢‚½I", "An alarm sounds!")); + + aggravate_monsters(0); + + break; + } + + case TRAP_OPEN: + { + msg_print(_("‘剹‹¿‚Æ‹¤‚É‚Ü‚í‚è‚Ì•Ç‚ª•ö‚ꂽI", "Suddenly, surrounding walls are opened!")); + (void)project(0, 3, y, x, 0, GF_DISINTEGRATE, PROJECT_GRID | PROJECT_HIDE, -1); + (void)project(0, 3, y, x - 4, 0, GF_DISINTEGRATE, PROJECT_GRID | PROJECT_HIDE, -1); + (void)project(0, 3, y, x + 4, 0, GF_DISINTEGRATE, PROJECT_GRID | PROJECT_HIDE, -1); + aggravate_monsters(0); + + break; + } + + case TRAP_ARMAGEDDON: + { + static int levs[10] = { 0, 0, 20, 10, 5, 3, 2, 1, 1, 1 }; + int evil_idx = 0, good_idx = 0; + + int lev; + msg_print(_("“Ë‘R“VŠE‚̐푈‚ÉŠª‚«ž‚܂ꂽI", "Suddenly, you are surrounded by immotal beings!")); + + /* Summon Demons and Angels */ + for (lev = dun_level; lev >= 20; lev -= 1 + lev / 16) + { + num = levs[MIN(lev / 10, 9)]; + for (i = 0; i < num; i++) + { + int x1 = rand_spread(x, 7); + int y1 = rand_spread(y, 5); + + /* Skip illegal grids */ + if (!in_bounds(y1, x1)) continue; + + /* Require line of projection */ + if (!projectable(p_ptr->y, p_ptr->x, y1, x1)) continue; + + if (summon_specific(0, y1, x1, lev, SUMMON_ARMAGE_EVIL, (PM_NO_PET))) + evil_idx = hack_m_idx_ii; + + if (summon_specific(0, y1, x1, lev, SUMMON_ARMAGE_GOOD, (PM_NO_PET))) + { + good_idx = hack_m_idx_ii; + } + + /* Let them fight each other */ + if (evil_idx && good_idx) + { + monster_type *evil_ptr = &m_list[evil_idx]; + monster_type *good_ptr = &m_list[good_idx]; + evil_ptr->target_y = good_ptr->fy; + evil_ptr->target_x = good_ptr->fx; + good_ptr->target_y = evil_ptr->fy; + good_ptr->target_x = evil_ptr->fx; + } + } + } + break; + } + + case TRAP_PIRANHA: + { + msg_print(_("“Ë‘R•Ç‚©‚琅‚ªˆì‚êo‚µ‚½Iƒsƒ‰ƒjƒA‚ª‚¢‚éI", "Suddenly, the room is filled with water with piranhas!")); + + /* Water fills room */ + fire_ball_hide(GF_WATER_FLOW, 0, 1, 10); + + /* Summon Piranhas */ + num = 1 + dun_level / 20; + for (i = 0; i < num; i++) + { + (void)summon_specific(0, y, x, dun_level, SUMMON_PIRANHAS, (PM_ALLOW_GROUP | PM_NO_PET)); + } + break; + } + } + + if (break_trap && is_trap(c_ptr->feat)) + { + cave_alter_feat(y, x, FF_DISARM); + msg_print(_("ƒgƒ‰ƒbƒv‚𕲍ӂµ‚½B", "You destroyed the trap.")); + } +} diff --git a/src/trap.h b/src/trap.h new file mode 100644 index 000000000..1ac7b530c --- /dev/null +++ b/src/trap.h @@ -0,0 +1,2 @@ +void hit_trap(bool break_trap); + -- 2.11.0