Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HarpoonAnimFix v1.0.1
HarpoonAnimFix.dll
Decompiled 16 hours agousing System; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using EntityStates; using EntityStates.Engi.EngiMissilePainter; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HarpoonAnimFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("HarpoonAnimFix")] [assembly: AssemblyTitle("HarpoonAnimFix")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HarpoonAnimFix { internal enum TrackKind : byte { Position, Euler, Scale } internal sealed class Channel { private readonly float constant; private readonly float[] times; private readonly float[] coeffs; internal Channel(float constant, float[] times, float[] coeffs) { this.constant = constant; this.times = times; this.coeffs = coeffs; } internal float Evaluate(float t) { if (times == null) { return constant; } int num = 0; int num2 = times.Length - 1; while (num < num2) { int num3 = num + num2 + 1 >> 1; if (times[num3] <= t) { num = num3; } else { num2 = num3 - 1; } } float num4 = t - times[num]; int num5 = num * 4; return ((coeffs[num5] * num4 + coeffs[num5 + 1]) * num4 + coeffs[num5 + 2]) * num4 + coeffs[num5 + 3]; } } internal sealed class Track { internal readonly int Bone; internal readonly TrackKind Kind; internal readonly Vector3 Reference; internal readonly Quaternion InverseReferenceRotation; private readonly Channel x; private readonly Channel y; private readonly Channel z; internal Track(int bone, TrackKind kind, Vector3 reference, Channel x, Channel y, Channel z) { //IL_0015: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Bone = bone; Kind = kind; Reference = reference; InverseReferenceRotation = ((kind == TrackKind.Euler) ? Quaternion.Inverse(Quaternion.Euler(reference)) : Quaternion.identity); this.x = x; this.y = y; this.z = z; } internal Vector3 Sample(float t) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x.Evaluate(t), y.Evaluate(t), z.Evaluate(t)); } } internal sealed class Clip { internal readonly float Length; internal readonly Track[] Tracks; internal Clip(float length, Track[] tracks) { Length = length; Tracks = tracks; } } internal static class OriginalClips { internal static readonly string[] BonePaths; internal static readonly Clip Prep; internal static readonly Clip Idle; internal static readonly Clip Exit; internal static readonly Clip FireLeft; internal static readonly Clip FireRight; static OriginalClips() { using Stream stream = typeof(OriginalClips).Assembly.GetManifestResourceStream("HarpoonAnimFix.Clips.bin"); using DeflateStream input = new DeflateStream(stream, CompressionMode.Decompress); using BinaryReader binaryReader = new BinaryReader(input); BonePaths = new string[binaryReader.ReadByte()]; for (int i = 0; i < BonePaths.Length; i++) { BonePaths[i] = Encoding.UTF8.GetString(binaryReader.ReadBytes(binaryReader.ReadByte())); } Clip[] array = new Clip[binaryReader.ReadByte()]; for (int j = 0; j < array.Length; j++) { array[j] = ReadClip(binaryReader); } Prep = array[0]; Idle = array[1]; Exit = array[2]; FireLeft = array[3]; FireRight = array[4]; } private static Clip ReadClip(BinaryReader reader) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) float length = reader.ReadSingle(); Track[] array = new Track[reader.ReadByte()]; Vector3 reference = default(Vector3); for (int i = 0; i < array.Length; i++) { int bone = reader.ReadByte(); TrackKind kind = (TrackKind)reader.ReadByte(); ((Vector3)(ref reference))..ctor(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); array[i] = new Track(bone, kind, reference, ReadChannel(reader), ReadChannel(reader), ReadChannel(reader)); } return new Clip(length, array); } private static Channel ReadChannel(BinaryReader reader) { int num = reader.ReadByte(); if (num == 0) { return new Channel(reader.ReadSingle(), null, null); } float[] array = new float[num]; for (int i = 0; i < num; i++) { array[i] = reader.ReadSingle(); } float[] array2 = new float[num * 4]; for (int j = 0; j < array2.Length; j++) { array2[j] = reader.ReadSingle(); } return new Channel(0f, array, array2); } } [BepInPlugin("FluxSquido.HarpoonAnimFix", "HarpoonAnimFix", "1.0.1")] public sealed class HarpoonAnimFixPlugin : BaseUnityPlugin { public const string Guid = "FluxSquido.HarpoonAnimFix"; public const string Name = "HarpoonAnimFix"; public const string Version = "1.0.1"; internal static ManualLogSource Log; private Harmony harmony; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("FluxSquido.HarpoonAnimFix"); harmony.PatchAll(typeof(Patches)); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } [DefaultExecutionOrder(-1000)] internal sealed class HarpoonRig : MonoBehaviour { private struct Applied { public bool Valid; public Quaternion WrittenRotation; public Vector3 WrittenPosition; public Vector3 WrittenScale; public BonePose Delta; } private const float GestureCrossfade = 0.1f; private const float ExitSpeed = 0.6f; private const float LeftExitNormalized = 1f; private const float LeftExitSeconds = 0.1f; private const float RightExitNormalized = 17f / 32f; private const float RightExitSeconds = 0.25f; private static readonly int PrepHash = Animator.StringToHash("PrepHarpoons"); private static readonly int IdleHash = Animator.StringToHash("IdleHarpoons"); private static readonly int ExitHash = Animator.StringToHash("ExitHarpoons"); private static readonly int FireGrenadeLeftHash = Animator.StringToHash("FireGrenadeLeft"); private static readonly int FireGrenadeRightHash = Animator.StringToHash("FireGrenadeRight"); private readonly LayerState gesture = new LayerState(); private readonly LayerState leftCannon = new LayerState(); private readonly LayerState rightCannon = new LayerState(); private Animator animator; private int gestureLayer = -1; private int leftLayer = -1; private int rightLayer = -1; private Transform[] bones; private BonePose[] layerPose; private BonePose[] totalPose; private Applied[] applied; private bool anyApplied; internal static HarpoonRig For(Animator animator) { if (!Object.op_Implicit((Object)(object)animator)) { return null; } HarpoonRig harpoonRig = ((Component)animator).GetComponent<HarpoonRig>(); if (!Object.op_Implicit((Object)(object)harpoonRig)) { harpoonRig = ((Component)animator).gameObject.AddComponent<HarpoonRig>(); harpoonRig.Init(animator); } if (harpoonRig.bones == null) { return null; } return harpoonRig; } private void Init(Animator anim) { animator = anim; gestureLayer = anim.GetLayerIndex("Gesture, Additive"); leftLayer = anim.GetLayerIndex("Gesture Left Cannon, Additive"); rightLayer = anim.GetLayerIndex("Gesture Right Cannon, Additive"); string[] bonePaths = OriginalClips.BonePaths; Transform[] array = (Transform[])(object)new Transform[bonePaths.Length]; for (int i = 0; i < bonePaths.Length; i++) { array[i] = ((Component)anim).transform.Find(bonePaths[i]); if (!Object.op_Implicit((Object)(object)array[i])) { HarpoonAnimFixPlugin.Log.LogWarning((object)("'" + ((Object)anim).name + "' has no bone '" + bonePaths[i] + "'; harpoon animation disabled for this model.")); ((Behaviour)this).enabled = false; return; } } bones = array; layerPose = new BonePose[bonePaths.Length]; totalPose = new BonePose[bonePaths.Length]; applied = new Applied[bonePaths.Length]; } internal void PaintEntered() { gesture.CrossFade(OriginalClips.Prep, 1f, 0.1f); ((Behaviour)this).enabled = true; } internal void PaintExited() { gesture.CrossFade(OriginalClips.Exit, 0.6f, 0.1f); ((Behaviour)this).enabled = true; } internal void FireEntered() { gesture.Play(OriginalClips.Idle, 1f); ((Behaviour)this).enabled = true; } internal void FireExited() { gesture.CrossFade(OriginalClips.Exit, 0.6f, 0.1f); ((Behaviour)this).enabled = true; } internal void Shot(bool left) { if (left) { leftCannon.Play(OriginalClips.FireLeft, 1f, 1f, 0.1f); } else { rightCannon.Play(OriginalClips.FireRight, 1f, 17f / 32f, 0.25f); } ((Behaviour)this).enabled = true; } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)animator) || !((Behaviour)animator).isActiveAndEnabled || (!gesture.Active && !leftCannon.Active && !rightCannon.Active)) { if (anyApplied) { Restore(); } ((Behaviour)this).enabled = false; return; } float dt = Time.deltaTime * animator.speed; gesture.Advance(dt); leftCannon.Advance(dt); rightCannon.Advance(dt); FollowAnimator(); for (int i = 0; i < totalPose.Length; i++) { totalPose[i] = BonePose.Identity; } ComposeLayer(gesture); ComposeLayer(leftCannon); ComposeLayer(rightCannon); Apply(); } private void FollowAnimator() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) gesture.Fade = 1f; if (gestureLayer >= 0 && gesture.Active) { AnimatorStateInfo val = animator.GetCurrentAnimatorStateInfo(gestureLayer); int shortNameHash = ((AnimatorStateInfo)(ref val)).shortNameHash; bool flag = animator.IsInTransition(gestureLayer); int num; if (!flag) { num = 0; } else { val = animator.GetNextAnimatorStateInfo(gestureLayer); num = ((AnimatorStateInfo)(ref val)).shortNameHash; } int hash = num; bool flag2 = IsGestureHarpoon(shortNameHash); bool flag3 = IsGestureHarpoon(hash); if (!flag2 && !flag3) { gesture.Stop(); } else if (flag2 && flag && !flag3) { LayerState layerState = gesture; AnimatorTransitionInfo animatorTransitionInfo = animator.GetAnimatorTransitionInfo(gestureLayer); layerState.Fade = 1f - ((AnimatorTransitionInfo)(ref animatorTransitionInfo)).normalizedTime; } } if (leftLayer >= 0 && leftCannon.Active && LayerIs(leftLayer, FireGrenadeLeftHash)) { leftCannon.Stop(); } if (rightLayer >= 0 && rightCannon.Active && LayerIs(rightLayer, FireGrenadeRightHash)) { rightCannon.Stop(); } } private static bool IsGestureHarpoon(int hash) { if (hash != PrepHash && hash != IdleHash) { return hash == ExitHash; } return true; } private bool LayerIs(int layer, int hash) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) AnimatorStateInfo val = animator.GetCurrentAnimatorStateInfo(layer); if (((AnimatorStateInfo)(ref val)).shortNameHash == hash) { return true; } if (animator.IsInTransition(layer)) { val = animator.GetNextAnimatorStateInfo(layer); return ((AnimatorStateInfo)(ref val)).shortNameHash == hash; } return false; } private void ComposeLayer(LayerState layer) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (layer.Active) { for (int i = 0; i < layerPose.Length; i++) { layerPose[i] = BonePose.Empty; } layer.Accumulate(layerPose); for (int j = 0; j < layerPose.Length; j++) { BonePose bonePose = layerPose[j].Resolve(); totalPose[j].Rotation = totalPose[j].Rotation * bonePose.Rotation; ref Vector3 position = ref totalPose[j].Position; position += bonePose.Position; totalPose[j].Scale = Vector3.Scale(totalPose[j].Scale, bonePose.Scale); } } } private void Apply() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) //IL_002a: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < bones.Length; i++) { Transform val = bones[i]; ref Applied reference = ref applied[i]; Quaternion val2 = val.localRotation; Vector3 val3 = val.localPosition; Vector3 val4 = val.localScale; if (reference.Valid && ((Quaternion)(ref val2)).Equals(reference.WrittenRotation) && ((Vector3)(ref val3)).Equals(reference.WrittenPosition) && ((Vector3)(ref val4)).Equals(reference.WrittenScale)) { val2 = reference.WrittenRotation * Quaternion.Inverse(reference.Delta.Rotation); val3 = reference.WrittenPosition - reference.Delta.Position; val4 = Divide(reference.WrittenScale, reference.Delta.Scale); } BonePose delta = totalPose[i]; Quaternion writtenRotation = (val.localRotation = val2 * delta.Rotation); reference.WrittenRotation = writtenRotation; Vector3 writtenPosition = (val.localPosition = val3 + delta.Position); reference.WrittenPosition = writtenPosition; writtenPosition = (val.localScale = Vector3.Scale(val4, delta.Scale)); reference.WrittenScale = writtenPosition; reference.Delta = delta; reference.Valid = true; } anyApplied = true; } private void Restore() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) for (int i = 0; i < bones.Length; i++) { Transform val = bones[i]; ref Applied reference = ref applied[i]; if (reference.Valid && Object.op_Implicit((Object)(object)val)) { Quaternion localRotation = val.localRotation; if (((Quaternion)(ref localRotation)).Equals(reference.WrittenRotation)) { Vector3 localPosition = val.localPosition; if (((Vector3)(ref localPosition)).Equals(reference.WrittenPosition)) { val.localRotation = reference.WrittenRotation * Quaternion.Inverse(reference.Delta.Rotation); val.localPosition = reference.WrittenPosition - reference.Delta.Position; val.localScale = Divide(reference.WrittenScale, reference.Delta.Scale); } } } reference.Valid = false; } anyApplied = false; } private static Vector3 Divide(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) return new Vector3((b.x != 0f) ? (a.x / b.x) : a.x, (b.y != 0f) ? (a.y / b.y) : a.y, (b.z != 0f) ? (a.z / b.z) : a.z); } } internal struct BonePose { public Quaternion Rotation; public Vector3 Position; public Vector3 Scale; public float RotationWeight; public float ScaleWeight; internal static readonly BonePose Identity = new BonePose { Rotation = Quaternion.identity, Position = Vector3.zero, Scale = Vector3.one }; internal static readonly BonePose Empty = new BonePose { Rotation = new Quaternion(0f, 0f, 0f, 0f), Position = Vector3.zero, Scale = Vector3.zero }; internal BonePose Resolve() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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) float num = Mathf.Clamp01(1f - RotationWeight); Quaternion val = default(Quaternion); ((Quaternion)(ref val))..ctor(Rotation.x, Rotation.y, Rotation.z, Rotation.w + num); float num2 = Mathf.Sqrt(val.x * val.x + val.y * val.y + val.z * val.z + val.w * val.w); return new BonePose { Rotation = (Quaternion)((num2 > 1E-06f) ? new Quaternion(val.x / num2, val.y / num2, val.z / num2, val.w / num2) : Quaternion.identity), Position = Position, Scale = Scale + Vector3.one * Mathf.Clamp01(1f - ScaleWeight) }; } } internal sealed class LayerState { private struct Slot { public Clip Clip; public float Time; public float Speed; public float ExitNormalized; public float ExitSeconds; } private Slot current; private Slot next; private bool transitioning; private float transitionElapsed; private float transitionSeconds; internal float Fade = 1f; internal bool Active { get { if (current.Clip == null) { if (transitioning) { return next.Clip != null; } return false; } return true; } } internal void Play(Clip clip, float speed, float exitNormalized = 0f, float exitSeconds = 0f) { current = new Slot { Clip = clip, Speed = speed, ExitNormalized = exitNormalized, ExitSeconds = exitSeconds }; next = default(Slot); transitioning = false; } internal void CrossFade(Clip clip, float speed, float seconds) { if (transitioning && transitionElapsed >= transitionSeconds * 0.5f) { current = next; } next = new Slot { Clip = clip, Speed = speed }; transitioning = true; transitionElapsed = 0f; transitionSeconds = Mathf.Max(seconds, 0.0001f); } internal void Stop() { current = default(Slot); next = default(Slot); transitioning = false; } internal void Advance(float dt) { current.Time += dt * current.Speed; if (transitioning) { next.Time += dt * next.Speed; transitionElapsed += dt; if (transitionElapsed >= transitionSeconds) { current = next; next = default(Slot); transitioning = false; } } if (!transitioning && current.Clip != null && current.ExitNormalized > 0f && current.Time >= current.ExitNormalized * current.Clip.Length) { CrossFade(null, 1f, current.ExitSeconds); } if (!transitioning && current.Clip == null) { current = default(Slot); } } internal void Accumulate(BonePose[] pose) { float num = (transitioning ? Mathf.Clamp01(transitionElapsed / transitionSeconds) : 0f); Add(pose, current, (1f - num) * Fade); if (transitioning) { Add(pose, next, num * Fade); } } private static void Add(BonePose[] pose, Slot slot, float weight) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (slot.Clip == null || weight <= 0f) { return; } float t = Mathf.Clamp(slot.Time, 0f, slot.Clip.Length); Track[] tracks = slot.Clip.Tracks; foreach (Track track in tracks) { ref BonePose reference = ref pose[track.Bone]; Vector3 val = track.Sample(t); switch (track.Kind) { case TrackKind.Euler: { Quaternion val2 = track.InverseReferenceRotation * Quaternion.Euler(val); if (val2.w < 0f) { ((Quaternion)(ref val2))..ctor(0f - val2.x, 0f - val2.y, 0f - val2.z, 0f - val2.w); } reference.Rotation = new Quaternion(reference.Rotation.x + val2.x * weight, reference.Rotation.y + val2.y * weight, reference.Rotation.z + val2.z * weight, reference.Rotation.w + val2.w * weight); reference.RotationWeight += weight; break; } case TrackKind.Position: { ref Vector3 position = ref reference.Position; position += (val - track.Reference) * weight; break; } case TrackKind.Scale: { ref Vector3 scale = ref reference.Scale; scale += new Vector3(Ratio(val.x, track.Reference.x), Ratio(val.y, track.Reference.y), Ratio(val.z, track.Reference.z)) * weight; reference.ScaleWeight += weight; break; } } } } private static float Ratio(float value, float reference) { if (reference == 0f) { return 1f; } return value / reference; } } internal static class Patches { private static EffectIndex flashIndex = (EffectIndex)(-1); private static bool flashResolved; [HarmonyPostfix] [HarmonyPatch(typeof(Paint), "OnEnter")] private static void PaintEnter(Paint __instance) { Guard((EntityState)(object)__instance, delegate(HarpoonRig rig) { rig.PaintEntered(); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Paint), "OnExit")] private static void PaintExit(Paint __instance) { Guard((EntityState)(object)__instance, delegate(HarpoonRig rig) { rig.PaintExited(); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Fire), "OnEnter")] private static void FireEnter(Fire __instance) { Guard((EntityState)(object)__instance, delegate(HarpoonRig rig) { rig.FireEntered(); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Fire), "OnExit")] private static void FireExit(Fire __instance) { Guard((EntityState)(object)__instance, delegate(HarpoonRig rig) { rig.FireExited(); }); } [HarmonyPrefix] [HarmonyPatch(typeof(EffectManager), "SpawnEffect", new Type[] { typeof(EffectIndex), typeof(EffectData), typeof(bool) })] private static void SpawnEffectPrefix(EffectIndex effectIndex, EffectData effectData, bool transmit) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (effectIndex != flashIndex || (int)effectIndex == -1 || !NetworkClient.active || (transmit && NetworkServer.active)) { return; } try { OnFlash(effectData); } catch (Exception ex) { HarpoonAnimFixPlugin.Log.LogError((object)ex); } } private static void Guard(EntityState state, Action<HarpoonRig> action) { try { ResolveFlash(); HarpoonRig harpoonRig = HarpoonRig.For(GetAnimator(Object.op_Implicit((Object)(object)state.outer) ? state.outer.commonComponents.modelLocator : null)); if (Object.op_Implicit((Object)(object)harpoonRig)) { action(harpoonRig); } } catch (Exception ex) { HarpoonAnimFixPlugin.Log.LogError((object)ex); } } private static void OnFlash(EffectData data) { GameObject rootObject = data.rootObject; if (Object.op_Implicit((Object)(object)rootObject)) { ModelLocator component = rootObject.GetComponent<ModelLocator>(); HarpoonRig harpoonRig = HarpoonRig.For(GetAnimator(component)); if (Object.op_Implicit((Object)(object)harpoonRig)) { ChildLocator val = (Object.op_Implicit((Object)(object)component.modelTransform) ? ((Component)component.modelTransform).GetComponent<ChildLocator>() : null); string text = ((Object.op_Implicit((Object)(object)val) && data.modelChildIndex >= 0) ? val.FindChildName((int)data.modelChildIndex) : null); harpoonRig.Shot(text != null && text.IndexOf("Left", StringComparison.OrdinalIgnoreCase) >= 0); } } } private static Animator GetAnimator(ModelLocator locator) { if (!Object.op_Implicit((Object)(object)locator)) { return null; } if (Object.op_Implicit((Object)(object)locator.modelAnimator)) { return locator.modelAnimator; } if (!Object.op_Implicit((Object)(object)locator.modelTransform)) { return null; } return ((Component)locator.modelTransform).GetComponent<Animator>(); } private static void ResolveFlash() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if (flashResolved) { return; } GameObject muzzleflashEffectPrefab = Fire.muzzleflashEffectPrefab; if (Object.op_Implicit((Object)(object)muzzleflashEffectPrefab)) { flashResolved = true; flashIndex = EffectCatalog.FindEffectIndexFromPrefab(muzzleflashEffectPrefab); if ((int)flashIndex == -1) { HarpoonAnimFixPlugin.Log.LogWarning((object)("Harpoon muzzle flash '" + ((Object)muzzleflashEffectPrefab).name + "' is not in the effect catalog; cannon recoil will not play.")); } } } } }