diff --git a/HarmonySrc/Possession.cs b/HarmonySrc/Possession.cs index 630d10d..c78bd54 100644 --- a/HarmonySrc/Possession.cs +++ b/HarmonySrc/Possession.cs @@ -168,6 +168,12 @@ namespace NecromancerTome /// Ctrl в игре - приседание переключателем (ToggleCrouch), C - пока держишь (Crouch). static bool _crouchToggled; public const float CrouchHeight = 0.6f; + /// Потолок роста пригнувшегося (тест 13.10: «зомби в приседе не проходят в 1 блок»): 0.6 роста - это + /// ~1.08 м, больше блока. Игра под низким потолком сжимает до высоты проёма минус 0.21 - под блок ~0.8 м. + public const float CrouchMaxHeight = 0.7f; + /// Куда идёт одержимый (по земле), иначе ноль - для выправления движения анимации + /// (Patch_EntityAlive_MoveEntityHeaded_Possession). + public static Vector3 MoveDir; /// Сколько чанков держать вокруг тела, пока игрок в зомби (указание 03.10: «сильно ограничить /// видимость у тела - ему вообще нет смысла что-либо видеть»). Тест 03.10: две полные области обзора /// (тело + одержимый) - память росла с каждым шагом зомби, а выход давал подвисание ~50 с. Трёх чанков @@ -349,6 +355,7 @@ namespace NecromancerTome Flying = false; BodyDanger = false; Crouching = false; + MoveDir = Vector3.zero; _meleeLookUntil = 0f; _crouchToggled = false; EntityAlive z = Zombie; @@ -682,6 +689,7 @@ namespace NecromancerTome _bodyYaw = Mathf.MoveTowardsAngle(_bodyYaw, wantYaw, TurnSpeed * Time.deltaTime); z.SetRotation(new Vector3(0f, _bodyYaw, 0f)); z.rotation.x = -_pitch; // наклон головы - для луча удара + MoveDir = moving ? Quaternion.Euler(0f, _bodyYaw, 0f) * Vector3.forward : Vector3.zero; if (moving) { // Бег - ночная скорость ярости (moveSpeedAggroMax) в любое время: днём GetMoveSpeedAggro отдаёт @@ -2386,6 +2394,26 @@ namespace NecromancerTome /// опускает его под низким потолком (EntityAlive.CrouchHeightFixedUpdate, её же шаги). Отпустил - дальше /// считает игра: встаёт, только если сверху свободно. Сама игра пригибает лишь под потолком над головой, /// а проём впереди чует через moveHelper, который у одержимого остановлен. + /// Движение анимации - туда, куда идёт одержимый (тест 13.10: «паук не может бежать вперёд, его сносит + /// влево»). У зомби с RootMotion (паук) шаг задаёт сама анимация, а у бега паука в ней уклон вбок; в игре его + /// каждый тик выправляет EntityMoveHelper - MakeMotionMoveToward к цели, скорость анимации та же. У одержимого + /// moveHelper стоит, поэтому то же самое делаем здесь, прямо перед тем, как MoveEntityHeaded превратит + /// накопленное движение анимации в шаг. + [HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.MoveEntityHeaded))] + public static class Patch_EntityAlive_MoveEntityHeaded_Possession + { + public static void Prefix(EntityAlive __instance) + { + Vector3 d = Possession.MoveDir; + if (d == Vector3.zero || !__instance.RootMotion || !Possession.IsPossessed(__instance) || __instance.Jumping) + { + return; + } + // Длина 10 - больше любого шага: MakeMotionMoveToward укоротит направление до длины движения анимации. + __instance.MakeMotionMoveToward(d.x * 10f, d.z * 10f, 0.02f, 1f); + } + } + [HarmonyPatch(typeof(EntityAlive), nameof(EntityAlive.CrouchHeightFixedUpdate))] public static class Patch_EntityAlive_CrouchHeightFixedUpdate_Possession { @@ -2396,7 +2424,8 @@ namespace NecromancerTome { return true; } - float h = Utils.FastMoveTowards(__instance.physicsHeight, __instance.physicsBaseHeight * Possession.CrouchHeight, 0.099999994f); + float target = Mathf.Min(__instance.physicsBaseHeight * Possession.CrouchHeight, Possession.CrouchMaxHeight); + float h = Utils.FastMoveTowards(__instance.physicsHeight, target, 0.099999994f); __instance.SetHeight(h); if (h <= __instance.physicsBaseHeight * 0.7f) { diff --git a/NecromancerHarmony.dll b/NecromancerHarmony.dll index bb2771c..81b2746 100644 Binary files a/NecromancerHarmony.dll and b/NecromancerHarmony.dll differ diff --git a/NecromancerHarmony.pdb b/NecromancerHarmony.pdb index 00bd353..f464227 100644 Binary files a/NecromancerHarmony.pdb and b/NecromancerHarmony.pdb differ