diff --git a/HarmonySrc/Possession.cs b/HarmonySrc/Possession.cs index 061e52e..49fe1e8 100644 --- a/HarmonySrc/Possession.cs +++ b/HarmonySrc/Possession.cs @@ -900,7 +900,7 @@ namespace NecromancerTome { PossessionPowers.BreakInvis(z, "удар"); z.SetLookPosition(MeleeAim(world, z)); - if (z.Attack(false)) + if (StartStrike(z)) { z.Attack(true); if (IsPet && BearControl.Is(z)) @@ -2308,6 +2308,28 @@ namespace NecromancerTome /// цель - его, взгляд - на прицел (MeleeAim). public static bool ForceImpact; + /// Идёт замах по нажатию игрока (StartStrike) - патчи ниже снимают с одержимого запреты на удар. + public static bool Striking; + + /// Начало удара одержимого по ЛКМ. Стрим 15.10: удар рук «иногда не проходил», когда противник подходил + /// вплотную (в логе - «зомби не может бить сейчас»). Причина в игре: EntityAlive.IsAttackValid запрещает удар, пока + /// идёт анимация попадания по самому зомби или аниматор ставит preventAttack, а UseHoldingItem - пока доигрывает + /// прошлый замах. Для ИИ это пауза после пропущенного удара, для игрока - съеденный клик. На время этого вызова + /// запреты сняты (Patch_EntityAlive_IsAttackValid_Possession, Patch_AvatarZombieController_IsAnimationAttackPlaying_Possession); + /// остаются смерть, оглушение «на колени»/«лёжа» и удар током. Частоту ударов держит _nextAttack. + static bool StartStrike(EntityAlive _z) + { + Striking = true; + try + { + return _z.Attack(false); + } + finally + { + Striking = false; + } + } + public static void FpImpact() { EntityAlive z = Zombie; @@ -2317,7 +2339,7 @@ namespace NecromancerTome } z.SetLookPosition(MeleeAim(z.world, z)); _meleeLookUntil = Time.time + 0.6f; - if (!z.Attack(false)) + if (!StartStrike(z)) { Debug.Log("[NecromancerTome] Possession: удар рук - зомби не может бить сейчас"); return; @@ -2464,6 +2486,35 @@ namespace NecromancerTome public static bool Prefix() => !Possession.Active; } + /// Удар одержимого по ЛКМ не съедается реакцией на попадание (стрим 15.10, см. Possession.StartStrike). + [HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.IsAttackValid))] + public static class Patch_EntityAlive_IsAttackValid_Possession + { + public static void Postfix(EntityAlive __instance, ref bool __result) + { + if (__result || !Possession.Striking || __instance != Possession.Zombie || __instance.IsDead() || __instance.Electrocuted) + { + return; + } + EnumEntityStunType stun = __instance.bodyDamage.CurrentStun; + __result = stun != EnumEntityStunType.Kneel && stun != EnumEntityStunType.Prone; + } + } + + /// И не ждёт конца прошлого замаха (там же). + [HarmonyPatch(typeof(AvatarZombieController), nameof(AvatarZombieController.IsAnimationAttackPlaying))] + public static class Patch_AvatarZombieController_IsAnimationAttackPlaying_Possession + { + public static void Postfix(AvatarZombieController __instance, ref bool __result) + { + if (__result && Possession.Striking && Possession.Zombie != null && Possession.Zombie.emodel != null && + Possession.Zombie.emodel.avatarController == __instance) + { + __result = false; + } + } + } + /// Одержимый зомби без своего ИИ: шаги ИИ, путь и moveHelper не идут, движение задаём мы. [HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.updateTasks))] public static class Patch_EntityAlive_updateTasks_Possession diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index eaf4e2e..68da51d 100644 Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb index 2173f58..d17627b 100644 Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ