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