• R/O
  • HTTP
  • SSH
  • HTTPS

hengband: Commit

変愚蛮怒のメインリポジトリです


Commit MetaInfo

Revisionb3cfbe29a94aa29d0c8830ba28e26408841c4db1 (tree)
Time2019-06-14 21:38:33
Authordeskull <deskull@user...>
Commiterdeskull

Log Message

[Refactor] #37353 モンスター間の打撃処理を melee1.c / melee.h へ移動.

Change Summary

Incremental Difference

--- a/src/melee.h
+++ b/src/melee.h
@@ -157,5 +157,6 @@ extern HIT_POINT critical_norm(WEIGHT weight, int plus, HIT_POINT dam, s16b meic
157157 extern bool py_attack(POSITION y, POSITION x, COMBAT_OPTION_IDX mode);
158158 extern bool make_attack_normal(MONSTER_IDX m_idx);
159159 extern void mon_take_hit_mon(MONSTER_IDX m_idx, HIT_POINT dam, bool *dead, bool *fear, concptr note, MONSTER_IDX who);
160+extern bool monst_attack_monst(MONSTER_IDX m_idx, MONSTER_IDX t_idx);
160161
161162 extern const mbe_info_type mbe_info[];
--- a/src/melee1.c
+++ b/src/melee1.c
@@ -4105,6 +4105,635 @@ bool make_attack_normal(MONSTER_IDX m_idx)
41054105 }
41064106
41074107
4108+#define BLOW_EFFECT_TYPE_NONE 0
4109+#define BLOW_EFFECT_TYPE_FEAR 1
4110+#define BLOW_EFFECT_TYPE_SLEEP 2
4111+#define BLOW_EFFECT_TYPE_HEAL 3
4112+
4113+/*!
4114+ * @brief モンスターから敵モンスターへの打撃攻撃処理
4115+ * @param m_idx 攻撃側モンスターの参照ID
4116+ * @param t_idx 目標側モンスターの参照ID
4117+ * @return 実際に打撃処理が行われた場合TRUEを返す
4118+ */
4119+bool monst_attack_monst(MONSTER_IDX m_idx, MONSTER_IDX t_idx)
4120+{
4121+ monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
4122+ monster_type *t_ptr = &current_floor_ptr->m_list[t_idx];
4123+
4124+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
4125+ monster_race *tr_ptr = &r_info[t_ptr->r_idx];
4126+
4127+ ARMOUR_CLASS ap_cnt;
4128+ ARMOUR_CLASS ac;
4129+ DEPTH rlev;
4130+ int pt;
4131+ GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
4132+ char temp[MAX_NLEN];
4133+ bool blinked;
4134+ bool explode = FALSE, touched = FALSE, fear = FALSE, dead = FALSE;
4135+ POSITION y_saver = t_ptr->fy;
4136+ POSITION x_saver = t_ptr->fx;
4137+ int effect_type;
4138+
4139+ bool see_m = is_seen(m_ptr);
4140+ bool see_t = is_seen(t_ptr);
4141+ bool see_either = see_m || see_t;
4142+
4143+ /* Can the player be aware of this attack? */
4144+ bool known = (m_ptr->cdis <= MAX_SIGHT) || (t_ptr->cdis <= MAX_SIGHT);
4145+ bool do_silly_attack = (one_in_(2) && p_ptr->image);
4146+
4147+ /* Cannot attack self */
4148+ if (m_idx == t_idx) return FALSE;
4149+
4150+ /* Not allowed to attack */
4151+ if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE;
4152+
4153+ if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) return (FALSE);
4154+
4155+ /* Total armor */
4156+ ac = tr_ptr->ac;
4157+
4158+ /* Extract the effective monster level */
4159+ rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
4160+
4161+ monster_desc(m_name, m_ptr, 0);
4162+ monster_desc(t_name, t_ptr, 0);
4163+
4164+ /* Assume no blink */
4165+ blinked = FALSE;
4166+
4167+ if (!see_either && known)
4168+ {
4169+ current_floor_ptr->monster_noise = TRUE;
4170+ }
4171+
4172+ if (p_ptr->riding && (m_idx == p_ptr->riding)) disturb(TRUE, TRUE);
4173+
4174+ /* Scan through all four blows */
4175+ for (ap_cnt = 0; ap_cnt < 4; ap_cnt++)
4176+ {
4177+ bool obvious = FALSE;
4178+
4179+ HIT_POINT power = 0;
4180+ HIT_POINT damage = 0;
4181+
4182+ concptr act = NULL;
4183+
4184+ /* Extract the attack infomation */
4185+ int effect = r_ptr->blow[ap_cnt].effect;
4186+ int method = r_ptr->blow[ap_cnt].method;
4187+ int d_dice = r_ptr->blow[ap_cnt].d_dice;
4188+ int d_side = r_ptr->blow[ap_cnt].d_side;
4189+
4190+ if (!monster_is_valid(m_ptr)) break;
4191+
4192+ /* Stop attacking if the target dies! */
4193+ if (t_ptr->fx != x_saver || t_ptr->fy != y_saver)
4194+ break;
4195+
4196+ /* Hack -- no more attacks */
4197+ if (!method) break;
4198+
4199+ if (method == RBM_SHOOT) continue;
4200+
4201+ /* Extract the attack "power" */
4202+ power = mbe_info[effect].power;
4203+
4204+ /* Monster hits */
4205+ if (!effect || check_hit2(power, rlev, ac, MON_STUNNED(m_ptr)))
4206+ {
4207+ (void)set_monster_csleep(t_idx, 0);
4208+
4209+ if (t_ptr->ml)
4210+ {
4211+ /* Redraw the health bar */
4212+ if (p_ptr->health_who == t_idx) p_ptr->redraw |= (PR_HEALTH);
4213+ if (p_ptr->riding == t_idx) p_ptr->redraw |= (PR_UHEALTH);
4214+ }
4215+
4216+ /* Describe the attack method */
4217+ switch (method)
4218+ {
4219+ case RBM_HIT:
4220+ {
4221+ act = _("%sを殴った。", "hits %s.");
4222+ touched = TRUE;
4223+ break;
4224+ }
4225+
4226+ case RBM_TOUCH:
4227+ {
4228+ act = _("%sを触った。", "touches %s.");
4229+ touched = TRUE;
4230+ break;
4231+ }
4232+
4233+ case RBM_PUNCH:
4234+ {
4235+ act = _("%sをパンチした。", "punches %s.");
4236+ touched = TRUE;
4237+ break;
4238+ }
4239+
4240+ case RBM_KICK:
4241+ {
4242+ act = _("%sを蹴った。", "kicks %s.");
4243+ touched = TRUE;
4244+ break;
4245+ }
4246+
4247+ case RBM_CLAW:
4248+ {
4249+ act = _("%sをひっかいた。", "claws %s.");
4250+ touched = TRUE;
4251+ break;
4252+ }
4253+
4254+ case RBM_BITE:
4255+ {
4256+ act = _("%sを噛んだ。", "bites %s.");
4257+ touched = TRUE;
4258+ break;
4259+ }
4260+
4261+ case RBM_STING:
4262+ {
4263+ act = _("%sを刺した。", "stings %s.");
4264+ touched = TRUE;
4265+ break;
4266+ }
4267+
4268+ case RBM_SLASH:
4269+ {
4270+ act = _("%sを斬った。", "slashes %s.");
4271+ break;
4272+ }
4273+
4274+ case RBM_BUTT:
4275+ {
4276+ act = _("%sを角で突いた。", "butts %s.");
4277+ touched = TRUE;
4278+ break;
4279+ }
4280+
4281+ case RBM_CRUSH:
4282+ {
4283+ act = _("%sに体当りした。", "crushes %s.");
4284+ touched = TRUE;
4285+ break;
4286+ }
4287+
4288+ case RBM_ENGULF:
4289+ {
4290+ act = _("%sを飲み込んだ。", "engulfs %s.");
4291+ touched = TRUE;
4292+ break;
4293+ }
4294+
4295+ case RBM_CHARGE:
4296+ {
4297+ act = _("%sに請求書をよこした。", "charges %s.");
4298+ touched = TRUE;
4299+ break;
4300+ }
4301+
4302+ case RBM_CRAWL:
4303+ {
4304+ act = _("%sの体の上を這い回った。", "crawls on %s.");
4305+ touched = TRUE;
4306+ break;
4307+ }
4308+
4309+ case RBM_DROOL:
4310+ {
4311+ act = _("%sによだれをたらした。", "drools on %s.");
4312+ touched = FALSE;
4313+ break;
4314+ }
4315+
4316+ case RBM_SPIT:
4317+ {
4318+ act = _("%sに唾を吐いた。", "spits on %s.");
4319+ touched = FALSE;
4320+ break;
4321+ }
4322+
4323+ case RBM_EXPLODE:
4324+ {
4325+ if (see_either) disturb(TRUE, TRUE);
4326+ act = _("爆発した。", "explodes.");
4327+ explode = TRUE;
4328+ touched = FALSE;
4329+ break;
4330+ }
4331+
4332+ case RBM_GAZE:
4333+ {
4334+ act = _("%sをにらんだ。", "gazes at %s.");
4335+ touched = FALSE;
4336+ break;
4337+ }
4338+
4339+ case RBM_WAIL:
4340+ {
4341+ act = _("%sに泣きついた。", "wails at %s.");
4342+ touched = FALSE;
4343+ break;
4344+ }
4345+
4346+ case RBM_SPORE:
4347+ {
4348+ act = _("%sに胞子を飛ばした。", "releases spores at %s.");
4349+ touched = FALSE;
4350+ break;
4351+ }
4352+
4353+ case RBM_XXX4:
4354+ {
4355+ act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
4356+ touched = FALSE;
4357+ break;
4358+ }
4359+
4360+ case RBM_BEG:
4361+ {
4362+ act = _("%sに金をせがんだ。", "begs %s for money.");
4363+ touched = FALSE;
4364+ break;
4365+ }
4366+
4367+ case RBM_INSULT:
4368+ {
4369+ act = _("%sを侮辱した。", "insults %s.");
4370+ touched = FALSE;
4371+ break;
4372+ }
4373+
4374+ case RBM_MOAN:
4375+ {
4376+ act = _("%sにむかってうめいた。", "moans at %s.");
4377+ touched = FALSE;
4378+ break;
4379+ }
4380+
4381+ case RBM_SHOW:
4382+ {
4383+ act = _("%sにむかって歌った。", "sings to %s.");
4384+ touched = FALSE;
4385+ break;
4386+ }
4387+ }
4388+
4389+ if (act && see_either)
4390+ {
4391+#ifdef JP
4392+ if (do_silly_attack) act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
4393+ strfmt(temp, act, t_name);
4394+ msg_format("%^sは%s", m_name, temp);
4395+#else
4396+ if (do_silly_attack)
4397+ {
4398+ act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
4399+ strfmt(temp, "%s %s.", act, t_name);
4400+ }
4401+ else strfmt(temp, act, t_name);
4402+ msg_format("%^s %s", m_name, temp);
4403+#endif
4404+ }
4405+
4406+ /* Hack -- assume all attacks are obvious */
4407+ obvious = TRUE;
4408+
4409+ /* Roll out the damage */
4410+ damage = damroll(d_dice, d_side);
4411+
4412+ /* Assume no effect */
4413+ effect_type = BLOW_EFFECT_TYPE_NONE;
4414+
4415+ pt = GF_MISSILE;
4416+
4417+ /* Apply appropriate damage */
4418+ switch (effect)
4419+ {
4420+ case 0:
4421+ case RBE_DR_MANA:
4422+ damage = pt = 0;
4423+ break;
4424+
4425+ case RBE_SUPERHURT:
4426+ if ((randint1(rlev * 2 + 250) > (ac + 200)) || one_in_(13))
4427+ {
4428+ int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
4429+ damage = MAX(damage, tmp_damage * 2);
4430+ break;
4431+ }
4432+
4433+ /* Fall through */
4434+
4435+ case RBE_HURT:
4436+ damage -= (damage * ((ac < 150) ? ac : 150) / 250);
4437+ break;
4438+
4439+ case RBE_POISON:
4440+ case RBE_DISEASE:
4441+ pt = GF_POIS;
4442+ break;
4443+
4444+ case RBE_UN_BONUS:
4445+ case RBE_UN_POWER:
4446+ pt = GF_DISENCHANT;
4447+ break;
4448+
4449+ case RBE_EAT_ITEM:
4450+ case RBE_EAT_GOLD:
4451+ if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE;
4452+ break;
4453+
4454+ case RBE_EAT_FOOD:
4455+ case RBE_EAT_LITE:
4456+ case RBE_BLIND:
4457+ case RBE_LOSE_STR:
4458+ case RBE_LOSE_INT:
4459+ case RBE_LOSE_WIS:
4460+ case RBE_LOSE_DEX:
4461+ case RBE_LOSE_CON:
4462+ case RBE_LOSE_CHR:
4463+ case RBE_LOSE_ALL:
4464+ break;
4465+
4466+ case RBE_ACID:
4467+ pt = GF_ACID;
4468+ break;
4469+
4470+ case RBE_ELEC:
4471+ pt = GF_ELEC;
4472+ break;
4473+
4474+ case RBE_FIRE:
4475+ pt = GF_FIRE;
4476+ break;
4477+
4478+ case RBE_COLD:
4479+ pt = GF_COLD;
4480+ break;
4481+
4482+ case RBE_CONFUSE:
4483+ pt = GF_CONFUSION;
4484+ break;
4485+
4486+ case RBE_TERRIFY:
4487+ effect_type = BLOW_EFFECT_TYPE_FEAR;
4488+ break;
4489+
4490+ case RBE_PARALYZE:
4491+ effect_type = BLOW_EFFECT_TYPE_SLEEP;
4492+ break;
4493+
4494+ case RBE_SHATTER:
4495+ damage -= (damage * ((ac < 150) ? ac : 150) / 250);
4496+ if (damage > 23) earthquake(m_ptr->fy, m_ptr->fx, 8, m_idx);
4497+ break;
4498+
4499+ case RBE_EXP_10:
4500+ case RBE_EXP_20:
4501+ case RBE_EXP_40:
4502+ case RBE_EXP_80:
4503+ pt = GF_NETHER;
4504+ break;
4505+
4506+ case RBE_TIME:
4507+ pt = GF_TIME;
4508+ break;
4509+
4510+ case RBE_DR_LIFE:
4511+ pt = GF_HYPODYNAMIA;
4512+ effect_type = BLOW_EFFECT_TYPE_HEAL;
4513+ break;
4514+
4515+ case RBE_INERTIA:
4516+ pt = GF_INERTIAL;
4517+ break;
4518+
4519+ case RBE_STUN:
4520+ pt = GF_SOUND;
4521+ break;
4522+
4523+ default:
4524+ pt = 0;
4525+ break;
4526+ }
4527+
4528+ if (pt)
4529+ {
4530+ /* Do damage if not exploding */
4531+ if (!explode)
4532+ {
4533+ project(m_idx, 0, t_ptr->fy, t_ptr->fx,
4534+ damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
4535+ }
4536+
4537+ switch (effect_type)
4538+ {
4539+ case BLOW_EFFECT_TYPE_FEAR:
4540+ project(m_idx, 0, t_ptr->fy, t_ptr->fx,
4541+ damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
4542+ break;
4543+
4544+ case BLOW_EFFECT_TYPE_SLEEP:
4545+ project(m_idx, 0, t_ptr->fy, t_ptr->fx,
4546+ r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
4547+ break;
4548+
4549+ case BLOW_EFFECT_TYPE_HEAL:
4550+ if ((monster_living(m_idx)) && (damage > 2))
4551+ {
4552+ bool did_heal = FALSE;
4553+
4554+ if (m_ptr->hp < m_ptr->maxhp) did_heal = TRUE;
4555+
4556+ /* Heal */
4557+ m_ptr->hp += damroll(4, damage / 6);
4558+ if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
4559+
4560+ /* Redraw (later) if needed */
4561+ if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
4562+ if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
4563+
4564+ /* Special message */
4565+ if (see_m && did_heal)
4566+ {
4567+ msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
4568+ }
4569+ }
4570+ break;
4571+ }
4572+
4573+ if (touched)
4574+ {
4575+ /* Aura fire */
4576+ if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx)
4577+ {
4578+ if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
4579+ {
4580+ if (see_either)
4581+ {
4582+ msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
4583+ }
4584+ if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_FIRE;
4585+ project(t_idx, 0, m_ptr->fy, m_ptr->fx,
4586+ damroll(1 + ((tr_ptr->level) / 26),
4587+ 1 + ((tr_ptr->level) / 17)),
4588+ GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
4589+ }
4590+ else
4591+ {
4592+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
4593+ }
4594+ }
4595+
4596+ /* Aura cold */
4597+ if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx)
4598+ {
4599+ if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
4600+ {
4601+ if (see_either)
4602+ {
4603+ msg_format(_("%^sは突然寒くなった!", "%^s is suddenly very cold!"), m_name);
4604+ }
4605+ if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags3 |= RF3_AURA_COLD;
4606+ project(t_idx, 0, m_ptr->fy, m_ptr->fx,
4607+ damroll(1 + ((tr_ptr->level) / 26),
4608+ 1 + ((tr_ptr->level) / 17)),
4609+ GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
4610+ }
4611+ else
4612+ {
4613+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
4614+ }
4615+ }
4616+
4617+ /* Aura elec */
4618+ if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx)
4619+ {
4620+ if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
4621+ {
4622+ if (see_either)
4623+ {
4624+ msg_format(_("%^sは電撃を食らった!", "%^s gets zapped!"), m_name);
4625+ }
4626+ if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_ELEC;
4627+ project(t_idx, 0, m_ptr->fy, m_ptr->fx,
4628+ damroll(1 + ((tr_ptr->level) / 26),
4629+ 1 + ((tr_ptr->level) / 17)),
4630+ GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
4631+ }
4632+ else
4633+ {
4634+ if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
4635+ }
4636+ }
4637+ }
4638+ }
4639+ }
4640+
4641+ /* Monster missed player */
4642+ else
4643+ {
4644+ /* Analyze failed attacks */
4645+ switch (method)
4646+ {
4647+ case RBM_HIT:
4648+ case RBM_TOUCH:
4649+ case RBM_PUNCH:
4650+ case RBM_KICK:
4651+ case RBM_CLAW:
4652+ case RBM_BITE:
4653+ case RBM_STING:
4654+ case RBM_SLASH:
4655+ case RBM_BUTT:
4656+ case RBM_CRUSH:
4657+ case RBM_ENGULF:
4658+ case RBM_CHARGE:
4659+ {
4660+ (void)set_monster_csleep(t_idx, 0);
4661+
4662+ /* Visible monsters */
4663+ if (see_m)
4664+ {
4665+#ifdef JP
4666+ msg_format("%sは%^sの攻撃をかわした。", t_name, m_name);
4667+#else
4668+ msg_format("%^s misses %s.", m_name, t_name);
4669+#endif
4670+ }
4671+
4672+ break;
4673+ }
4674+ }
4675+ }
4676+
4677+
4678+ /* Analyze "visible" monsters only */
4679+ if (is_original_ap_and_seen(m_ptr) && !do_silly_attack)
4680+ {
4681+ /* Count "obvious" attacks (and ones that cause damage) */
4682+ if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10))
4683+ {
4684+ /* Count attacks of this type */
4685+ if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR)
4686+ {
4687+ r_ptr->r_blows[ap_cnt]++;
4688+ }
4689+ }
4690+ }
4691+ }
4692+
4693+ if (explode)
4694+ {
4695+ sound(SOUND_EXPLODE);
4696+
4697+ /* Cancel Invulnerability */
4698+ (void)set_monster_invulner(m_idx, 0, FALSE);
4699+ mon_take_hit_mon(m_idx, m_ptr->hp + 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
4700+ blinked = FALSE;
4701+ }
4702+
4703+ /* Blink away */
4704+ if (blinked && m_ptr->r_idx)
4705+ {
4706+ if (teleport_barrier(m_idx))
4707+ {
4708+ if (see_m)
4709+ {
4710+ msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But magic barrier obstructs it."));
4711+ }
4712+ else if (known)
4713+ {
4714+ current_floor_ptr->monster_noise = TRUE;
4715+ }
4716+ }
4717+ else
4718+ {
4719+ if (see_m)
4720+ {
4721+ msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
4722+ }
4723+ else if (known)
4724+ {
4725+ current_floor_ptr->monster_noise = TRUE;
4726+ }
4727+
4728+ teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L);
4729+ }
4730+ }
4731+
4732+ return TRUE;
4733+}
4734+
4735+
4736+
41084737 /*!
41094738 * @brief モンスターが敵モンスターに行う打撃処理 /
41104739 * Hack, based on mon_take_hit... perhaps all monster attacks on other monsters should use this?
--- a/src/monster-process.c
+++ b/src/monster-process.c
@@ -1202,666 +1202,6 @@ static bool get_moves(MONSTER_IDX m_idx, DIRECTION *mm)
12021202 }
12031203
12041204
1205-/*!
1206- * @brief モンスターから敵モンスターへの命中判定
1207- * @param power 打撃属性による基本命中値
1208- * @param level 攻撃側モンスターのレベル
1209- * @param ac 目標モンスターのAC
1210- * @param stun 攻撃側モンスターが朦朧状態ならTRUEを返す
1211- * @return 命中ならばTRUEを返す
1212- */
1213-static int check_hit2(int power, DEPTH level, ARMOUR_CLASS ac, int stun)
1214-{
1215- int i, k;
1216-
1217- /* Percentile dice */
1218- k = randint0(100);
1219-
1220- if (stun && one_in_(2)) return FALSE;
1221-
1222- /* Hack -- Always miss or hit */
1223- if (k < 10) return (k < 5);
1224-
1225- /* Calculate the "attack quality" */
1226- i = (power + (level * 3));
1227-
1228- /* Power and Level compete against Armor */
1229- if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE);
1230-
1231- /* Assume miss */
1232- return (FALSE);
1233-}
1234-
1235-
1236-#define BLOW_EFFECT_TYPE_NONE 0
1237-#define BLOW_EFFECT_TYPE_FEAR 1
1238-#define BLOW_EFFECT_TYPE_SLEEP 2
1239-#define BLOW_EFFECT_TYPE_HEAL 3
1240-
1241-
1242-/*!
1243- * @brief モンスターから敵モンスターへの打撃攻撃処理
1244- * @param m_idx 攻撃側モンスターの参照ID
1245- * @param t_idx 目標側モンスターの参照ID
1246- * @return 実際に打撃処理が行われた場合TRUEを返す
1247- */
1248-static bool monst_attack_monst(MONSTER_IDX m_idx, MONSTER_IDX t_idx)
1249-{
1250- monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
1251- monster_type *t_ptr = &current_floor_ptr->m_list[t_idx];
1252-
1253- monster_race *r_ptr = &r_info[m_ptr->r_idx];
1254- monster_race *tr_ptr = &r_info[t_ptr->r_idx];
1255-
1256- ARMOUR_CLASS ap_cnt;
1257- ARMOUR_CLASS ac;
1258- DEPTH rlev;
1259- int pt;
1260- GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
1261- char temp[MAX_NLEN];
1262- bool blinked;
1263- bool explode = FALSE, touched = FALSE, fear = FALSE, dead = FALSE;
1264- POSITION y_saver = t_ptr->fy;
1265- POSITION x_saver = t_ptr->fx;
1266- int effect_type;
1267-
1268- bool see_m = is_seen(m_ptr);
1269- bool see_t = is_seen(t_ptr);
1270- bool see_either = see_m || see_t;
1271-
1272- /* Can the player be aware of this attack? */
1273- bool known = (m_ptr->cdis <= MAX_SIGHT) || (t_ptr->cdis <= MAX_SIGHT);
1274- bool do_silly_attack = (one_in_(2) && p_ptr->image);
1275-
1276- /* Cannot attack self */
1277- if (m_idx == t_idx) return FALSE;
1278-
1279- /* Not allowed to attack */
1280- if (r_ptr->flags1 & RF1_NEVER_BLOW) return FALSE;
1281-
1282- if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) return (FALSE);
1283-
1284- /* Total armor */
1285- ac = tr_ptr->ac;
1286-
1287- /* Extract the effective monster level */
1288- rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
1289-
1290- monster_desc(m_name, m_ptr, 0);
1291- monster_desc(t_name, t_ptr, 0);
1292-
1293- /* Assume no blink */
1294- blinked = FALSE;
1295-
1296- if (!see_either && known)
1297- {
1298- current_floor_ptr->monster_noise = TRUE;
1299- }
1300-
1301- if (p_ptr->riding && (m_idx == p_ptr->riding)) disturb(TRUE, TRUE);
1302-
1303- /* Scan through all four blows */
1304- for (ap_cnt = 0; ap_cnt < 4; ap_cnt++)
1305- {
1306- bool obvious = FALSE;
1307-
1308- HIT_POINT power = 0;
1309- HIT_POINT damage = 0;
1310-
1311- concptr act = NULL;
1312-
1313- /* Extract the attack infomation */
1314- int effect = r_ptr->blow[ap_cnt].effect;
1315- int method = r_ptr->blow[ap_cnt].method;
1316- int d_dice = r_ptr->blow[ap_cnt].d_dice;
1317- int d_side = r_ptr->blow[ap_cnt].d_side;
1318-
1319- if (!monster_is_valid(m_ptr)) break;
1320-
1321- /* Stop attacking if the target dies! */
1322- if (t_ptr->fx != x_saver || t_ptr->fy != y_saver)
1323- break;
1324-
1325- /* Hack -- no more attacks */
1326- if (!method) break;
1327-
1328- if (method == RBM_SHOOT) continue;
1329-
1330- /* Extract the attack "power" */
1331- power = mbe_info[effect].power;
1332-
1333- /* Monster hits */
1334- if (!effect || check_hit2(power, rlev, ac, MON_STUNNED(m_ptr)))
1335- {
1336- (void)set_monster_csleep(t_idx, 0);
1337-
1338- if (t_ptr->ml)
1339- {
1340- /* Redraw the health bar */
1341- if (p_ptr->health_who == t_idx) p_ptr->redraw |= (PR_HEALTH);
1342- if (p_ptr->riding == t_idx) p_ptr->redraw |= (PR_UHEALTH);
1343- }
1344-
1345- /* Describe the attack method */
1346- switch (method)
1347- {
1348- case RBM_HIT:
1349- {
1350- act = _("%sを殴った。", "hits %s.");
1351- touched = TRUE;
1352- break;
1353- }
1354-
1355- case RBM_TOUCH:
1356- {
1357- act = _("%sを触った。", "touches %s.");
1358- touched = TRUE;
1359- break;
1360- }
1361-
1362- case RBM_PUNCH:
1363- {
1364- act = _("%sをパンチした。", "punches %s.");
1365- touched = TRUE;
1366- break;
1367- }
1368-
1369- case RBM_KICK:
1370- {
1371- act = _("%sを蹴った。", "kicks %s.");
1372- touched = TRUE;
1373- break;
1374- }
1375-
1376- case RBM_CLAW:
1377- {
1378- act = _("%sをひっかいた。", "claws %s.");
1379- touched = TRUE;
1380- break;
1381- }
1382-
1383- case RBM_BITE:
1384- {
1385- act = _("%sを噛んだ。", "bites %s.");
1386- touched = TRUE;
1387- break;
1388- }
1389-
1390- case RBM_STING:
1391- {
1392- act = _("%sを刺した。", "stings %s.");
1393- touched = TRUE;
1394- break;
1395- }
1396-
1397- case RBM_SLASH:
1398- {
1399- act = _("%sを斬った。", "slashes %s.");
1400- break;
1401- }
1402-
1403- case RBM_BUTT:
1404- {
1405- act = _("%sを角で突いた。", "butts %s.");
1406- touched = TRUE;
1407- break;
1408- }
1409-
1410- case RBM_CRUSH:
1411- {
1412- act = _("%sに体当りした。", "crushes %s.");
1413- touched = TRUE;
1414- break;
1415- }
1416-
1417- case RBM_ENGULF:
1418- {
1419- act = _("%sを飲み込んだ。", "engulfs %s.");
1420- touched = TRUE;
1421- break;
1422- }
1423-
1424- case RBM_CHARGE:
1425- {
1426- act = _("%sに請求書をよこした。", "charges %s.");
1427- touched = TRUE;
1428- break;
1429- }
1430-
1431- case RBM_CRAWL:
1432- {
1433- act = _("%sの体の上を這い回った。", "crawls on %s.");
1434- touched = TRUE;
1435- break;
1436- }
1437-
1438- case RBM_DROOL:
1439- {
1440- act = _("%sによだれをたらした。", "drools on %s.");
1441- touched = FALSE;
1442- break;
1443- }
1444-
1445- case RBM_SPIT:
1446- {
1447- act = _("%sに唾を吐いた。", "spits on %s.");
1448- touched = FALSE;
1449- break;
1450- }
1451-
1452- case RBM_EXPLODE:
1453- {
1454- if (see_either) disturb(TRUE, TRUE);
1455- act = _("爆発した。", "explodes.");
1456- explode = TRUE;
1457- touched = FALSE;
1458- break;
1459- }
1460-
1461- case RBM_GAZE:
1462- {
1463- act = _("%sをにらんだ。", "gazes at %s.");
1464- touched = FALSE;
1465- break;
1466- }
1467-
1468- case RBM_WAIL:
1469- {
1470- act = _("%sに泣きついた。", "wails at %s.");
1471- touched = FALSE;
1472- break;
1473- }
1474-
1475- case RBM_SPORE:
1476- {
1477- act = _("%sに胞子を飛ばした。", "releases spores at %s.");
1478- touched = FALSE;
1479- break;
1480- }
1481-
1482- case RBM_XXX4:
1483- {
1484- act = _("%sにXXX4を飛ばした。", "projects XXX4's at %s.");
1485- touched = FALSE;
1486- break;
1487- }
1488-
1489- case RBM_BEG:
1490- {
1491- act = _("%sに金をせがんだ。", "begs %s for money.");
1492- touched = FALSE;
1493- break;
1494- }
1495-
1496- case RBM_INSULT:
1497- {
1498- act = _("%sを侮辱した。", "insults %s.");
1499- touched = FALSE;
1500- break;
1501- }
1502-
1503- case RBM_MOAN:
1504- {
1505- act = _("%sにむかってうめいた。", "moans at %s.");
1506- touched = FALSE;
1507- break;
1508- }
1509-
1510- case RBM_SHOW:
1511- {
1512- act = _("%sにむかって歌った。", "sings to %s.");
1513- touched = FALSE;
1514- break;
1515- }
1516- }
1517-
1518- if (act && see_either)
1519- {
1520-#ifdef JP
1521- if (do_silly_attack) act = silly_attacks2[randint0(MAX_SILLY_ATTACK)];
1522- strfmt(temp, act, t_name);
1523- msg_format("%^sは%s", m_name, temp);
1524-#else
1525- if (do_silly_attack)
1526- {
1527- act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
1528- strfmt(temp, "%s %s.", act, t_name);
1529- }
1530- else strfmt(temp, act, t_name);
1531- msg_format("%^s %s", m_name, temp);
1532-#endif
1533- }
1534-
1535- /* Hack -- assume all attacks are obvious */
1536- obvious = TRUE;
1537-
1538- /* Roll out the damage */
1539- damage = damroll(d_dice, d_side);
1540-
1541- /* Assume no effect */
1542- effect_type = BLOW_EFFECT_TYPE_NONE;
1543-
1544- pt = GF_MISSILE;
1545-
1546- /* Apply appropriate damage */
1547- switch (effect)
1548- {
1549- case 0:
1550- case RBE_DR_MANA:
1551- damage = pt = 0;
1552- break;
1553-
1554- case RBE_SUPERHURT:
1555- if ((randint1(rlev*2+250) > (ac+200)) || one_in_(13))
1556- {
1557- int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
1558- damage = MAX(damage, tmp_damage * 2);
1559- break;
1560- }
1561-
1562- /* Fall through */
1563-
1564- case RBE_HURT:
1565- damage -= (damage * ((ac < 150) ? ac : 150) / 250);
1566- break;
1567-
1568- case RBE_POISON:
1569- case RBE_DISEASE:
1570- pt = GF_POIS;
1571- break;
1572-
1573- case RBE_UN_BONUS:
1574- case RBE_UN_POWER:
1575- pt = GF_DISENCHANT;
1576- break;
1577-
1578- case RBE_EAT_ITEM:
1579- case RBE_EAT_GOLD:
1580- if ((p_ptr->riding != m_idx) && one_in_(2)) blinked = TRUE;
1581- break;
1582-
1583- case RBE_EAT_FOOD:
1584- case RBE_EAT_LITE:
1585- case RBE_BLIND:
1586- case RBE_LOSE_STR:
1587- case RBE_LOSE_INT:
1588- case RBE_LOSE_WIS:
1589- case RBE_LOSE_DEX:
1590- case RBE_LOSE_CON:
1591- case RBE_LOSE_CHR:
1592- case RBE_LOSE_ALL:
1593- break;
1594-
1595- case RBE_ACID:
1596- pt = GF_ACID;
1597- break;
1598-
1599- case RBE_ELEC:
1600- pt = GF_ELEC;
1601- break;
1602-
1603- case RBE_FIRE:
1604- pt = GF_FIRE;
1605- break;
1606-
1607- case RBE_COLD:
1608- pt = GF_COLD;
1609- break;
1610-
1611- case RBE_CONFUSE:
1612- pt = GF_CONFUSION;
1613- break;
1614-
1615- case RBE_TERRIFY:
1616- effect_type = BLOW_EFFECT_TYPE_FEAR;
1617- break;
1618-
1619- case RBE_PARALYZE:
1620- effect_type = BLOW_EFFECT_TYPE_SLEEP;
1621- break;
1622-
1623- case RBE_SHATTER:
1624- damage -= (damage * ((ac < 150) ? ac : 150) / 250);
1625- if (damage > 23) earthquake(m_ptr->fy, m_ptr->fx, 8, m_idx);
1626- break;
1627-
1628- case RBE_EXP_10:
1629- case RBE_EXP_20:
1630- case RBE_EXP_40:
1631- case RBE_EXP_80:
1632- pt = GF_NETHER;
1633- break;
1634-
1635- case RBE_TIME:
1636- pt = GF_TIME;
1637- break;
1638-
1639- case RBE_DR_LIFE:
1640- pt = GF_HYPODYNAMIA;
1641- effect_type = BLOW_EFFECT_TYPE_HEAL;
1642- break;
1643-
1644- case RBE_INERTIA:
1645- pt = GF_INERTIAL;
1646- break;
1647-
1648- case RBE_STUN:
1649- pt = GF_SOUND;
1650- break;
1651-
1652- default:
1653- pt = 0;
1654- break;
1655- }
1656-
1657- if (pt)
1658- {
1659- /* Do damage if not exploding */
1660- if (!explode)
1661- {
1662- project(m_idx, 0, t_ptr->fy, t_ptr->fx,
1663- damage, pt, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
1664- }
1665-
1666- switch (effect_type)
1667- {
1668- case BLOW_EFFECT_TYPE_FEAR:
1669- project(m_idx, 0, t_ptr->fy, t_ptr->fx,
1670- damage, GF_TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
1671- break;
1672-
1673- case BLOW_EFFECT_TYPE_SLEEP:
1674- project(m_idx, 0, t_ptr->fy, t_ptr->fx,
1675- r_ptr->level, GF_OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
1676- break;
1677-
1678- case BLOW_EFFECT_TYPE_HEAL:
1679- if ((monster_living(m_idx)) && (damage > 2))
1680- {
1681- bool did_heal = FALSE;
1682-
1683- if (m_ptr->hp < m_ptr->maxhp) did_heal = TRUE;
1684-
1685- /* Heal */
1686- m_ptr->hp += damroll(4, damage / 6);
1687- if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
1688-
1689- /* Redraw (later) if needed */
1690- if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
1691- if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
1692-
1693- /* Special message */
1694- if (see_m && did_heal)
1695- {
1696- msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
1697- }
1698- }
1699- break;
1700- }
1701-
1702- if (touched)
1703- {
1704- /* Aura fire */
1705- if ((tr_ptr->flags2 & RF2_AURA_FIRE) && m_ptr->r_idx)
1706- {
1707- if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK))
1708- {
1709- if (see_either)
1710- {
1711- msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
1712- }
1713- if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_FIRE;
1714- project(t_idx, 0, m_ptr->fy, m_ptr->fx,
1715- damroll (1 + ((tr_ptr->level) / 26),
1716- 1 + ((tr_ptr->level) / 17)),
1717- GF_FIRE, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
1718- }
1719- else
1720- {
1721- if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
1722- }
1723- }
1724-
1725- /* Aura cold */
1726- if ((tr_ptr->flags3 & RF3_AURA_COLD) && m_ptr->r_idx)
1727- {
1728- if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK))
1729- {
1730- if (see_either)
1731- {
1732- msg_format(_("%^sは突然寒くなった!", "%^s is suddenly very cold!"), m_name);
1733- }
1734- if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags3 |= RF3_AURA_COLD;
1735- project(t_idx, 0, m_ptr->fy, m_ptr->fx,
1736- damroll (1 + ((tr_ptr->level) / 26),
1737- 1 + ((tr_ptr->level) / 17)),
1738- GF_COLD, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
1739- }
1740- else
1741- {
1742- if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
1743- }
1744- }
1745-
1746- /* Aura elec */
1747- if ((tr_ptr->flags2 & RF2_AURA_ELEC) && m_ptr->r_idx)
1748- {
1749- if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK))
1750- {
1751- if (see_either)
1752- {
1753- msg_format(_("%^sは電撃を食らった!", "%^s gets zapped!"), m_name);
1754- }
1755- if (m_ptr->ml && is_original_ap_and_seen(t_ptr)) tr_ptr->r_flags2 |= RF2_AURA_ELEC;
1756- project(t_idx, 0, m_ptr->fy, m_ptr->fx,
1757- damroll (1 + ((tr_ptr->level) / 26),
1758- 1 + ((tr_ptr->level) / 17)),
1759- GF_ELEC, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED, -1);
1760- }
1761- else
1762- {
1763- if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
1764- }
1765- }
1766- }
1767- }
1768- }
1769-
1770- /* Monster missed player */
1771- else
1772- {
1773- /* Analyze failed attacks */
1774- switch (method)
1775- {
1776- case RBM_HIT:
1777- case RBM_TOUCH:
1778- case RBM_PUNCH:
1779- case RBM_KICK:
1780- case RBM_CLAW:
1781- case RBM_BITE:
1782- case RBM_STING:
1783- case RBM_SLASH:
1784- case RBM_BUTT:
1785- case RBM_CRUSH:
1786- case RBM_ENGULF:
1787- case RBM_CHARGE:
1788- {
1789- (void)set_monster_csleep(t_idx, 0);
1790-
1791- /* Visible monsters */
1792- if (see_m)
1793- {
1794-#ifdef JP
1795- msg_format("%sは%^sの攻撃をかわした。", t_name, m_name);
1796-#else
1797- msg_format("%^s misses %s.", m_name, t_name);
1798-#endif
1799- }
1800-
1801- break;
1802- }
1803- }
1804- }
1805-
1806-
1807- /* Analyze "visible" monsters only */
1808- if (is_original_ap_and_seen(m_ptr) && !do_silly_attack)
1809- {
1810- /* Count "obvious" attacks (and ones that cause damage) */
1811- if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10))
1812- {
1813- /* Count attacks of this type */
1814- if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR)
1815- {
1816- r_ptr->r_blows[ap_cnt]++;
1817- }
1818- }
1819- }
1820- }
1821-
1822- if (explode)
1823- {
1824- sound(SOUND_EXPLODE);
1825-
1826- /* Cancel Invulnerability */
1827- (void)set_monster_invulner(m_idx, 0, FALSE);
1828- mon_take_hit_mon(m_idx, m_ptr->hp + 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
1829- blinked = FALSE;
1830- }
1831-
1832- /* Blink away */
1833- if (blinked && m_ptr->r_idx)
1834- {
1835- if (teleport_barrier(m_idx))
1836- {
1837- if (see_m)
1838- {
1839- msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But magic barrier obstructs it."));
1840- }
1841- else if (known)
1842- {
1843- current_floor_ptr->monster_noise = TRUE;
1844- }
1845- }
1846- else
1847- {
1848- if (see_m)
1849- {
1850- msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
1851- }
1852- else if (known)
1853- {
1854- current_floor_ptr->monster_noise = TRUE;
1855- }
1856-
1857- teleport_away(m_idx, MAX_SIGHT * 2 + 5, 0L);
1858- }
1859- }
1860-
1861- return TRUE;
1862-}
1863-
1864-
18651205 static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr)
18661206 {
18671207 return !have_flag(f_ptr->flags, FF_GLASS) ||
Show on old repository browser