using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2Cpp;
using Il2CppCinemachine;
using Il2CppFemur;
using Il2CppGB.Core;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using OldCamera;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(OldCameraMod), "OldCamera", "1.1.0", "Zooks", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("OldCamera")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("mod for Gang Beasts")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OldCamera")]
[assembly: AssemblyTitle("OldCamera")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 OldCamera
{
public sealed class OldCameraRenderDriver : MonoBehaviour
{
public OldCameraRenderDriver(IntPtr pointer)
: base(pointer)
{
}
public void OnDisable()
{
OldCameraMod.Instance?.AfterRender(this);
}
}
public class OldCameraMod : MelonMod
{
private struct StateMessage
{
public Actor Actor;
public ActorState State;
public string Source;
}
private sealed class Beast
{
public int Key;
public Actor Actor;
public Transform Root;
public Transform Target;
public bool IsAI;
public bool Known;
public bool Dead;
public bool HasPosition;
public Vector3 Position;
public float NextTargetRefresh;
public float LastEventTime = -100f;
public float AliveSince = -1f;
}
private sealed class RenderState
{
public Camera Camera;
public Transform Transform;
public OldCameraRenderDriver Driver;
public bool Applied;
public Vector3 BasePosition;
public Vector3 WrittenPosition;
public bool ReceivedBrainUpdate;
public bool Warned;
public float AttachedAt;
public int LoggedTransition = -1;
public bool HasDisplayedPosition;
public Vector3 DisplayedPosition;
public int LastDisplayedFrame = -1;
public bool SmoothingMovement;
public int LastSmoothingFrame = -1;
}
private sealed class ComposerState
{
public GangBeastsGroupComposer Composer;
public float Original;
public float Applied;
}
internal static OldCameraMod Instance;
private MelonPreferences_Category _category;
private MelonPreferences_Entry<bool> _pTrackAI;
private MelonPreferences_Entry<bool> _pDiagnostics;
private MelonPreferences_Entry<float> _pDipTime;
private MelonPreferences_Entry<float> _pReturnTime;
private MelonPreferences_Entry<float> _pDepth;
private MelonPreferences_Entry<float> _pSideReach;
private MelonPreferences_Entry<float> _pStrength;
private MelonPreferences_Entry<float> _pRoughness;
private MelonPreferences_Entry<float> _pMaxOffset;
private MelonPreferences_Entry<float> _pDamping;
private bool _trackAI = true;
private bool _diagnostics = true;
private float _dipTime = 0.85f;
private float _returnTime = 2.4f;
private float _depth = -1.25f;
private float _sideReach = 0.65f;
private float _strength = 1.5f;
private float _maxOffset = 3f;
private float _roughness = 0.022f;
private float _damping = 4.5f;
private readonly ConcurrentQueue<StateMessage> _stateQueue = new ConcurrentQueue<StateMessage>();
private ActorStateHandler _clientDelegate;
private ActorStateHandler _serverDelegate;
private bool _clientSubscribed;
private bool _serverSubscribed;
private volatile bool _acceptEvents;
private readonly Dictionary<int, Beast> _beasts = new Dictionary<int, Beast>();
private readonly List<int> _removeKeys = new List<int>();
private readonly List<int> _pendingDeaths = new List<int>();
private int _livingCount;
private Vector3 _centroid;
private CMTargetGroupHandler _handler;
private CMTargetGroupPool _pool;
private bool _aiCached;
private bool _originalTrackAI;
private float _originalAIWeight;
private float _originalAIRadius;
private CinemachineTargetGroup _aiGroup;
private readonly Dictionary<int, Transform> _addedAI = new Dictionary<int, Transform>();
private readonly Dictionary<IntPtr, RenderState> _renderers = new Dictionary<IntPtr, RenderState>();
private readonly HashSet<IntPtr> _knownCameras = new HashSet<IntPtr>();
private readonly List<IntPtr> _removeRenderers = new List<IntPtr>();
private MethodInfo _brainLateUpdateMethod;
private bool _brainPatchInstalled;
private readonly List<ComposerState> _composers = new List<ComposerState>();
private readonly HashSet<IntPtr> _knownComposers = new HashSet<IntPtr>();
private bool _moving;
private int _transitionId;
private int _startFrame = -1;
private int _advancedFrame = -1;
private float _dipProgress;
private float _returnProgress;
private Vector3 _startOffset;
private Vector3 _peakOffset;
private Vector3 _offset;
private int _seed;
private bool _gameplay;
private bool _insideTick;
private bool _insideRender;
private float _nextDiscovery;
private float _nextCameraScan;
private float _nextSettings;
private float _nextAI;
private float _nextStatus;
private float _lastError = -100f;
private int _clientEvents;
private int _serverEvents;
private int _detectedDeaths;
public override void OnInitializeMelon()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
InitializePreferences();
ClassInjector.RegisterTypeInIl2Cpp<OldCameraRenderDriver>();
_clientDelegate = DelegateSupport.ConvertDelegate<ActorStateHandler>((Delegate)new Action<Actor, int, ActorState>(OnClientState));
_serverDelegate = DelegateSupport.ConvertDelegate<ActorStateHandler>((Delegate)new Action<Actor, int, ActorState>(OnServerState));
Scene activeScene = SceneManager.GetActiveScene();
_gameplay = IsGameplayScene(((Scene)(ref activeScene)).name);
_acceptEvents = _gameplay;
if (_gameplay)
{
SubscribeStateEvents();
}
InstallBrainPatch();
((MelonBase)this).LoggerInstance.Msg("OldCamera 1.2.1 initialized. Online death detection and final-position smoothing. Patch installed=" + _brainPatchInstalled + " strength=" + _strength + " maximumOffset=" + _maxOffset);
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
_gameplay = false;
Cleanup();
_gameplay = IsGameplayScene(sceneName);
_acceptEvents = _gameplay;
if (_gameplay)
{
SubscribeStateEvents();
}
}
public override void OnDeinitializeMelon()
{
_gameplay = false;
_acceptEvents = false;
RemoveBrainPatch();
Cleanup();
Instance = null;
}
public override void OnUpdate()
{
foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
{
RestorePosition(renderer.Value);
}
if (_gameplay)
{
Tick();
}
}
public override void OnLateUpdate()
{
if (_gameplay)
{
Tick();
}
}
private static bool IsGameplayScene(string name)
{
if (!string.IsNullOrEmpty(name))
{
return name != Global.MENU_SCENE_NAME;
}
return false;
}
private void InstallBrainPatch()
{
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
if (_brainPatchInstalled)
{
return;
}
try
{
_brainLateUpdateMethod = AccessTools.Method(typeof(CinemachineBrain), "LateUpdate", Type.EmptyTypes, (Type[])null);
if (_brainLateUpdateMethod == null)
{
((MelonBase)this).LoggerInstance.Error("CAMERA PATCH FAILED: CinemachineBrain.LateUpdate was not found.");
return;
}
MethodInfo methodInfo = AccessTools.Method(typeof(OldCameraMod), "AfterCinemachineLateUpdate", (Type[])null, (Type[])null);
if (methodInfo == null)
{
((MelonBase)this).LoggerInstance.Error("CAMERA PATCH FAILED: postfix method was not found.");
return;
}
((MelonBase)this).HarmonyInstance.Patch((MethodBase)_brainLateUpdateMethod, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
_brainPatchInstalled = true;
((MelonBase)this).LoggerInstance.Msg("CAMERA PATCH INSTALLED: CinemachineBrain.LateUpdate");
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Error("CAMERA PATCH FAILED: " + ex);
}
}
private void RemoveBrainPatch()
{
if (_brainPatchInstalled && !(_brainLateUpdateMethod == null))
{
try
{
((MelonBase)this).HarmonyInstance.Unpatch((MethodBase)_brainLateUpdateMethod, (HarmonyPatchType)2, ((MelonBase)this).HarmonyInstance.Id);
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Error("Camera patch removal failed: " + ex);
}
_brainPatchInstalled = false;
_brainLateUpdateMethod = null;
}
}
private static void AfterCinemachineLateUpdate(CinemachineBrain __instance)
{
OldCameraMod instance = Instance;
if (instance == null)
{
return;
}
try
{
instance.ApplyAfterCinemachine(__instance);
}
catch (Exception exception)
{
instance.Report("Cinemachine postfix", exception);
}
}
private void ApplyAfterCinemachine(CinemachineBrain brain)
{
//IL_00bd: 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_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_00ca: 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_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: 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_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: 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_020e: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_0214: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_022a: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_0231: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
if (!_gameplay || _insideRender || (Object)(object)brain == (Object)null || !((Behaviour)brain).enabled)
{
return;
}
Camera component = ((Component)brain).GetComponent<Camera>();
if ((Object)(object)component == (Object)null || !((Behaviour)component).enabled || !((Component)component).gameObject.activeInHierarchy)
{
return;
}
_insideRender = true;
RenderState renderState = null;
try
{
Tick();
renderState = FindRenderState(component);
if (renderState == null)
{
Attach(component);
renderState = FindRenderState(component);
}
if (renderState == null || (Object)(object)renderState.Transform == (Object)null)
{
return;
}
if (!renderState.ReceivedBrainUpdate)
{
renderState.ReceivedBrainUpdate = true;
((MelonBase)this).LoggerInstance.Msg("CINEMACHINE POSTFIX RUNNING: " + ((Object)component).name);
}
RestorePosition(renderState);
Vector3 position = renderState.Transform.position;
Vector3 val = DisplayOffset();
if (!Finite(position) || !Finite(val))
{
return;
}
Vector3 val2 = position + val;
if (!Finite(val2))
{
return;
}
int frameCount = Time.frameCount;
bool flag = renderState.HasDisplayedPosition && frameCount >= renderState.LastDisplayedFrame && frameCount - renderState.LastDisplayedFrame <= 2;
if (!flag)
{
renderState.DisplayedPosition = val2;
renderState.HasDisplayedPosition = true;
renderState.SmoothingMovement = false;
renderState.LastSmoothingFrame = -1;
}
if (_moving && flag)
{
renderState.SmoothingMovement = true;
}
Vector3 val3 = val2;
if (renderState.SmoothingMovement)
{
if (renderState.LastSmoothingFrame != frameCount)
{
renderState.LastSmoothingFrame = frameCount;
float num = Mathf.Max(0f, Time.unscaledDeltaTime);
float num2 = 1f - Mathf.Exp((0f - num) / 0.12f);
renderState.DisplayedPosition = Vector3.Lerp(renderState.DisplayedPosition, val2, num2);
}
val3 = renderState.DisplayedPosition;
if (!_moving)
{
Vector3 val4 = val3 - val2;
if (((Vector3)(ref val4)).sqrMagnitude < 1E-06f)
{
renderState.SmoothingMovement = false;
val3 = val2;
}
}
}
if (!Finite(val3))
{
return;
}
renderState.DisplayedPosition = val3;
renderState.HasDisplayedPosition = true;
renderState.LastDisplayedFrame = frameCount;
Vector3 val5 = val3 - position;
if (!(((Vector3)(ref val5)).sqrMagnitude < 1E-08f))
{
renderState.BasePosition = position;
renderState.WrittenPosition = val3;
renderState.Transform.position = val3;
renderState.Applied = true;
if (_diagnostics && _moving && renderState.LoggedTransition != _transitionId)
{
renderState.LoggedTransition = _transitionId;
((MelonBase)this).LoggerInstance.Msg("SMOOTH DEATH MOVEMENT: #" + _transitionId + " camera=" + ((Object)component).name + " strength=" + _strength);
}
}
}
catch
{
if (renderState != null)
{
RestorePosition(renderState);
}
throw;
}
finally
{
_insideRender = false;
}
}
private void OnClientState(Actor actor, int connectionId, ActorState state)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (_acceptEvents)
{
_stateQueue.Enqueue(new StateMessage
{
Actor = actor,
State = state,
Source = "client event"
});
}
}
private void OnServerState(Actor actor, int connectionId, ActorState state)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (_acceptEvents)
{
_stateQueue.Enqueue(new StateMessage
{
Actor = actor,
State = state,
Source = "server event"
});
}
}
private void SubscribeStateEvents()
{
try
{
Actor.OnActorStateChangedClient -= _clientDelegate;
Actor.OnActorStateChangedClient += _clientDelegate;
_clientSubscribed = true;
}
catch (Exception exception)
{
_clientSubscribed = false;
Report("subscribe client state event", exception);
}
try
{
Actor.OnActorStateChangedServer -= _serverDelegate;
Actor.OnActorStateChangedServer += _serverDelegate;
_serverSubscribed = true;
}
catch (Exception exception2)
{
_serverSubscribed = false;
Report("subscribe server state event", exception2);
}
}
private void UnsubscribeStateEvents()
{
try
{
if ((Delegate)(object)_clientDelegate != (Delegate)null)
{
Actor.OnActorStateChangedClient -= _clientDelegate;
}
}
catch
{
}
try
{
if ((Delegate)(object)_serverDelegate != (Delegate)null)
{
Actor.OnActorStateChangedServer -= _serverDelegate;
}
}
catch
{
}
_clientSubscribed = false;
_serverSubscribed = false;
}
private void ProcessStateEvents(float now)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
StateMessage result;
while (_stateQueue.TryDequeue(out result))
{
if ((Object)(object)result.Actor == (Object)null)
{
continue;
}
Beast beast = Register(result.Actor);
if (beast != null)
{
if (result.Source == "client event")
{
_clientEvents++;
}
else
{
_serverEvents++;
}
beast.LastEventTime = now;
if (IsDead(result.State))
{
MarkDead(beast, result.Source);
}
else if ((int)result.State != 0)
{
beast.Known = true;
beast.Dead = false;
beast.AliveSince = -1f;
}
}
}
}
private static bool IsDead(ActorState state)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Invalid comparison between Unknown and I4
return (state & 1) > 0;
}
private void MarkDead(Beast beast, string source)
{
if (beast.Dead)
{
return;
}
bool num = beast.Known || beast.HasPosition;
beast.Known = true;
beast.Dead = true;
beast.AliveSince = -1f;
if (num)
{
_pendingDeaths.Add(beast.Key);
_detectedDeaths++;
if (_diagnostics)
{
((MelonBase)this).LoggerInstance.Msg("DEATH: actor=" + beast.Key + " source=" + source + " AI=" + beast.IsAI + " positionKnown=" + beast.HasPosition);
}
}
}
private void Tick()
{
if (_insideTick)
{
return;
}
_insideTick = true;
try
{
float unscaledTime = Time.unscaledTime;
if (unscaledTime >= _nextSettings)
{
_nextSettings = unscaledTime + 0.5f;
ReadPreferences();
}
if (unscaledTime >= _nextDiscovery)
{
_nextDiscovery = unscaledTime + 0.5f;
DiscoverActorsAndReferences();
SubscribeStateEvents();
}
if (unscaledTime >= _nextCameraScan)
{
_nextCameraScan = unscaledTime + 1f;
DiscoverCameras();
DiscoverComposers();
}
SampleBeasts(unscaledTime);
ProcessStateEvents(unscaledTime);
BuildCentroid();
if (_pendingDeaths.Count > 0)
{
StartTransition();
_pendingDeaths.Clear();
}
AdvanceTransition();
ApplyDamping();
if (unscaledTime >= _nextAI)
{
_nextAI = unscaledTime + 0.5f;
ApplyAI();
}
if (_diagnostics && unscaledTime >= _nextStatus)
{
_nextStatus = unscaledTime + 10f;
LogStatus(unscaledTime);
}
}
catch (Exception exception)
{
Report("tick", exception);
}
finally
{
_insideTick = false;
}
}
private void LogStatus(float now)
{
int num = 0;
foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
{
RenderState value = renderer.Value;
if (value.ReceivedBrainUpdate)
{
num++;
}
if (!value.ReceivedBrainUpdate && !value.Warned && (Object)(object)value.Camera != (Object)null && ((Behaviour)value.Camera).enabled && now - value.AttachedAt > 8f)
{
value.Warned = true;
((MelonBase)this).LoggerInstance.Warning("No Cinemachine postfix update for camera: " + ((Object)value.Camera).name);
}
}
((MelonBase)this).LoggerInstance.Msg("STATUS: actors=" + _beasts.Count + " living=" + _livingCount + " clientEvents=" + _clientEvents + " serverEvents=" + _serverEvents + " deaths=" + _detectedDeaths + " brainUpdates=" + num + "/" + _renderers.Count + " patchInstalled=" + _brainPatchInstalled + " strength=" + _strength + " subscribed=" + _clientSubscribed + "/" + _serverSubscribed);
}
private Beast Register(Actor actor)
{
if ((Object)(object)actor == (Object)null)
{
return null;
}
int instanceID = ((Object)actor).GetInstanceID();
if (!_beasts.TryGetValue(instanceID, out var value))
{
value = new Beast
{
Key = instanceID,
Actor = actor,
IsAI = actor.IsAI
};
_beasts.Add(instanceID, value);
}
value.Actor = actor;
return value;
}
private void DiscoverActorsAndReferences()
{
if ((Object)(object)_handler == (Object)null)
{
_handler = CMTargetGroupHandler.Instance;
if ((Object)(object)_handler == (Object)null)
{
_handler = Object.FindObjectOfType<CMTargetGroupHandler>();
}
}
if ((Object)(object)_pool == (Object)null)
{
_pool = CMTargetGroupPool.Instance;
if ((Object)(object)_pool == (Object)null)
{
_pool = Object.FindObjectOfType<CMTargetGroupPool>();
}
}
try
{
List<Actor> cachedActors = Actor.CachedActors;
if (cachedActors != null)
{
for (int i = 0; i < cachedActors.Count; i++)
{
Register(cachedActors[i]);
}
}
}
catch (Exception exception)
{
Report("CachedActors", exception);
}
try
{
List<Actor> remoteActors = Actor.RemoteActors;
if (remoteActors != null)
{
for (int j = 0; j < remoteActors.Count; j++)
{
Register(remoteActors[j]);
}
}
}
catch (Exception exception2)
{
Report("RemoteActors", exception2);
}
try
{
List<Actor> localPlayers = Actor.LocalPlayers;
if (localPlayers != null)
{
for (int k = 0; k < localPlayers.Count; k++)
{
Register(localPlayers[k]);
}
}
}
catch (Exception exception3)
{
Report("LocalPlayers", exception3);
}
if ((Object)(object)_handler != (Object)null)
{
List<CMTrackedObject> trackedObjects = _handler.TrackedObjects;
if (trackedObjects != null)
{
for (int l = 0; l < trackedObjects.Count; l++)
{
CMTrackedObject val = trackedObjects[l];
if (val != null)
{
Register(val.beast);
}
}
}
}
Il2CppArrayBase<Actor> val2 = Object.FindObjectsOfType<Actor>();
if (val2 != null)
{
for (int m = 0; m < val2.Length; m++)
{
Register(val2[m]);
}
}
}
private void SampleBeasts(float now)
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: 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_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
_removeKeys.Clear();
foreach (KeyValuePair<int, Beast> beast in _beasts)
{
Beast value = beast.Value;
if ((Object)(object)value.Actor == (Object)null)
{
_removeKeys.Add(beast.Key);
continue;
}
try
{
value.IsAI = value.Actor.IsAI;
if ((Object)(object)value.Target == (Object)null || now >= value.NextTargetRefresh)
{
value.NextTargetRefresh = now + 0.5f;
value.Root = ((Component)value.Actor).transform;
value.Target = value.Actor.GetTrackingTransform();
if ((Object)(object)value.Target == (Object)null)
{
value.Target = value.Root;
}
}
ActorState actorState = value.Actor.actorState;
ActorState network_actorState = value.Actor.Network_actorState;
bool flag = IsDead(actorState) || IsDead(network_actorState);
if (!value.Known)
{
value.Known = true;
value.Dead = flag;
}
else if (flag)
{
MarkDead(value, IsDead(network_actorState) ? "Network_actorState" : "actorState");
}
else if (value.Dead && now - value.LastEventTime > 1f)
{
if (value.AliveSince < 0f)
{
value.AliveSince = now;
}
if (now - value.AliveSince >= 1f)
{
value.Dead = false;
value.AliveSince = -1f;
}
}
if ((!value.Dead || !value.HasPosition) && TryPosition(value.Target, out var position))
{
value.Position = position;
value.HasPosition = true;
}
}
catch (Exception exception)
{
Report("sample beast", exception);
}
}
for (int i = 0; i < _removeKeys.Count; i++)
{
_beasts.Remove(_removeKeys[i]);
}
}
private void BuildCentroid()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: 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_00a4: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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)
//IL_006b: 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)
Vector3 val = Vector3.zero;
int num = 0;
foreach (KeyValuePair<int, Beast> beast in _beasts)
{
Beast value = beast.Value;
if ((Object)(object)value.Actor == (Object)null || value.Dead || !value.HasPosition)
{
continue;
}
try
{
if (!((Component)value.Actor).gameObject.activeInHierarchy)
{
continue;
}
}
catch
{
continue;
}
val += value.Position;
num++;
}
_livingCount = num;
_centroid = ((num > 0) ? (val / (float)num) : Vector3.zero);
}
private void StartTransition()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: 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_009d: 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_00b9: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: 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)
//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_0076: 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_008a: 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)
Beast beast = null;
for (int i = 0; i < _pendingDeaths.Count; i++)
{
if (_beasts.TryGetValue(_pendingDeaths[i], out var value))
{
beast = value;
if (value.HasPosition)
{
break;
}
}
}
if (beast != null && !(_strength <= 0f))
{
Vector3 val = Vector3.zero;
if (beast.HasPosition && _livingCount > 0)
{
val = beast.Position - _centroid;
val.y = 0f;
val = Vector3.ClampMagnitude(val, _sideReach);
}
_startOffset = DisplayOffset();
_peakOffset = Vector3.ClampMagnitude((val + Vector3.up * _depth) * _strength, _maxOffset);
_offset = _startOffset;
_dipProgress = 0f;
_returnProgress = 0f;
_seed = beast.Key;
_startFrame = Time.frameCount;
_transitionId++;
_moving = true;
if (_diagnostics)
{
((MelonBase)this).LoggerInstance.Msg("TRANSITION START: #" + _transitionId + " actor=" + beast.Key + " cameras=" + _renderers.Count + " strength=" + _strength);
}
}
}
private void AdvanceTransition()
{
//IL_0080: 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_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_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)
//IL_00de: 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_00fd: 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_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
int frameCount = Time.frameCount;
if (_advancedFrame == frameCount)
{
return;
}
_advancedFrame = frameCount;
if (_moving && frameCount != _startFrame)
{
float num = Mathf.Max(0f, Time.deltaTime);
if (_dipProgress < 1f)
{
float num2 = Mathf.Min((1f - _dipProgress) * _dipTime, num);
_dipProgress = Mathf.Clamp01(_dipProgress + num2 / _dipTime);
num -= num2;
_offset = Vector3.Lerp(_startOffset, _peakOffset, Curve(_dipProgress));
}
if (_dipProgress >= 1f)
{
_returnProgress = Mathf.Clamp01(_returnProgress + num / _returnTime);
_offset = Vector3.Lerp(_peakOffset, Vector3.zero, Curve(_returnProgress));
}
if (_returnProgress >= 1f)
{
_moving = false;
_offset = Vector3.zero;
_startOffset = Vector3.zero;
}
}
}
private Vector3 DisplayOffset()
{
//IL_0082: 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_0094: 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_009c: 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_0008: Unknown result type (might be due to invalid IL or missing references)
if (!_moving)
{
return Vector3.zero;
}
float num = _dipProgress + _returnProgress;
float num2 = Mathf.Sin((float)Math.PI * Mathf.Clamp01(num * 0.5f));
num2 *= num2;
float num3 = (float)(_seed & 0x3FF) * 0.071f;
Vector3 val = new Vector3(Mathf.Sin(num * 10f + num3), Mathf.Sin(num * 8f + num3) * 0.35f, Mathf.Sin(num * 9f + num3) * 0.25f) * (_roughness * num2);
return Vector3.ClampMagnitude(_offset + val, _maxOffset);
}
private RenderState FindRenderState(Camera camera)
{
if ((Object)(object)camera == (Object)null)
{
return null;
}
foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
{
RenderState value = renderer.Value;
if ((Object)(object)value.Camera != (Object)null && (Object)(object)value.Driver != (Object)null && ((Il2CppObjectBase)value.Camera).Pointer == ((Il2CppObjectBase)camera).Pointer)
{
return value;
}
}
return null;
}
private void DiscoverCameras()
{
_knownCameras.Clear();
_removeRenderers.Clear();
foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
{
RenderState value = renderer.Value;
if ((Object)(object)value.Camera == (Object)null || (Object)(object)value.Driver == (Object)null)
{
_removeRenderers.Add(renderer.Key);
}
else
{
_knownCameras.Add(((Il2CppObjectBase)value.Camera).Pointer);
}
}
for (int i = 0; i < _removeRenderers.Count; i++)
{
IntPtr key = _removeRenderers[i];
if (_renderers.TryGetValue(key, out var value2))
{
Detach(value2);
}
_renderers.Remove(key);
}
Il2CppArrayBase<Camera> val = Object.FindObjectsOfType<Camera>();
bool flag = false;
if (val != null)
{
for (int j = 0; j < val.Length; j++)
{
Camera val2 = val[j];
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).GetComponent<CinemachineBrain>() == (Object)null))
{
flag = true;
Attach(val2);
}
}
}
if (!flag && (Object)(object)Camera.main != (Object)null)
{
Attach(Camera.main);
}
}
private void Attach(Camera camera)
{
if (!((Object)(object)camera == (Object)null) && !_knownCameras.Contains(((Il2CppObjectBase)camera).Pointer))
{
OldCameraRenderDriver oldCameraRenderDriver = ((Component)camera).GetComponent<OldCameraRenderDriver>();
if ((Object)(object)oldCameraRenderDriver == (Object)null)
{
oldCameraRenderDriver = ((Component)camera).gameObject.AddComponent<OldCameraRenderDriver>();
}
((Behaviour)oldCameraRenderDriver).enabled = true;
_renderers[((Il2CppObjectBase)oldCameraRenderDriver).Pointer] = new RenderState
{
Camera = camera,
Transform = ((Component)camera).transform,
Driver = oldCameraRenderDriver,
AttachedAt = Time.unscaledTime
};
_knownCameras.Add(((Il2CppObjectBase)camera).Pointer);
((MelonBase)this).LoggerInstance.Msg("CAMERA REGISTERED: " + ((Object)camera).name + " enabled=" + ((Behaviour)camera).enabled);
}
}
internal void AfterRender(OldCameraRenderDriver driver)
{
if ((Object)(object)driver != (Object)null && _renderers.TryGetValue(((Il2CppObjectBase)driver).Pointer, out var value))
{
RestorePosition(value);
value.HasDisplayedPosition = false;
value.SmoothingMovement = false;
value.LastDisplayedFrame = -1;
value.LastSmoothingFrame = -1;
}
}
private static void RestorePosition(RenderState state)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: 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_0044: Unknown result type (might be due to invalid IL or missing references)
if (!state.Applied)
{
return;
}
try
{
if ((Object)(object)state.Transform != (Object)null)
{
Vector3 val = state.Transform.position - state.WrittenPosition;
if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
{
state.Transform.position = state.BasePosition;
}
}
}
catch
{
}
state.Applied = false;
}
private static void Detach(RenderState state)
{
RestorePosition(state);
if ((Object)(object)state.Driver != (Object)null)
{
try
{
((Behaviour)state.Driver).enabled = false;
Object.Destroy((Object)(object)state.Driver);
}
catch
{
}
}
state.HasDisplayedPosition = false;
state.SmoothingMovement = false;
state.Driver = null;
state.Camera = null;
state.Transform = null;
}
private void ApplyAI()
{
if ((Object)(object)_handler != (Object)null && !_aiCached)
{
_originalTrackAI = _handler.TrackAI;
_originalAIWeight = CMTargetGroupHandler._AITrackingWeight;
_originalAIRadius = CMTargetGroupHandler._AITrackingRadius;
_aiCached = true;
}
if ((Object)(object)_handler != (Object)null && _aiCached)
{
_handler.TrackAI = _trackAI || _originalTrackAI;
CMTargetGroupHandler._AITrackingWeight = (_trackAI ? 1f : _originalAIWeight);
CMTargetGroupHandler._AITrackingRadius = (_trackAI ? 2f : _originalAIRadius);
}
if ((Object)(object)_pool == (Object)null)
{
return;
}
TargetGroupAndTrackingInfo allLiving = _pool.AllLiving;
CinemachineTargetGroup val = ((allLiving != null) ? allLiving.group : null);
if (!((Object)(object)val != (Object)null) || !((Object)(object)_aiGroup != (Object)null) || !(((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)_aiGroup).Pointer))
{
RemoveAddedAI();
_aiGroup = val;
}
if ((Object)(object)val == (Object)null)
{
return;
}
_removeKeys.Clear();
foreach (KeyValuePair<int, Transform> item in _addedAI)
{
if (_trackAI && _beasts.TryGetValue(item.Key, out var value) && (Object)(object)value.Actor != (Object)null && !value.Dead && (Object)(object)value.Target != (Object)null && (Object)(object)item.Value != (Object)null && ((Il2CppObjectBase)value.Target).Pointer == ((Il2CppObjectBase)item.Value).Pointer)
{
continue;
}
if ((Object)(object)item.Value != (Object)null)
{
try
{
val.RemoveMember(item.Value);
}
catch
{
}
}
_removeKeys.Add(item.Key);
}
for (int i = 0; i < _removeKeys.Count; i++)
{
_addedAI.Remove(_removeKeys[i]);
}
if (!_trackAI)
{
return;
}
foreach (KeyValuePair<int, Beast> beast in _beasts)
{
Beast value2 = beast.Value;
if (value2.IsAI && !((Object)(object)value2.Actor == (Object)null) && !value2.Dead && value2.HasPosition && !((Object)(object)value2.Target == (Object)null) && ((Component)value2.Actor).gameObject.activeInHierarchy && !ContainsBeast(val, value2))
{
val.AddMember(value2.Target, 1f, 2f);
_addedAI[value2.Key] = value2.Target;
}
}
}
private static bool ContainsBeast(CinemachineTargetGroup group, Beast beast)
{
Il2CppReferenceArray<Target> targets = group.m_Targets;
if (targets == null)
{
return false;
}
for (int i = 0; i < ((Il2CppArrayBase<Target>)(object)targets).Length; i++)
{
Transform target = ((Il2CppArrayBase<Target>)(object)targets)[i].target;
if ((Object)(object)target == (Object)null)
{
continue;
}
if ((Object)(object)beast.Target != (Object)null && ((Il2CppObjectBase)target).Pointer == ((Il2CppObjectBase)beast.Target).Pointer)
{
return true;
}
Transform val = target;
int num = 0;
while ((Object)(object)val != (Object)null && num < 32)
{
if ((Object)(object)beast.Root != (Object)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)beast.Root).Pointer)
{
return true;
}
val = val.parent;
num++;
}
}
return false;
}
private void RemoveAddedAI()
{
if ((Object)(object)_aiGroup != (Object)null)
{
foreach (KeyValuePair<int, Transform> item in _addedAI)
{
if (!((Object)(object)item.Value == (Object)null))
{
try
{
_aiGroup.RemoveMember(item.Value);
}
catch
{
}
}
}
}
_addedAI.Clear();
_aiGroup = null;
}
private void DiscoverComposers()
{
for (int num = _composers.Count - 1; num >= 0; num--)
{
if ((Object)(object)_composers[num].Composer == (Object)null)
{
_composers.RemoveAt(num);
}
}
_knownComposers.Clear();
for (int i = 0; i < _composers.Count; i++)
{
_knownComposers.Add(((Il2CppObjectBase)_composers[i].Composer).Pointer);
}
Il2CppArrayBase<GangBeastsGroupComposer> val = Object.FindObjectsOfType<GangBeastsGroupComposer>();
if (val == null)
{
return;
}
for (int j = 0; j < val.Length; j++)
{
GangBeastsGroupComposer val2 = val[j];
if (!((Object)(object)val2 == (Object)null) && _knownComposers.Add(((Il2CppObjectBase)val2).Pointer))
{
_composers.Add(new ComposerState
{
Composer = val2,
Original = val2.m_FrameDamping,
Applied = val2.m_FrameDamping
});
}
}
}
private void ApplyDamping()
{
for (int i = 0; i < _composers.Count; i++)
{
ComposerState composerState = _composers[i];
if ((Object)(object)composerState.Composer != (Object)null)
{
composerState.Composer.m_FrameDamping = _damping;
composerState.Applied = _damping;
}
}
}
private void InitializePreferences()
{
_category = MelonPreferences.CreateCategory("OldCameraNetwork", "OldCamera Network");
_pTrackAI = _category.CreateEntry<bool>("TrackAI", true, "Track AI", (string)null, false, false, (ValueValidator)null, (string)null);
_pDiagnostics = _category.CreateEntry<bool>("Diagnostics", true, "Log network and camera stages", (string)null, false, false, (ValueValidator)null, (string)null);
_pDipTime = _category.CreateEntry<float>("DipDuration", 0.85f, "Dip duration in seconds", (string)null, false, false, (ValueValidator)null, (string)null);
_pReturnTime = _category.CreateEntry<float>("ReturnDuration", 2.4f, "Return duration in seconds", (string)null, false, false, (ValueValidator)null, (string)null);
_pDepth = _category.CreateEntry<float>("DipDepth", -1.25f, "Negative moves down", (string)null, false, false, (ValueValidator)null, (string)null);
_pSideReach = _category.CreateEntry<float>("SidewaysReach", 0.65f, "Horizontal movement limit", (string)null, false, false, (ValueValidator)null, (string)null);
_pStrength = _category.CreateEntry<float>("Strength", 1.5f, "Death movement strength", (string)null, false, false, (ValueValidator)null, (string)null);
_pRoughness = _category.CreateEntry<float>("Roughness", 0.022f, "Small motion unevenness", (string)null, false, false, (ValueValidator)null, (string)null);
_pMaxOffset = _category.CreateEntry<float>("MaximumOffset", 3f, "Death offset limit", (string)null, false, false, (ValueValidator)null, (string)null);
_pDamping = _category.CreateEntry<float>("CameraDamping", 4.5f, "Composer damping", (string)null, false, false, (ValueValidator)null, (string)null);
ReadPreferences();
}
private void ReadPreferences()
{
_trackAI = _pTrackAI.Value;
_diagnostics = _pDiagnostics.Value;
_dipTime = Safe(_pDipTime.Value, 0.85f, 0.1f, 8f);
_returnTime = Safe(_pReturnTime.Value, 2.4f, 0.2f, 12f);
_depth = Safe(_pDepth.Value, -1.25f, -5f, 0f);
_sideReach = Safe(_pSideReach.Value, 0.65f, 0f, 2f);
_strength = Safe(_pStrength.Value, 1.5f, 0f, 2f);
_roughness = Safe(_pRoughness.Value, 0.022f, 0f, 0.2f);
_maxOffset = Safe(_pMaxOffset.Value, 3f, 0.1f, 5f);
_damping = Safe(_pDamping.Value, 4.5f, 0.1f, 20f);
}
private void Cleanup()
{
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
_acceptEvents = false;
UnsubscribeStateEvents();
StateMessage result;
while (_stateQueue.TryDequeue(out result))
{
}
foreach (KeyValuePair<IntPtr, RenderState> renderer in _renderers)
{
Detach(renderer.Value);
}
_renderers.Clear();
_knownCameras.Clear();
_removeRenderers.Clear();
RemoveAddedAI();
if (_aiCached)
{
CMTargetGroupHandler._AITrackingWeight = _originalAIWeight;
CMTargetGroupHandler._AITrackingRadius = _originalAIRadius;
if ((Object)(object)_handler != (Object)null)
{
try
{
_handler.TrackAI = _originalTrackAI;
}
catch
{
}
}
}
_aiCached = false;
foreach (ComposerState composer in _composers)
{
if ((Object)(object)composer.Composer == (Object)null)
{
continue;
}
try
{
if (Mathf.Abs(composer.Composer.m_FrameDamping - composer.Applied) < 0.0001f)
{
composer.Composer.m_FrameDamping = composer.Original;
}
}
catch
{
}
}
_composers.Clear();
_knownComposers.Clear();
_beasts.Clear();
_removeKeys.Clear();
_pendingDeaths.Clear();
_handler = null;
_pool = null;
_moving = false;
_offset = Vector3.zero;
_startOffset = Vector3.zero;
_peakOffset = Vector3.zero;
_dipProgress = 0f;
_returnProgress = 0f;
_startFrame = -1;
_advancedFrame = -1;
_livingCount = 0;
_centroid = Vector3.zero;
_insideTick = false;
_insideRender = false;
_nextDiscovery = 0f;
_nextCameraScan = 0f;
_nextSettings = 0f;
_nextAI = 0f;
_nextStatus = 0f;
_clientEvents = 0;
_serverEvents = 0;
_detectedDeaths = 0;
}
private static bool Finite(float value)
{
if (!float.IsNaN(value))
{
return !float.IsInfinity(value);
}
return false;
}
private static bool Finite(Vector3 value)
{
//IL_0000: 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_001a: 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_0039: 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)
if (Finite(value.x) && Finite(value.y) && Finite(value.z) && Mathf.Abs(value.x) < 100000f && Mathf.Abs(value.y) < 100000f)
{
return Mathf.Abs(value.z) < 100000f;
}
return false;
}
private static bool TryPosition(Transform target, out Vector3 position)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
position = Vector3.zero;
if ((Object)(object)target == (Object)null)
{
return false;
}
try
{
position = target.position;
return Finite(position);
}
catch
{
return false;
}
}
private static float Curve(float value)
{
float num = Mathf.Clamp01(value);
return num * num * num * (num * (num * 6f - 15f) + 10f);
}
private static float Safe(float value, float fallback, float min, float max)
{
return Mathf.Clamp(Finite(value) ? value : fallback, min, max);
}
private void Report(string operation, Exception exception)
{
float unscaledTime = Time.unscaledTime;
if (!(unscaledTime - _lastError < 5f))
{
_lastError = unscaledTime;
((MelonBase)this).LoggerInstance.Error(operation + " failed: " + exception);
}
}
}
}