1 #include "mind/mind-ninja.h"
2 #include "cmd-action/cmd-attack.h"
3 #include "combat/combat-options-type.h"
4 #include "effect/effect-characteristics.h"
5 #include "effect/spells-effect-util.h"
6 #include "floor/floor-object.h"
7 #include "io/targeting.h"
8 #include "monster-race/race-indice-types.h"
9 #include "object-enchant/trc-types.h"
10 #include "object/object-generator.h"
11 #include "object/object-kind-hook.h"
12 #include "player/player-effects.h"
13 #include "spell-kind/spells-teleport.h"
17 * @param caster_ptr プレーヤーへの参照ポインタ
18 * @param success 判定成功上の処理ならばTRUE
19 * @return 作用が実際にあった場合TRUEを返す
21 bool kawarimi(player_type *caster_ptr, bool success)
24 object_type *q_ptr = &forge;
26 if (caster_ptr->is_dead)
28 if (caster_ptr->confused || caster_ptr->blind || caster_ptr->paralyzed || caster_ptr->image)
30 if (randint0(200) < caster_ptr->stun)
33 if (!success && one_in_(3)) {
34 msg_print(_("失敗!逃げられなかった。", "Failed! You couldn't run away."));
35 caster_ptr->special_defense &= ~(NINJA_KAWARIMI);
36 caster_ptr->redraw |= (PR_STATUS);
40 POSITION y = caster_ptr->y;
41 POSITION x = caster_ptr->x;
43 teleport_player(caster_ptr, 10 + randint1(90), TELEPORT_SPONTANEOUS);
45 const int SV_WOODEN_STATUE = 0;
46 object_prep(q_ptr, lookup_kind(TV_STATUE, SV_WOODEN_STATUE));
48 q_ptr->pval = MON_NINJA;
49 (void)drop_near(caster_ptr, q_ptr, -1, y, x);
52 msg_print(_("攻撃を受ける前に素早く身をひるがえした。", "You have turned around just before the attack hit you."));
54 msg_print(_("失敗!攻撃を受けてしまった。", "Failed! You are hit by the attack."));
56 caster_ptr->special_defense &= ~(NINJA_KAWARIMI);
57 caster_ptr->redraw |= (PR_STATUS);
62 * @brief 入身処理 / "Rush Attack" routine for Samurai or Ninja
63 * @param caster_ptr プレーヤーへの参照ポインタ
64 * @param mdeath 目標モンスターが死亡したかを返す
65 * @return 作用が実際にあった場合TRUEを返す / Return value is for checking "done"
67 bool rush_attack(player_type *attacker_ptr, bool *mdeath)
74 if (!get_aim_dir(attacker_ptr, &dir))
77 int tx = attacker_ptr->x + project_length * ddx[dir];
78 int ty = attacker_ptr->y + project_length * ddy[dir];
80 if ((dir == 5) && target_okay(attacker_ptr)) {
86 floor_type *floor_ptr = attacker_ptr->current_floor_ptr;
87 if (in_bounds(floor_ptr, ty, tx))
88 tm_idx = floor_ptr->grid_array[ty][tx].m_idx;
91 int path_n = project_path(attacker_ptr, path_g, project_length, attacker_ptr->y, attacker_ptr->x, ty, tx, PROJECT_STOP | PROJECT_KILL);
98 bool tmp_mdeath = FALSE;
100 for (int i = 0; i < path_n; i++) {
103 int ny = GRID_Y(path_g[i]);
104 int nx = GRID_X(path_g[i]);
106 if (is_cave_empty_bold(attacker_ptr, ny, nx) && player_can_enter(attacker_ptr, floor_ptr->grid_array[ny][nx].feat, 0)) {
112 if (!floor_ptr->grid_array[ny][nx].m_idx) {
114 msg_print(_("失敗!", "Failed!"));
116 msg_print(_("ここには入身では入れない。", "You can't move to that place."));
122 if (!player_bold(attacker_ptr, ty, tx))
123 teleport_player_to(attacker_ptr, ty, tx, TELEPORT_NONMAGICAL);
124 update_monster(attacker_ptr, floor_ptr->grid_array[ny][nx].m_idx, TRUE);
126 m_ptr = &floor_ptr->m_list[floor_ptr->grid_array[ny][nx].m_idx];
127 if (tm_idx != floor_ptr->grid_array[ny][nx].m_idx) {
129 msg_format("%s%sが立ちふさがっている!", tm_idx ? "別の" : "", m_ptr->ml ? "モンスター" : "何か");
131 msg_format("There is %s in the way!", m_ptr->ml ? (tm_idx ? "another monster" : "a monster") : "someone");
133 } else if (!player_bold(attacker_ptr, ty, tx)) {
134 GAME_TEXT m_name[MAX_NLEN];
135 monster_desc(attacker_ptr, m_name, m_ptr, 0);
136 msg_format(_("素早く%sの懐に入り込んだ!", "You quickly jump in and attack %s!"), m_name);
139 if (!player_bold(attacker_ptr, ty, tx))
140 teleport_player_to(attacker_ptr, ty, tx, TELEPORT_NONMAGICAL);
142 tmp_mdeath = do_cmd_attack(attacker_ptr, ny, nx, HISSATSU_NYUSIN);
147 if (!moved && !player_bold(attacker_ptr, ty, tx))
148 teleport_player_to(attacker_ptr, ty, tx, TELEPORT_NONMAGICAL);
151 *mdeath = tmp_mdeath;
156 * @brief 盗賊と忍者における不意打ち
157 * @param attacker_ptr プレーヤーへの参照ポインタ
158 * @param pa_ptr 直接攻撃構造体への参照ポインタ
161 void process_surprise_attack(player_type *attacker_ptr, player_attack_type *pa_ptr)
163 monster_race *r_ptr = &r_info[pa_ptr->m_ptr->r_idx];
164 if (!has_melee_weapon(attacker_ptr, INVEN_RARM + pa_ptr->hand) || attacker_ptr->icky_wield[pa_ptr->hand])
167 int tmp = attacker_ptr->lev * 6 + (attacker_ptr->skill_stl + 10) * 4;
168 if (attacker_ptr->monlite && (pa_ptr->mode != HISSATSU_NYUSIN))
170 if (attacker_ptr->cursed & TRC_AGGRAVATE)
172 if (r_ptr->level > (attacker_ptr->lev * attacker_ptr->lev / 20 + 10))
174 if (MON_CSLEEP(pa_ptr->m_ptr) && pa_ptr->m_ptr->ml) {
175 /* Can't backstab creatures that we can't see, right? */
176 pa_ptr->backstab = TRUE;
177 } else if ((attacker_ptr->special_defense & NINJA_S_STEALTH) && (randint0(tmp) > (r_ptr->level + 20)) && pa_ptr->m_ptr->ml
178 && !(r_ptr->flagsr & RFR_RES_ALL)) {
179 pa_ptr->surprise_attack = TRUE;
180 } else if (MON_MONFEAR(pa_ptr->m_ptr) && pa_ptr->m_ptr->ml) {
181 pa_ptr->stab_fleeing = TRUE;
185 void print_surprise_attack(player_attack_type *pa_ptr)
187 if (pa_ptr->backstab)
188 msg_format(_("あなたは冷酷にも眠っている無力な%sを突き刺した!", "You cruelly stab the helpless, sleeping %s!"), pa_ptr->m_name);
189 else if (pa_ptr->surprise_attack)
190 msg_format(_("不意を突いて%sに強烈な一撃を喰らわせた!", "You make surprise attack, and hit %s with a powerful blow!"), pa_ptr->m_name);
191 else if (pa_ptr->stab_fleeing)
192 msg_format(_("逃げる%sを背中から突き刺した!", "You backstab the fleeing %s!"), pa_ptr->m_name);
193 else if (!pa_ptr->monk_attack)
194 msg_format(_("%sを攻撃した。", "You hit %s."), pa_ptr->m_name);
198 * @brief 盗賊と忍者における不意打ちのダメージ計算
199 * @param attacker_ptr プレーヤーへの参照ポインタ
200 * @param pa_ptr 直接攻撃構造体への参照ポインタ
203 void calc_surprise_attack_damage(player_type *attacker_ptr, player_attack_type *pa_ptr)
205 if (pa_ptr->backstab) {
206 pa_ptr->attack_damage *= (3 + (attacker_ptr->lev / 20));
210 if (pa_ptr->surprise_attack) {
211 pa_ptr->attack_damage = pa_ptr->attack_damage * (5 + (attacker_ptr->lev * 2 / 25)) / 2;
215 if (pa_ptr->stab_fleeing)
216 pa_ptr->attack_damage = (3 * pa_ptr->attack_damage) / 2;
219 void hayagake(player_type *creature_ptr)
221 if (creature_ptr->action == ACTION_HAYAGAKE) {
222 set_action(creature_ptr, ACTION_NONE);
223 creature_ptr->energy_use = 0;
227 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x];
228 feature_type *f_ptr = &f_info[g_ptr->feat];
230 if (!have_flag(f_ptr->flags, FF_PROJECT) || (!creature_ptr->levitation && have_flag(f_ptr->flags, FF_DEEP))) {
231 msg_print(_("ここでは素早く動けない。", "You cannot run in here."));
233 set_action(creature_ptr, ACTION_HAYAGAKE);
236 creature_ptr->energy_use = 0;