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

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, "удар");
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).</summary>
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()
{
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;
}
/// <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>
[HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.updateTasks))]
public static class Patch_EntityAlive_updateTasks_Possession
Binary file not shown.
Binary file not shown.