using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using KeybindLib.Classes; using Newtonsoft.Json; using Photon.Pun; using REPOLib.Modules; using REPOLib.Objects.Sdk; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SemiKick")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SemiKick")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f6f7da04-f36c-4ac4-a3dc-28fbe347a753")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [Serializable] public class AnimationData { public float duration; public List frames; } [Serializable] public class FrameData { public float time; public Dictionary bones; } [Serializable] public struct BoneRotation { public float x; public float y; public float z; public float w; public Quaternion ToQuaternion() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(x, y, z, w); } } public struct RuntimeFrame { public float time; public Quaternion[] rotations; } public class KickAnimationPlayer : MonoBehaviour { private static readonly Dictionary BoneMap = new Dictionary { { "Bone", "ANIM BODY BOT" }, { "Bone.003", "ANIM HEAD BOT" }, { "Bone.004", "Player Spring Impulse - Leg Right" }, { "Bone.005", "Player Spring Impulse - Leg Left" }, { "Bone.006", "Player Spring Impulse - Arm Left" }, { "Bone.007", "Player Spring Impulse - Arm Right" } }; private Transform[] boneTransforms; private string[] blenderBoneNames; private Quaternion[] initialLocalRotations; private int rightLegBoneIndex = -1; private Vector3? stretchTargetWorldPos; private float currentStretchFactor = 1f; private RuntimeFrame[] runtimeFrames; private float totalDuration; private bool isReady; private bool isPlaying; [SerializeField] private float returnToRestDuration = 0.15f; private Coroutine returnToRestCoroutine; private RuntimeFrame currentFrameA; private RuntimeFrame currentFrameB; private float currentT; private bool hasFrameToApply; private bool _loggedFirstApply; private bool _loggedNullBoneWarning; private static string LoadTextFromEmbeddedResource(string resourceFileName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(resourceFileName, StringComparison.OrdinalIgnoreCase)); if (text == null) { Debug.LogError((object)("[JSONAnimation] Embedded resource '" + resourceFileName + "' не найден. Доступные ресурсы: " + string.Join(", ", executingAssembly.GetManifestResourceNames()))); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { Debug.LogError((object)("[JSONAnimation] GetManifestResourceStream вернул null для '" + text + "'.")); return null; } using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } public void Initialize(string jsonPath, Transform rigRoot) { Debug.Log((object)("[JSONAnimation] Initialize вызван: jsonPath=" + jsonPath + ", rigRoot=" + (((Object)(object)rigRoot != (Object)null) ? ((Object)rigRoot).name : "NULL"))); bool flag = File.Exists(jsonPath); Debug.Log((object)$"[JSONAnimation] Проверка файла анимации: fileExists={flag}, path={jsonPath}"); string text = (flag ? File.ReadAllText(jsonPath) : null); InitializeInternal(text, rigRoot, flag, "Файл kick_animation.json не найден по указанному пути. "); } public void InitializeFromJsonText(string jsonText, Transform rigRoot) { Debug.Log((object)string.Format("[JSONAnimation] Initialize (embedded) вызван: jsonText.Length={0}, rigRoot={1}", jsonText?.Length ?? (-1), ((Object)(object)rigRoot != (Object)null) ? ((Object)rigRoot).name : "NULL")); InitializeInternal(jsonText, rigRoot, !string.IsNullOrEmpty(jsonText), "JSON-текст из embedded resource пуст или не был найден (см. лог LoadTextFromEmbeddedResource выше). "); } public void InitializeFromEmbeddedResource(string resourceFileName, Transform rigRoot) { string jsonText = LoadTextFromEmbeddedResource(resourceFileName); InitializeFromJsonText(jsonText, rigRoot); } private void InitializeInternal(string text, Transform rigRoot, bool hasSource, string missingSourceReason) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); foreach (KeyValuePair item in BoneMap) { Transform val = FindDeepChild(rigRoot, item.Value); if ((Object)(object)val != (Object)null) { list.Add(val); list2.Add(item.Key); Debug.Log((object)("[JSONAnimation] Привязана кость: blenderName=" + item.Key + " -> unityName='" + item.Value + "', path=" + GetHierarchyPath(val))); } else { Debug.LogWarning((object)("[JSONAnimation] НЕ найдена кость: blenderName=" + item.Key + ", ожидалось имя в Unity='" + item.Value + "' (FindDeepChild не нашёл такого объекта под " + (((Object)(object)rigRoot != (Object)null) ? ((Object)rigRoot).name : "NULL") + ").")); } } boneTransforms = list.ToArray(); blenderBoneNames = list2.ToArray(); int num = boneTransforms.Length; Debug.Log((object)$"[JSONAnimation] Итог поиска костей: найдено {num}/{BoneMap.Count}."); initialLocalRotations = (Quaternion[])(object)new Quaternion[num]; for (int i = 0; i < num; i++) { initialLocalRotations[i] = boneTransforms[i].localRotation; } rightLegBoneIndex = Array.IndexOf(blenderBoneNames, "Bone.004"); if (rightLegBoneIndex < 0) { Debug.LogWarning((object)"[JSONAnimation] Кость правой ноги (Bone.004 / 'Player Spring Impulse - Leg Right') не найдена в рантайм-иерархии — стретч ноги работать не будет для этого аватара."); } if (hasSource && num > 0) { Debug.Log((object)$"[JSONAnimation] JSON получен, длина текста={text.Length} символов. Десериализую..."); AnimationData animationData = JsonConvert.DeserializeObject(text); if (animationData == null) { Debug.LogError((object)"[JSONAnimation] JsonConvert.DeserializeObject вернул NULL — файл битый или не соответствует структуре AnimationData. Анимация не будет готова."); return; } if (animationData.frames == null || animationData.frames.Count == 0) { Debug.LogError((object)$"[JSONAnimation] rawData.frames пуст или NULL (duration={animationData.duration}). Анимация не будет готова."); return; } totalDuration = animationData.duration; runtimeFrames = new RuntimeFrame[animationData.frames.Count]; Debug.Log((object)$"[JSONAnimation] Десериализация ок: duration={totalDuration}, framesCount={animationData.frames.Count}. Пересобираю в RuntimeFrame..."); int num2 = 0; for (int j = 0; j < animationData.frames.Count; j++) { FrameData frameData = animationData.frames[j]; runtimeFrames[j].time = frameData.time; runtimeFrames[j].rotations = (Quaternion[])(object)new Quaternion[num]; for (int k = 0; k < num; k++) { string key = blenderBoneNames[k]; if (frameData.bones != null && frameData.bones.TryGetValue(key, out var value)) { runtimeFrames[j].rotations[k] = value.ToQuaternion(); continue; } runtimeFrames[j].rotations[k] = boneTransforms[k].localRotation; num2++; } } if (num2 > 0) { Debug.LogWarning((object)$"[JSONAnimation] В {num2} случаях (кадр x кость) в JSON не было данных для найденной кости — использован текущий localRotation как фоллбэк. Если это не задумано, проверьте имена костей в Blender-экспорте."); } isReady = true; Debug.Log((object)$"[JSONAnimation] Initialize завершён успешно: isReady=true, totalDuration={totalDuration}, framesCount={runtimeFrames.Length}, boneCount={num}."); } else { Debug.LogWarning((object)($"[JSONAnimation] Initialize НЕ завершился (isReady останется false): hasSource={hasSource}, actualBoneCount={num}. " + ((!hasSource) ? missingSourceReason : "") + ((num == 0) ? "Ни одна кость из BoneMap не найдена в rigRoot — проверьте иерархию/имена." : ""))); } } private static string GetHierarchyPath(Transform t) { if ((Object)(object)t == (Object)null) { return "NULL"; } string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private IEnumerator RunKick() { if (returnToRestCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(returnToRestCoroutine); returnToRestCoroutine = null; } isPlaying = true; float startTime = Time.time; int currentFrameIndex = 0; int frameCount = runtimeFrames.Length; int loggedFrameIndex = -1; object[] obj = new object[4] { startTime, totalDuration, frameCount, null }; Transform[] array = boneTransforms; obj[3] = ((array != null) ? array.Length : 0); Debug.Log((object)string.Format("[JSONAnimation] RunKick стартовал: startTime={0}, totalDuration={1}, frameCount={2}, boneCount={3}.", obj)); while (Time.time - startTime < totalDuration) { float num; for (num = Time.time - startTime; currentFrameIndex < frameCount - 1 && runtimeFrames[currentFrameIndex + 1].time <= num; currentFrameIndex++) { } if (currentFrameIndex != loggedFrameIndex) { Debug.Log((object)$"[JSONAnimation] RunKick: переход на кадр {currentFrameIndex}/{frameCount - 1} (time={runtimeFrames[currentFrameIndex].time}, elapsed={num:F3})."); loggedFrameIndex = currentFrameIndex; } currentFrameA = runtimeFrames[currentFrameIndex]; currentFrameB = runtimeFrames[Mathf.Min(currentFrameIndex + 1, frameCount - 1)]; currentT = Mathf.InverseLerp(currentFrameA.time, currentFrameB.time, num); hasFrameToApply = true; yield return null; } isPlaying = false; hasFrameToApply = false; stretchTargetWorldPos = null; currentStretchFactor = 1f; if (rightLegBoneIndex >= 0 && rightLegBoneIndex < boneTransforms.Length && (Object)(object)boneTransforms[rightLegBoneIndex] != (Object)null) { boneTransforms[rightLegBoneIndex].localScale = Vector3.one; } if (returnToRestCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(returnToRestCoroutine); } returnToRestCoroutine = ((MonoBehaviour)this).StartCoroutine(ReturnToRestPose()); Debug.Log((object)$"[JSONAnimation] RunKick завершён: реальная длительность={Time.time - startTime:F3} (ожидалось totalDuration={totalDuration}), запущен плавный возврат костей в стартовую позу за {returnToRestDuration:F3}с."); } private IEnumerator ReturnToRestPose() { if (initialLocalRotations == null || boneTransforms == null) { yield break; } int count = boneTransforms.Length; Quaternion[] fromRotations = (Quaternion[])(object)new Quaternion[count]; for (int i = 0; i < count; i++) { if ((Object)(object)boneTransforms[i] != (Object)null) { fromRotations[i] = boneTransforms[i].localRotation; } } if (returnToRestDuration <= 0f) { for (int j = 0; j < count; j++) { if ((Object)(object)boneTransforms[j] != (Object)null && j < initialLocalRotations.Length) { boneTransforms[j].localRotation = initialLocalRotations[j]; } } returnToRestCoroutine = null; yield break; } float elapsed = 0f; while (elapsed < returnToRestDuration) { elapsed += Time.deltaTime; float num = Mathf.Clamp01(elapsed / returnToRestDuration); for (int k = 0; k < count; k++) { if ((Object)(object)boneTransforms[k] != (Object)null && k < initialLocalRotations.Length) { boneTransforms[k].localRotation = Quaternion.Slerp(fromRotations[k], initialLocalRotations[k], num); } } yield return null; } for (int l = 0; l < count; l++) { if ((Object)(object)boneTransforms[l] != (Object)null && l < initialLocalRotations.Length) { boneTransforms[l].localRotation = initialLocalRotations[l]; } } returnToRestCoroutine = null; } private void LateUpdate() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (!hasFrameToApply) { _loggedFirstApply = false; return; } if (!_loggedFirstApply) { Debug.Log((object)$"[JSONAnimation] LateUpdate: начал применять ротации к {boneTransforms.Length} костям."); _loggedFirstApply = true; } for (int i = 0; i < boneTransforms.Length; i++) { if ((Object)(object)boneTransforms[i] == (Object)null) { if (!_loggedNullBoneWarning) { Debug.LogWarning((object)$"[JSONAnimation] LateUpdate: boneTransforms[{i}] == NULL (кость уничтожена/недоступна?), пропускаю. Дальнейшие такие предупреждения на этот проигрыш подавлены."); _loggedNullBoneWarning = true; } } else { boneTransforms[i].localRotation = Quaternion.Slerp(currentFrameA.rotations[i], currentFrameB.rotations[i], currentT); } } if (rightLegBoneIndex >= 0 && rightLegBoneIndex < boneTransforms.Length && (Object)(object)boneTransforms[rightLegBoneIndex] != (Object)null) { ApplyLegStretch(boneTransforms[rightLegBoneIndex]); } } private void ApplyLegStretch(Transform legBone) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) float num = 1f; if (stretchTargetWorldPos.HasValue) { float num2 = Vector3.Distance(legBone.position, stretchTargetWorldPos.Value); float num3 = 0.5f; if (num3 > 0f && num2 > num3) { num = Mathf.Clamp(num2 / num3, 1f, 1.8f); } } currentStretchFactor = Mathf.Lerp(currentStretchFactor, num, Time.deltaTime * 8f); Vector3 one = Vector3.one; one.y = currentStretchFactor; legBone.localScale = one; } private Transform FindDeepChild(Transform parent, string targetName) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (((Object)parent).name == targetName) { return parent; } foreach (Transform item in parent) { Transform parent2 = item; Transform val = FindDeepChild(parent2, targetName); if ((Object)(object)val != (Object)null) { return val; } } return null; } public void PlayKick(Vector3? targetWorldPoint = null) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)string.Format("[JSONAnimation] PlayKick вызван: isReady={0}, isPlaying={1}, gameObject={2}, targetWorldPoint={3}.", isReady, isPlaying, ((Object)this).name, targetWorldPoint.HasValue ? ((object)targetWorldPoint.Value/*cast due to .constrained prefix*/).ToString() : "NULL")); if (!isReady) { Debug.LogWarning((object)"[JSONAnimation] PlayKick: isReady=false, анимация не запущена (Initialize не завершился успешно — см. логи выше)."); return; } if (isPlaying) { Debug.LogWarning((object)"[JSONAnimation] PlayKick: анимация уже проигрывается (isPlaying=true), повторный запуск пропущен."); return; } stretchTargetWorldPos = targetWorldPoint; currentStretchFactor = 1f; ((MonoBehaviour)this).StartCoroutine(RunKick()); } } namespace SemiKick; internal class EnemyKickReceiver : MonoBehaviour { private const float KickStunDuration = 1f; private Enemy _enemy; private EnemyRigidbody _enemyRigidbody; private EnemyStateStunned _stateStunned; private void Awake() { _enemy = ((Component)this).GetComponent(); _stateStunned = InternalAccessors.GetEnemyStateStunned(_enemy); _enemyRigidbody = (((Object)(object)((Component)this).transform.parent != (Object)null) ? ((Component)((Component)this).transform.parent).GetComponentInChildren() : ((Component)this).GetComponentInChildren()); if ((Object)(object)_enemyRigidbody == (Object)null) { SemiKick.LogWarning("[SemiKick] EnemyKickReceiver на " + ((Object)this).name + ": не нашёл EnemyRigidbody у сиблингов родителя."); } if ((Object)(object)_stateStunned == (Object)null) { SemiKick.LogWarning("[SemiKick] EnemyKickReceiver на " + ((Object)this).name + ": не нашёл StateStunned — нокбэк будет гаситься AI на следующем кадре."); } SemiKick.LogInfo($"[SemiKick] EnemyKickReceiver.Awake на {((Object)this).name}: enemyRigidbody={(Object)(object)_enemyRigidbody != (Object)null}, stateStunned={(Object)(object)_stateStunned != (Object)null}"); } public float GetMass() { if ((Object)(object)_enemyRigidbody == (Object)null) { SemiKick.LogWarning("[SemiKick] EnemyKickReceiver.GetMass на " + ((Object)this).name + ": _enemyRigidbody == null, возвращаю 0."); return 0f; } Rigidbody enemyRigidbody = InternalAccessors.GetEnemyRigidbody(_enemyRigidbody); float num = (((Object)(object)enemyRigidbody != (Object)null) ? enemyRigidbody.mass : 0f); SemiKick.LogInfo($"[SemiKick] EnemyKickReceiver.GetMass на {((Object)this).name}: rb={(Object)(object)enemyRigidbody != (Object)null}, mass={num}"); return num; } public void SendKick(Vector3 force) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) SemiKick.LogInfo($"[SemiKick] EnemyKickReceiver.SendKick на {((Object)this).name}: force={force}, magnitude={((Vector3)(ref force)).magnitude}, Multiplayer={GameManager.Multiplayer()}"); if (!GameManager.Multiplayer()) { ReceiveKickRPC(force); return; } PhotonView enemyPhotonView = InternalAccessors.GetEnemyPhotonView(_enemy); if ((Object)(object)enemyPhotonView == (Object)null) { SemiKick.LogWarning("[SemiKick] EnemyKickReceiver.SendKick на " + ((Object)this).name + ": photonView == null, RPC не отправлен."); return; } enemyPhotonView.RPC("ReceiveKickRPC", (RpcTarget)0, new object[1] { force }); } [PunRPC] public void ReceiveKickRPC(Vector3 force, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) SemiKick.LogInfo($"[SemiKick] EnemyKickReceiver.ReceiveKickRPC на {((Object)this).name}: force={force}"); if ((Object)(object)_enemyRigidbody == (Object)null) { SemiKick.LogWarning("[SemiKick] EnemyKickReceiver.ReceiveKickRPC на " + ((Object)this).name + ": _enemyRigidbody == null, импульс не применён."); return; } EnemyStateStunned stateStunned = _stateStunned; if (stateStunned != null) { stateStunned.Set(1f); } _enemyRigidbody.FreezeForces(force, Vector3.zero); } } [HarmonyPatch(typeof(Enemy), "Awake")] internal static class EnemyKickReceiverPatch { [HarmonyPostfix] private static void Postfix(Enemy __instance) { if (!((Object)(object)((Component)__instance).GetComponent() != (Object)null)) { ((Component)__instance).gameObject.AddComponent(); } } } public class KickAnimHandler : MonoBehaviour { private KickAnimationPlayer _animPlayer; private PhotonView _photonView; private PlayerAvatar _avatar; private bool _isLocal; private PlayerController pc; public PlayerAvatar Avatar => _avatar; public int KickLevel { get; private set; } public void SetKickLevel(int level) { SemiKick.LogInfo($"[SemiKick] KickAnimHandler.SetKickLevel: {(((Object)(object)_avatar != (Object)null) ? ((Object)_avatar).name : ((Object)this).name)} -> level={level} (было {KickLevel})."); KickLevel = level; } public void Initialize(KickAnimationPlayer animPlayer, PlayerAvatar avatar) { GameObject val = GameObject.Find("Controller"); if ((Object)(object)val != (Object)null) { pc = val.GetComponent(); } if ((Object)(object)pc == (Object)null) { SemiKick.LogWarning("[KickAnimHandler] PlayerController не найден на сцене!"); } _animPlayer = animPlayer; _avatar = avatar; SemiKick.LogInfo("[SemiKick] KickAnimHandler.Initialize вызван, avatar=" + (((Object)(object)avatar != (Object)null) ? ((Object)avatar).name : "NULL")); SemiKick.LogInfo("[JSONAnimation] KickAnimHandler.Initialize: animPlayer передан как " + (((Object)(object)animPlayer != (Object)null) ? "не NULL" : "NULL") + "."); if ((Object)(object)avatar == (Object)null) { SemiKick.LogError("[SemiKick] KickAnimHandler.Initialize: avatar передана как NULL!"); return; } _photonView = avatar.photonView ?? ((Component)avatar).GetComponent() ?? ((Component)avatar).GetComponentInParent(); if ((Object)(object)_photonView == (Object)null) { SemiKick.LogError("[SemiKick] Не удалось найти PhotonView на объекте " + ((Object)avatar).name + "!"); return; } _isLocal = !SemiFunc.IsMultiplayer() || _photonView.IsMine; SemiKick.LogInfo($"[SemiKick] KickAnimHandler: PhotonView найден, IsMine={_photonView.IsMine}, IsMultiplayer={SemiFunc.IsMultiplayer()}, isLocal={_isLocal}, ViewID={_photonView.ViewID}"); if (_isLocal) { SemiKickRunner semiKickRunner = Object.FindObjectOfType(); if ((Object)(object)semiKickRunner != (Object)null) { semiKickRunner.SetLocalPlayer(this); SemiKick.LogInfo("[SemiKick] KickAnimHandler: локальный игрок зарегистрирован в SemiKickRunner, Avatar передан."); } else { SemiKick.LogWarning("[SemiKick] SemiKickRunner не найден на сцене! Локальный Avatar не будет доступен для knockback."); } } SemiKick.LogInfo($"[SemiKick] KickAnimHandler успешно инициализирован (Local: {_isLocal}, ViewID: {_photonView.ViewID})"); } public void PerformKick(Vector3? stretchTargetWorldPos = null) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)string.Format("[JSONAnimation] KickAnimHandler.PerformKick вызван для {0}: _animPlayer={1}, Multiplayer={2}, stretchTarget={3}.", ((Object)(object)_avatar != (Object)null) ? ((Object)_avatar).name : "NULL", ((Object)(object)_animPlayer != (Object)null) ? "не NULL" : "NULL", GameManager.Multiplayer(), stretchTargetWorldPos.HasValue ? ((object)stretchTargetWorldPos.Value/*cast due to .constrained prefix*/).ToString() : "NULL")); if ((Object)(object)_animPlayer != (Object)null) { _animPlayer.PlayKick(stretchTargetWorldPos); } else { Debug.LogWarning((object)"[JSONAnimation] KickAnimHandler.PerformKick: _animPlayer == NULL — анимация физически не может проиграться, т.к. компонент не был передан при Initialize (см. PlayerAvatarVisualsPatch)."); } if ((Object)(object)_photonView != (Object)null && GameManager.Multiplayer()) { _photonView.RPC("RPC_PlayKick", (RpcTarget)1, Array.Empty()); } } [PunRPC] public void RPC_PlayKick() { if ((Object)(object)_animPlayer != (Object)null) { _animPlayer.PlayKick(); } } private void TryForceTumble(Vector3 force) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) PlayerTumble tumbleComponent = InternalAccessors.GetTumbleComponent(_avatar); if (!((Object)(object)tumbleComponent == (Object)null)) { Vector3 val = Vector3.Lerp(((Vector3)(ref force)).normalized, Vector3.up, 0.6f); float magnitude = ((Vector3)(ref force)).magnitude; tumbleComponent.TumbleRequest(true, false); tumbleComponent.TumbleForce(val * magnitude); tumbleComponent.TumbleTorque(-((Component)_avatar).transform.right * magnitude); tumbleComponent.TumbleOverrideTime(1.5f); SemiKick.LogInfo($"[SemiKick] ГАРАНТИРОВАННЫЙ ПОЛЕТ для {((Object)_avatar).name}. Сила: {magnitude}"); } } public void RequestGenericKick(Action applyAction) { if (InternalAccessors.CanDoStuff(Avatar)) { ((MonoBehaviour)this).StartCoroutine(DelayedKickCoroutine(applyAction)); } } private IEnumerator DelayedKickCoroutine(Action applyAction) { if ((Object)(object)pc == (Object)null) { SemiKick.LogWarning("[KickAnimHandler.DelayedKickCoroutine] PlayerController не найден на сцене! Если что сейчас мод ляжет НАХУЙ, хорошо?"); } ((Behaviour)pc).enabled = false; yield return (object)new WaitForSeconds(0.5f); float duration = 0.11f; float totalKick = 49.04f; float elapsed = 0f; float lastHeight = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; float num = Mathf.Sin(Mathf.Min(1f, elapsed / duration) * (float)Math.PI * 0.5f); float num2 = totalKick * num; float num3 = num2 - lastHeight; CameraAim.Instance.AdditiveAimY(0f - num3); lastHeight = num2; yield return null; } ((Behaviour)pc).enabled = true; applyAction?.Invoke(); } public void RequestKick(Vector3 force, bool forceTumble = false) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) RequestGenericKick(delegate { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer()) { _avatar.ForceImpulse(force); if (forceTumble) { TryForceTumble(force); } } else if ((Object)(object)_photonView != (Object)null) { _photonView.RPC("RequestKickRPC", (RpcTarget)2, new object[2] { force, forceTumble }); } }); } [PunRPC] private void RequestKickRPC(Vector3 force, bool forceTumble, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) _avatar.ForceImpulse(force); if (forceTumble) { TryForceTumble(force); } } } internal static class KnockbackCalculator { public static void Apply(PlayerAvatar kicker, float targetMass, float kickForce, Vector3 kickDirection) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) SemiKick.LogInfo(string.Format("[SemiKick] KnockbackCalculator.Apply вызван: kicker={0}, targetMass={1}, kickForce={2}, direction={3}", ((Object)(object)kicker != (Object)null) ? ((Object)kicker).name : "NULL", targetMass, kickForce, kickDirection)); if ((Object)(object)kicker == (Object)null) { SemiKick.LogWarning("[SemiKick] KnockbackCalculator.Apply: kicker == null (localPlayerHandler.Avatar не был передан?), выхожу без эффекта."); return; } if (targetMass <= 0f) { SemiKick.LogWarning($"[SemiKick] KnockbackCalculator.Apply: targetMass={targetMass} <= 0, выхожу без эффекта (масса не найдена или объект и правда невесомый)."); return; } if (kickForce <= 0f) { SemiKick.LogWarning($"[SemiKick] KnockbackCalculator.Apply: kickForce={kickForce} <= 0, выхожу без эффекта."); return; } float num = targetMass / kickForce; float num2 = 0.9f; float num3 = 4f; SemiKick.LogInfo($"[SemiKick] KnockbackCalculator: resistanceRatio={num} (targetMass={targetMass} / kickForce={kickForce}), SoftThreshold={num2}, HardThreshold={num3}"); if (num <= num2) { SemiKick.LogInfo("[SemiKick] KnockbackCalculator: resistanceRatio <= SoftThreshold -> без отдачи."); return; } Vector3 val = -((Vector3)(ref kickDirection)).normalized; float num4 = targetMass * 3f; if (num > num3) { float num5 = targetMass * 3f; float num6 = Mathf.Max(num5, 20f); SemiKick.LogInfo($"[SemiKick] KnockbackCalculator: resistanceRatio > HardThreshold -> ТАМБЛ + урон. computedForce={num5}, floor={20f}, итог recoilForce={num6}, direction={val}"); PlayerTumble tumbleComponent = InternalAccessors.GetTumbleComponent(kicker); if ((Object)(object)tumbleComponent != (Object)null) { int num7 = CalculateDamage(num, num3); SemiKick.LogInfo($"[SemiKick] KnockbackCalculator: вызываю tumble.TumbleRequest(true, false) и tumble.ImpactHurtSet(window={0.5f}, damage={num7})"); tumbleComponent.TumbleRequest(true, false); tumbleComponent.ImpactHurtSet(0.5f, num7); } else { SemiKick.LogWarning("[SemiKick] KnockbackCalculator: tumble == null, тамбл/урон НЕ применены, будет только импульс."); } SemiKick.LogInfo($"[SemiKick] KnockbackCalculator: вызываю kicker.ForceImpulse({val * num6})"); kicker.ForceImpulse(val * num6); } else { float num8 = num4 * 0.3f; SemiKick.LogInfo($"[SemiKick] KnockbackCalculator: Soft < resistanceRatio <= Hard -> лёгкая отдача без тамбла. force={num8}, direction={val}"); kicker.ForceImpulse(val * num8); } } private static int CalculateDamage(float resistanceRatio, float hardThreshold) { float num = Mathf.InverseLerp(hardThreshold, hardThreshold * 2f, resistanceRatio); int num2 = Mathf.RoundToInt(Mathf.Lerp(15f, 50f, num)); SemiKick.LogInfo($"[SemiKick] KnockbackCalculator.CalculateDamage: resistanceRatio={resistanceRatio}, t={num}, damage={num2}"); return num2; } } [HarmonyPatch(typeof(PlayerAvatar), "Start")] public static class PlayerAvatar_Start_Patch { [HarmonyPostfix] public static void Postfix(PlayerAvatar __instance) { Debug.Log((object)$"[JSONAnimation] PlayerAvatar_Start_Patch.Postfix вызван для {((Object)__instance).name}, photonView={(Object)(object)__instance.photonView != (Object)null}."); if (!((Object)(object)__instance.photonView == (Object)null)) { KickAnimHandler kickAnimHandler = ((Component)__instance).gameObject.GetComponent() ?? ((Component)__instance).gameObject.AddComponent(); PlayerAvatarVisuals componentInChildren = ((Component)((Component)__instance).transform.root).GetComponentInChildren(true); Debug.Log((object)($"[JSONAnimation] transform.root.GetComponentInChildren(true) на {((Object)__instance).name} (root={((Object)((Component)__instance).transform.root).name}): найдено={(Object)(object)componentInChildren != (Object)null}" + (((Object)(object)componentInChildren != (Object)null) ? $", gameObject.activeSelf={((Component)componentInChildren).gameObject.activeSelf}, activeInHierarchy={((Component)componentInChildren).gameObject.activeInHierarchy}" : "") + ".")); KickAnimationPlayer kickAnimationPlayer = null; if ((Object)(object)componentInChildren != (Object)null) { kickAnimationPlayer = ((Component)componentInChildren).gameObject.GetComponent() ?? ((Component)componentInChildren).gameObject.AddComponent(); Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = "SemiKick.Resources.kick_animation.json"; Debug.Log((object)("[JSONAnimation] Вызываю kickPlayer.InitializeFromEmbeddedResource(jsonPath=" + text + ", rigRoot=" + ((Object)((Component)componentInChildren).transform).name + ") на объекте " + ((Object)((Component)componentInChildren).gameObject).name + ".")); kickAnimationPlayer.InitializeFromEmbeddedResource(text, ((Component)componentInChildren).transform); } else { Debug.LogWarning((object)("[JSONAnimation] PlayerAvatarVisuals НЕ найден на " + ((Object)__instance).name + " (или его детях) — kickPlayer останется NULL, анимация для этого аватара работать не будет.")); } Debug.Log((object)("[JSONAnimation] Передаю kickPlayer=" + (((Object)(object)kickAnimationPlayer != (Object)null) ? "не NULL" : "NULL") + " в KickAnimHandler.Initialize для " + ((Object)__instance).name + ".")); kickAnimHandler.Initialize(kickAnimationPlayer, __instance); } } } internal static class InternalAccessors { private static readonly FieldRef IsTumblingRef = AccessTools.FieldRefAccess("isTumbling"); private static readonly FieldRef IsCrouchingRef = AccessTools.FieldRefAccess("isCrouching"); private static readonly FieldRef IsGroundedRef = AccessTools.FieldRefAccess("isGrounded"); public static Rigidbody GetEnemyRigidbody(EnemyRigidbody enemyRb) { if ((Object)(object)enemyRb == (Object)null) { return null; } Rigidbody value = Traverse.Create((object)enemyRb).Field("rb").GetValue(); if ((Object)(object)value == (Object)null) { SemiKick.LogWarning("[SemiKick] InternalAccessors.GetEnemyRigidbody: поле 'rb' вернуло null."); } return value; } public static Enemy GetEnemyFromRigidbody(EnemyRigidbody enemyRb) { if ((Object)(object)enemyRb == (Object)null) { return null; } return Traverse.Create((object)enemyRb).Field("enemy").GetValue(); } public static Rigidbody GetPlayerRigidbody(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return null; } return Traverse.Create((object)player).Field("rb").GetValue(); } public static bool GetIsTumbling(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return false; } return Traverse.Create((object)player).Field("isTumbling").GetValue(); } public static PlayerTumble GetTumbleComponent(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { SemiKick.LogWarning("[SemiKick] InternalAccessors.GetTumbleComponent: player == null."); return null; } PlayerTumble value = Traverse.Create((object)player).Field("tumble").GetValue(); if ((Object)(object)value == (Object)null) { SemiKick.LogWarning("[SemiKick] InternalAccessors.GetTumbleComponent: поле 'tumble' вернуло null для " + ((Object)player).name + "."); return value; } SemiKick.LogInfo("[SemiKick] InternalAccessors.GetTumbleComponent: tumble найден для " + ((Object)player).name + "."); return value; } public static PhotonView GetEnemyPhotonView(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return null; } return Traverse.Create((object)enemy).Field("PhotonView").GetValue(); } public static EnemyStateStunned GetEnemyStateStunned(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return null; } return Traverse.Create((object)enemy).Field("StateStunned").GetValue(); } public static bool CanDoStuff(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return false; } bool num = IsTumblingRef.Invoke(player); bool flag = IsCrouchingRef.Invoke(player); bool flag2 = IsGroundedRef.Invoke(player); return !num && !flag && flag2; } } internal static class KickNetworking { public static void ApplyKickToPlayer(PlayerAvatar player, Vector3 force, bool forceTumble = false) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) KickAnimHandler component = ((Component)player).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { component.RequestKick(force, forceTumble); return; } SemiKick.LogWarning("[SemiKick] ApplyKickToPlayer: у " + ((Object)player).name + " нет KickAnimHandler, пинок может не сработать у гостей."); player.ForceImpulse(force); } public static void ApplyKickToValuable(PhysGrabObject physGrabObject, Vector3 force, Vector3 hitPoint) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)physGrabObject == (Object)null) && SemiFunc.IsMasterClientOrSingleplayer()) { Rigidbody rb = physGrabObject.rb; if (!((Object)(object)rb == (Object)null)) { rb.AddForceAtPosition(force, hitPoint, (ForceMode)1); } } } } internal enum KickTargetType { None, Player, Enemy, Valuable } internal struct KickTarget { public KickTargetType Type; public Rigidbody Rigidbody; public Component Component; } internal static class KickTargetClassifier { public static KickTarget ClassifyHit(Collider col) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Invalid comparison between Unknown and I4 KickTarget result = new KickTarget { Type = KickTargetType.None }; PlayerAvatar val = ((Component)col).GetComponentInParent(); if ((Object)(object)val == (Object)null) { val = ((Component)((Component)col).transform.root).GetComponentInChildren(); } if ((Object)(object)val != (Object)null) { result.Type = KickTargetType.Player; result.Component = (Component)(object)val; result.Rigidbody = InternalAccessors.GetPlayerRigidbody(val); return result; } EnemyRigidbody componentInParent = ((Component)col).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { Enemy enemyFromRigidbody = InternalAccessors.GetEnemyFromRigidbody(componentInParent); if ((Object)(object)enemyFromRigidbody != (Object)null) { if ((int)enemyFromRigidbody.CurrentState == 11) { return result; } result.Type = KickTargetType.Enemy; result.Component = (Component)(object)enemyFromRigidbody; result.Rigidbody = InternalAccessors.GetEnemyRigidbody(componentInParent); return result; } } ValuableObject componentInParent2 = ((Component)col).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null) { PhysGrabObject component = ((Component)componentInParent2).GetComponent(); if ((Object)(object)component == (Object)null) { return result; } if (component.grabbed) { return result; } result.Type = KickTargetType.Valuable; result.Component = (Component)(object)component; result.Rigidbody = component.rb; return result; } PhysGrabObject componentInParent3 = ((Component)col).GetComponentInParent(); if ((Object)(object)componentInParent3 != (Object)null) { if (componentInParent3.grabbed) { return result; } result.Type = KickTargetType.Valuable; result.Component = (Component)(object)componentInParent3; result.Rigidbody = componentInParent3.rb; return result; } return result; } } [BepInPlugin("quxxciy.semikick", "SemiKick", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SemiKick : BaseUnityPlugin { private Harmony harmony; private Keybind kickKeybind; private static bool runnerCreated; internal static ManualLogSource LoggerInstance; public const string UpgradeId = "SemiKick_KickUpgrade"; private void Awake() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown LoggerInstance = ((BaseUnityPlugin)this).Logger; kickKeybind = Keybinds.Bind("Kick", "/f"); LogInfo("SemiKick загружен, бинд зарегистрирован."); ItemContent val = LoadItemContentFromEmbeddedBundle("SemiKick.Resources.SemiKick.repobundle", "REPOLib_Item Upgrade Kick"); Item val2 = null; if ((Object)(object)val != (Object)null) { Items.RegisterItem(val); ItemAttributes component = ((Component)val.Prefab).GetComponent(); if ((Object)(object)component != (Object)null) { val2 = component.item; } else { LogError("На префабе нет компонента ItemAttributes."); } } Upgrades.RegisterUpgrade("SemiKick_KickUpgrade", val2, (Action)OnUpgradeStart, (Action)OnUpgradeApplied); harmony = new Harmony("quxxciy.semikick"); harmony.PatchAll(); SceneManager.sceneLoaded += OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (!runnerCreated) { LogInfo("Первая сцена загружена: " + ((Scene)(ref scene)).name + ", создаю Runner."); GameObject val = new GameObject("SemiKickRunner"); Object.DontDestroyOnLoad((Object)val); val.AddComponent().InitKey(kickKeybind); runnerCreated = true; SceneManager.sceneLoaded -= OnSceneLoaded; } } private ItemContent LoadItemContentFromEmbeddedBundle(string resourceFileName, string itemContentAssetName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(resourceFileName)); if (text == null) { LogError("Embedded resource '" + resourceFileName + "' не найден."); return null; } Stream? manifestResourceStream = executingAssembly.GetManifestResourceStream(text); MemoryStream memoryStream = new MemoryStream(); manifestResourceStream.CopyTo(memoryStream); manifestResourceStream.Dispose(); AssetBundle val = AssetBundle.LoadFromMemory(memoryStream.ToArray()); memoryStream.Dispose(); if ((Object)(object)val == (Object)null) { LogError("Не удалось загрузить AssetBundle из памяти."); return null; } ItemContent obj = val.LoadAsset(itemContentAssetName); if ((Object)(object)obj == (Object)null) { LogError("ItemContent '" + itemContentAssetName + "' не найден в бандле."); } return obj; } private ItemContent LoadItemContentFromFile(string bundleFileName, string itemContentAssetName) { string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), bundleFileName); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Ищу бандл по пути: " + text)); if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Файл бандла не найден по пути: " + text)); return null; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"AssetBundle.LoadFromFile вернул null — файл повреждён или не тот формат."); return null; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("AssetBundle загружен. Ассеты внутри: " + string.Join(", ", val.GetAllAssetNames()))); ItemContent obj = val.LoadAsset(itemContentAssetName); if ((Object)(object)obj == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)("ItemContent с именем '" + itemContentAssetName + "' НЕ найден в бандле.")); return obj; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"ItemContent успешно загружен!"); return obj; } public static void Log(LogLevel level, object data) { } public static void LogInfo(object data) { Log((LogLevel)16, data); } public static void LogDebug(object data) { Log((LogLevel)32, data); } public static void LogWarning(object data) { Log((LogLevel)4, data); } public static void LogError(object data) { Log((LogLevel)2, data); } private static void OnUpgradeStart(PlayerAvatar player, int level) { LogInfo(string.Format("[Start] {0} имеет {1} уровня {2}", ((Object)player).name, "SemiKick_KickUpgrade", level)); ApplyKickLevelToPlayer(player, level); } private static void OnUpgradeApplied(PlayerAvatar player, int level) { LogInfo(string.Format("[Applied] {0} теперь имеет {1} уровня {2}", ((Object)player).name, "SemiKick_KickUpgrade", level)); ApplyKickLevelToPlayer(player, level); } private static void ApplyKickLevelToPlayer(PlayerAvatar player, int level) { if ((Object)(object)player == (Object)null) { LogWarning("[SemiKick] ApplyKickLevelToPlayer: player == null."); } else { (((Component)player).gameObject.GetComponent() ?? ((Component)player).gameObject.AddComponent()).SetKickLevel(level); } } } public class SemiKickRunner : MonoBehaviour { private Keybind kickKeybind; private KickAnimHandler localPlayerHandler; private float kickCooldown = 1.4f; private float cooldownTimer; public void InitKey(Keybind keybind) { kickKeybind = keybind; } public void SetLocalPlayer(KickAnimHandler handler) { localPlayerHandler = handler; SemiKick.LogInfo(string.Format("SemiKickRunner.SetLocalPlayer: handler={0}, Avatar={1}", (Object)(object)handler != (Object)null, ((Object)(object)handler != (Object)null && (Object)(object)handler.Avatar != (Object)null) ? ((Object)handler.Avatar).name : "NULL")); } private void Update() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (cooldownTimer > 0f) { cooldownTimer -= Time.deltaTime; } if (SemiFunc.InputDown(kickKeybind.inputKey) && !(cooldownTimer > 0f)) { RaycastHit hit; KickTarget target; bool flag = TryFindKickTarget(out hit, out target); Vector3? stretchTargetWorldPos = (flag ? new Vector3?(((RaycastHit)(ref hit)).point) : ((Vector3?)null)); if ((Object)(object)localPlayerHandler != (Object)null) { localPlayerHandler.PerformKick(stretchTargetWorldPos); } else { SemiKick.LogWarning("SemiKickRunner.Update: localPlayerHandler == null, PerformKick пропущен."); } ApplyKickEffects(flag, hit, target); } } private int GetEffectiveKickLevel() { if (!((Object)(object)localPlayerHandler != (Object)null)) { return 0; } return localPlayerHandler.KickLevel; } private bool TryFindKickTarget(out RaycastHit hit, out KickTarget target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) hit = default(RaycastHit); target = default(KickTarget); RaycastHit[] array = Physics.RaycastAll(new Ray(((Component)Camera.main).transform.position, ((Component)Camera.main).transform.forward), 2.3f); if (array.Length == 0) { SemiKick.LogInfo("TryFindKickTarget: рейкаст ни во что не попал."); return false; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); PlayerAvatar val = (((Object)(object)localPlayerHandler != (Object)null) ? localPlayerHandler.Avatar : null); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val2 = array2[num]; SemiKick.LogInfo("TryFindKickTarget: попадание в коллайдер '" + ((Object)((RaycastHit)(ref val2)).collider).name + "' на объекте '" + ((Object)((Component)((RaycastHit)(ref val2)).collider).gameObject).name + "'."); KickTarget kickTarget = KickTargetClassifier.ClassifyHit(((RaycastHit)(ref val2)).collider); SemiKick.LogInfo(string.Format("TryFindKickTarget: классификация -> Type={0}, Component={1}", kickTarget.Type, ((Object)(object)kickTarget.Component != (Object)null) ? ((object)kickTarget.Component).GetType().Name : "NULL")); if (kickTarget.Type == KickTargetType.Player && (Object)(object)val != (Object)null && (object)kickTarget.Component == val) { SemiKick.LogInfo("TryFindKickTarget: попадание в СВОЕГО персонажа — игнорирую и продолжаю искать дальше."); continue; } hit = val2; target = kickTarget; return true; } SemiKick.LogInfo("TryFindKickTarget: после пропуска своего персонажа других целей не найдено."); return false; } private void ApplyKickEffects(bool found, RaycastHit hit, KickTarget target) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) if (!found) { SemiKick.LogInfo("ApplyKickEffects: цель не найдена, выхожу без эффектов."); return; } if (!InternalAccessors.CanDoStuff(localPlayerHandler?.Avatar)) { SemiKick.LogInfo("Не устойчивая конструкция - пропуск."); return; } if (target.Type != KickTargetType.Player && target.Type != KickTargetType.Enemy && target.Type != KickTargetType.Valuable) { SemiKick.LogInfo("ApplyKickEffects: цель не валидна (None/неизвестный тип), выхожу без эффектов."); return; } Vector3 direction = ((Component)Camera.main).transform.forward; int effectiveKickLevel = GetEffectiveKickLevel(); float force = SemiKickSettings.GetKickForce(effectiveKickLevel); SemiKick.LogInfo($"ApplyKickEffects: рассчитанная сила force={force} (baseForce={1.4f}, effectiveLevel={effectiveKickLevel}, levelMultiplier={0.7f})"); float num = Mathf.Clamp(force * 0.05f, 4f, 14f); if ((Object)(object)GameDirector.instance != (Object)null && (Object)(object)GameDirector.instance.CameraShake != (Object)null) { SemiKick.LogInfo($"ApplyKickEffects: вызываю CameraShake.Shake(strength={num}, time={0.05f})"); GameDirector.instance.CameraShake.Shake(num, 0.05f); } else { SemiKick.LogWarning("ApplyKickEffects: GameDirector.instance или CameraShake == null, тряска пропущена."); } PlayerAvatar kicker = (((Object)(object)localPlayerHandler != (Object)null) ? localPlayerHandler.Avatar : null); if ((Object)(object)kicker == (Object)null) { SemiKick.LogWarning("ApplyKickEffects: kicker (Avatar локального игрока) == null — knockback работать не будет для этого пинка."); } switch (target.Type) { case KickTargetType.Player: { bool flag = effectiveKickLevel >= 2; SemiKick.LogInfo($"ApplyKickEffects: цель Player -> KickNetworking.ApplyKickToPlayer (без self-knockback), forceTumble={flag} (effectiveLevel={effectiveKickLevel} >= {2})."); KickNetworking.ApplyKickToPlayer((PlayerAvatar)target.Component, direction * force, flag); break; } case KickTargetType.Enemy: { Enemy enemy = (Enemy)target.Component; EnemyKickReceiver enemyReceiver = ((Component)enemy).GetComponent(); if (!((Object)(object)enemyReceiver != (Object)null)) { break; } float enemyMass = enemyReceiver.GetMass(); SemiKick.LogInfo($"ApplyKickEffects: цель Enemy '{((Object)enemy).name}', mass={enemyMass} -> ставлю в очередь."); if ((Object)(object)localPlayerHandler != (Object)null) { localPlayerHandler.RequestGenericKick(delegate { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemyReceiver == (Object)null || (Object)(object)enemy == (Object)null) { SemiKick.LogWarning("ApplyKickEffects: Враг исчез до момента удара!"); } else { enemyReceiver.SendKick(direction * force); if ((Object)(object)kicker != (Object)null) { KnockbackCalculator.Apply(kicker, enemyMass, force, direction); } } }); } else { enemyReceiver.SendKick(direction * force); KnockbackCalculator.Apply(kicker, enemyMass, force, direction); } break; } case KickTargetType.Valuable: { PhysGrabObject physGrabObject = (PhysGrabObject)target.Component; ValuableKickReceiver valuableReceiver = ((Component)physGrabObject).GetComponent(); if (!((Object)(object)valuableReceiver != (Object)null)) { break; } float valuableMass = (((Object)(object)physGrabObject.rb != (Object)null) ? physGrabObject.rb.mass : 0f); Vector3 hitPoint = ((RaycastHit)(ref hit)).point; if ((Object)(object)localPlayerHandler != (Object)null) { localPlayerHandler.RequestGenericKick(delegate { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)valuableReceiver == (Object)null || (Object)(object)physGrabObject == (Object)null) { SemiKick.LogWarning("ApplyKickEffects: Предмет исчез до момента удара!"); } else { valuableReceiver.RequestKick(direction * force, hitPoint); if ((Object)(object)kicker != (Object)null && (Object)(object)physGrabObject.rb != (Object)null) { KnockbackCalculator.Apply(kicker, valuableMass, force, direction); } } }); } else { valuableReceiver.RequestKick(direction * force, hitPoint); KnockbackCalculator.Apply(kicker, valuableMass, force, direction); } break; } } } } internal static class SemiKickSettings { public const bool EnableLogging = false; public const LogLevel MinLogLevel = (LogLevel)16; public const float BaseForce = 1.4f; public const float LevelMultiplier = 0.7f; public const int PlayerTumbleGuaranteeLevel = 2; public const float ShakeForceMultiplier = 0.05f; public const float ShakeMin = 4f; public const float ShakeMax = 14f; public const float ShakeTime = 0.05f; public const float LegStretchNaturalReach = 0.5f; public const float LegStretchMaxMultiplier = 1.8f; public const int LegStretchAxis = 1; public const float LegStretchLerpSpeed = 8f; public const float KnockbackSoftThreshold = 0.9f; public const float KnockbackHardThreshold = 4f; public const float RecoilForceMultiplier = 3f; public const float KnockbackHardMinForce = 20f; public const float ImpactHurtWindow = 0.5f; public const int ImpactHurtDamageBase = 15; public const int ImpactHurtDamageMax = 50; public static float GetKickForce(int kickLevel) { return 1.4f * (1f + (float)kickLevel * 0.7f); } } internal class ValuableKickReceiver : MonoBehaviourPun { private PhysGrabObject _physGrabObject; private void Awake() { _physGrabObject = ((Component)this).GetComponent(); } public void RequestKick(Vector3 force, Vector3 hitPoint) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer()) { KickNetworking.ApplyKickToValuable(_physGrabObject, force, hitPoint); return; } PhotonView photonView = ((MonoBehaviourPun)this).photonView; if (!((Object)(object)photonView == (Object)null)) { photonView.RPC("RequestKickRPC", (RpcTarget)2, new object[2] { force, hitPoint }); } } [PunRPC] private void RequestKickRPC(Vector3 force, Vector3 hitPoint, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) KickNetworking.ApplyKickToValuable(_physGrabObject, force, hitPoint); } } [HarmonyPatch(typeof(PhysGrabObject), "Awake")] internal static class ValuableKickReceiverPatch { [HarmonyPostfix] private static void Postfix(PhysGrabObject __instance) { if ((Object)(object)((Component)__instance).gameObject.GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } }