Одержимость: удар по ЛКМ не съедается реакцией на попадание и недоигранным замахом

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-15 22:39:53 +03:00
co-authored by Claude Opus 5.5
parent 211f0407e2
commit 1f9e62e038
3 changed files with 53 additions and 2 deletions
+53 -2
View File
@@ -900,7 +900,7 @@ namespace NecromancerTome
{ {
PossessionPowers.BreakInvis(z, "удар"); PossessionPowers.BreakInvis(z, "удар");
z.SetLookPosition(MeleeAim(world, z)); z.SetLookPosition(MeleeAim(world, z));
if (z.Attack(false)) if (StartStrike(z))
{ {
z.Attack(true); z.Attack(true);
if (IsPet && BearControl.Is(z)) if (IsPet && BearControl.Is(z))
@@ -2308,6 +2308,28 @@ namespace NecromancerTome
/// цель - его, взгляд - на прицел (MeleeAim).</summary> /// цель - его, взгляд - на прицел (MeleeAim).</summary>
public static bool ForceImpact; public static bool ForceImpact;
/// <summary>Идёт замах по нажатию игрока (StartStrike) - патчи ниже снимают с одержимого запреты на удар.</summary>
public static bool Striking;
/// <summary>Начало удара одержимого по ЛКМ. Стрим 15.10: удар рук «иногда не проходил», когда противник подходил
/// вплотную (в логе - «зомби не может бить сейчас»). Причина в игре: EntityAlive.IsAttackValid запрещает удар, пока
/// идёт анимация попадания по самому зомби или аниматор ставит preventAttack, а UseHoldingItem - пока доигрывает
/// прошлый замах. Для ИИ это пауза после пропущенного удара, для игрока - съеденный клик. На время этого вызова
/// запреты сняты (Patch_EntityAlive_IsAttackValid_Possession, Patch_AvatarZombieController_IsAnimationAttackPlaying_Possession);
/// остаются смерть, оглушение «на колени»/«лёжа» и удар током. Частоту ударов держит _nextAttack.</summary>
static bool StartStrike(EntityAlive _z)
{
Striking = true;
try
{
return _z.Attack(false);
}
finally
{
Striking = false;
}
}
public static void FpImpact() public static void FpImpact()
{ {
EntityAlive z = Zombie; EntityAlive z = Zombie;
@@ -2317,7 +2339,7 @@ namespace NecromancerTome
} }
z.SetLookPosition(MeleeAim(z.world, z)); z.SetLookPosition(MeleeAim(z.world, z));
_meleeLookUntil = Time.time + 0.6f; _meleeLookUntil = Time.time + 0.6f;
if (!z.Attack(false)) if (!StartStrike(z))
{ {
Debug.Log("[NecromancerTome] Possession: удар рук - зомби не может бить сейчас"); Debug.Log("[NecromancerTome] Possession: удар рук - зомби не может бить сейчас");
return; return;
@@ -2464,6 +2486,35 @@ namespace NecromancerTome
public static bool Prefix() => !Possession.Active; public static bool Prefix() => !Possession.Active;
} }
/// <summary>Удар одержимого по ЛКМ не съедается реакцией на попадание (стрим 15.10, см. Possession.StartStrike).</summary>
[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;
}
}
/// <summary>И не ждёт конца прошлого замаха (там же).</summary>
[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;
}
}
}
/// <summary>Одержимый зомби без своего ИИ: шаги ИИ, путь и moveHelper не идут, движение задаём мы.</summary> /// <summary>Одержимый зомби без своего ИИ: шаги ИИ, путь и moveHelper не идут, движение задаём мы.</summary>
[HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.updateTasks))] [HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.updateTasks))]
public static class Patch_EntityAlive_updateTasks_Possession public static class Patch_EntityAlive_updateTasks_Possession
Binary file not shown.
Binary file not shown.