

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.VRMK;
using Il2CppSystem;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using NEP.ScoreLab;
using NEP.ScoreLab.Audio;
using NEP.ScoreLab.Core;
using NEP.ScoreLab.Data;
using NEP.ScoreLab.HUD;
using NEP.ScoreLab.Menu;
using NEP.ScoreLab.Patches;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "ScoreLab", "1.0.0", "Not Enough Photons", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ScoreLab")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0140fb38dafe5a3ef9669f29b961df65def51cb4")]
[assembly: AssemblyProduct("ScoreLab")]
[assembly: AssemblyTitle("ScoreLab")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 NEP.ScoreLab
{
public static class BuildInfo
{
public const string Name = "ScoreLab";
public const string Author = "Not Enough Photons";
public const string Company = "Not Enough Photons";
public const string Version = "1.0.0";
public const string DownloadLink = "https://thunderstore.io/c/bonelab/p/NotEnoughPhotons/ScoreLab";
}
public class Main : MelonMod
{
internal static Instance Logger;
public override void OnLateInitializeMelon()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
Logger = new Instance("ScoreLab");
Settings.CreatePreferences();
Hooks.Initialize();
Hooks.Game.OnMarrowGameStarted = (Action)Delegate.Combine(Hooks.Game.OnMarrowGameStarted, new Action(OnMarrowGameStarted));
Hooks.Game.OnMarrowSceneLoaded = (Action<MarrowSceneInfo>)Delegate.Combine(Hooks.Game.OnMarrowSceneLoaded, new Action<MarrowSceneInfo>(OnMarrowSceneLoaded));
HUDLoader.Initialize();
SLMenu.Initialize();
}
public void OnMarrowGameStarted()
{
ScoreTracker.Initialize();
ValueManager.Initialize();
AudioManager.Initialize();
ScoreDirector.Patches.InitPatches();
}
public void OnMarrowSceneLoaded(MarrowSceneInfo sceneInfo)
{
HUDManager.Initialize();
ScoreTracker.ResetAll();
}
public override void OnUpdate()
{
ScoreTracker.Update();
}
public override void OnDeinitializeMelon()
{
HUDManager.Uninitialize();
AudioManager.Uninitialize();
Settings.Save();
}
}
}
namespace NEP.ScoreLab.Patches
{
public static class Hooks
{
public static class Game
{
public static Action OnMarrowGameStarted;
public static Action<MarrowSceneInfo> OnMarrowSceneLoaded;
private static MarrowSceneInfo _lastScene;
private static MarrowSceneInfo _currentScene;
private static MarrowSceneInfo _nextScene;
public static void Initialize()
{
MarrowGame.RegisterOnReadyAction(Action.op_Implicit((Action)delegate
{
OnMarrowGameStarted?.Invoke();
}));
Hooking.OnLevelLoaded += OnSceneMarrowLoaded;
}
private static void OnSceneMarrowLoaded(LevelInfo info)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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)
MarrowSceneInfo currentScene = default(MarrowSceneInfo);
currentScene.Barcode = info.barcode;
currentScene.LevelTitle = info.title;
currentScene.MarrowScene = ((CrateReferenceT<LevelCrate>)(object)info.levelReference).Crate.MainScene;
_currentScene = currentScene;
_lastScene = _currentScene;
OnMarrowSceneLoaded?.Invoke(_currentScene);
}
}
public static void Initialize()
{
Game.Initialize();
}
}
}
namespace NEP.ScoreLab.Menu
{
public static class SLMenu
{
private static Page _hudPage;
public static void Initialize()
{
//IL_000a: 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_002d: 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_0087: 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)
Page obj = Page.Root.CreatePage("Not Enough Photons", Color.white, 0, true).CreatePage("ScoreLab", Color.white, 0, true);
_hudPage = obj.CreatePage("HUDs", Color.white, 0, true);
obj.CreateFloat("HUD Distance", Color.white, 1.125f, 0.025f, 0f, 2f, (Action<float>)delegate(float value)
{
Settings.DistanceToCamera = value;
});
obj.CreateEnum("Show HUD", Color.white, (Enum)Settings.HUDShowMode, (Action<Enum>)delegate(Enum value)
{
Settings.SetHUDShowMode((HUDShowMode)(object)value);
});
for (int i = 0; i < HUDLoader.LoadedHUDManifests.Count; i++)
{
int index = i;
JSONHUDManifest manifest = HUDLoader.LoadedHUDManifests[index];
_hudPage.CreateFunction(manifest.Name, Color.white, (Action)delegate
{
HUDManager.LoadHUD(manifest.Name);
}).Logo = manifest.Logo;
}
}
public static void RefreshHUDPage()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
_hudPage.RemoveAll();
for (int i = 0; i < HUDLoader.LoadedHUDManifests.Count; i++)
{
int index = i;
JSONHUDManifest manifest = HUDLoader.LoadedHUDManifests[index];
_hudPage.CreateFunction(manifest.Name, Color.white, (Action)delegate
{
HUDManager.LoadHUD(manifest.Name);
}).Logo = manifest.Logo;
}
}
}
}
namespace NEP.ScoreLab.HUD
{
public enum HUDShowMode
{
Always,
UpdateOnly,
Never
}
[RegisterTypeInIl2Cpp]
public class Module : MonoBehaviour
{
public enum UIModuleType
{
Main,
Descriptor
}
public UIModuleType ModuleType;
private bool _reachedDecay;
private bool _reachedPostDecay;
public PackedValue PackedValue => _packedValue;
public virtual PackedValue.PackedType PackedType => PackedValue.PackedType.Base;
public virtual bool CanDecay => (Object)(object)((Component)this).transform.Find("-Persist") == (Object)null;
public float DecayTime => _decayTime;
public float PostDecayTime => _postDecayTime;
protected TextMeshProUGUI _title { get; private set; }
protected TextMeshProUGUI _value { get; private set; }
protected Slider _timeBar { get; private set; }
protected PackedValue _packedValue { get; private set; }
protected bool _canDecay { get; private set; }
protected bool _decayed { get; private set; }
protected float _decayTime { get; private set; }
protected float _postDecayTime { get; private set; }
protected float _tDecay { get; private set; }
protected float _tPostDecay { get; private set; }
private string Path_Root => ((Object)this).name;
protected virtual string Path_TitleText => "Title";
protected virtual string Path_ValueText => "Value";
protected virtual string Path_TimeBar => "TimeBar";
public Module(IntPtr ptr)
: base(ptr)
{
}
public virtual void OnModuleEnable()
{
API.UI.OnModuleEnabled?.Invoke(this);
}
public virtual void OnModuleDisable()
{
API.UI.OnModuleDisabled?.Invoke(this);
}
public virtual void OnUpdate()
{
}
public void AssignPackedData(PackedValue packedValue)
{
if (packedValue != null)
{
_packedValue = packedValue;
if (_packedValue.DecayTime != 0f)
{
SetDecayTime(_packedValue.DecayTime);
}
}
}
public void SetDecayTime(float decayTime)
{
_decayTime = decayTime;
_tDecay = _decayTime;
}
public void SetPostDecayTime(float postDecayTime)
{
_postDecayTime = postDecayTime;
_tPostDecay = _postDecayTime;
}
public bool IsDecaying()
{
return _reachedDecay;
}
public bool IsDecayed()
{
return _reachedPostDecay;
}
protected void SetText(TextMeshProUGUI text, string value)
{
if (!((Object)(object)text == (Object)null))
{
((TMP_Text)text).text = value;
}
}
protected void SetText(TextMeshProUGUI text, int value)
{
if (!((Object)(object)text == (Object)null))
{
SetText(text, value.ToString());
}
}
protected void SetText(TextMeshProUGUI text, float value)
{
if (!((Object)(object)text == (Object)null))
{
SetText(text, value.ToString());
}
}
protected void SetBarValue(Slider timeBar, float value)
{
timeBar.value = value;
}
protected void SetMaxValueToBar(Slider timeBar, float value)
{
if (!((Object)(object)timeBar == (Object)null))
{
timeBar.maxValue = value;
}
}
protected void UpdateDecay()
{
if (!CanDecay)
{
return;
}
if (_tDecay < 0f)
{
if (!_reachedDecay)
{
API.UI.OnModuleDecayed?.Invoke(this);
_reachedDecay = true;
}
_tPostDecay -= Time.deltaTime;
if (_tPostDecay < 0f)
{
if (!_reachedPostDecay)
{
API.UI.OnModulePostDecayed?.Invoke(this);
_reachedPostDecay = true;
}
_tDecay = _decayTime;
_tPostDecay = _postDecayTime;
_reachedDecay = false;
_reachedPostDecay = false;
((Component)this).gameObject.SetActive(false);
}
}
else
{
_tDecay -= Time.deltaTime;
}
}
private void Start()
{
Transform val = ((Component)this).transform.Find(Path_TitleText);
Transform val2 = ((Component)this).transform.Find(Path_ValueText);
Transform val3 = ((Component)this).transform.Find(Path_TimeBar);
_title = ((val != null) ? ((Component)val).GetComponent<TextMeshProUGUI>() : null);
_value = ((val2 != null) ? ((Component)val2).GetComponent<TextMeshProUGUI>() : null);
_timeBar = ((val3 != null) ? ((Component)val3).GetComponent<Slider>() : null);
}
private void OnEnable()
{
OnModuleEnable();
}
private void OnDisable()
{
OnModuleEnable();
}
private void Update()
{
OnUpdate();
}
}
[RegisterTypeInIl2Cpp]
public class ModuleAnimator : MonoBehaviour
{
public Animator Animator;
private Module _module;
public ModuleAnimator(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
_module = ((Component)this).GetComponent<Module>();
Animator = ((Component)this).GetComponent<Animator>();
}
private void OnEnable()
{
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, (Action<PackedValue>)delegate
{
OnTierReached();
});
API.UI.OnModuleDecayed = (Action<Module>)Delegate.Combine(API.UI.OnModuleDecayed, new Action<Module>(OnModuleDecayed));
}
private void OnDisable()
{
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, (Action<PackedValue>)delegate
{
OnTierReached();
});
API.UI.OnModuleDecayed = (Action<Module>)Delegate.Remove(API.UI.OnModuleDecayed, new Action<Module>(OnModuleDecayed));
}
private void PlayAnimation(string name)
{
if (!((Object)(object)Animator == (Object)null))
{
Animator.Play(name, -1, 0f);
}
}
private void OnModuleEnabled(Module module)
{
if (!((Object)(object)_module != (Object)(object)module))
{
if (_module.ModuleType == Module.UIModuleType.Descriptor)
{
PlayAnimation("descriptor_show");
}
else
{
PlayAnimation("show");
}
}
}
private void OnTierReached()
{
PlayAnimation("tier_reached");
}
private void OnModuleDecayed(Module module)
{
if (!((Object)(object)_module != (Object)(object)module))
{
if (_module.ModuleType == Module.UIModuleType.Descriptor)
{
PlayAnimation("descriptor_hide");
}
else
{
PlayAnimation("hide");
}
}
}
}
[RegisterTypeInIl2Cpp]
public class MultiplierModule : Module
{
private float _currentValue;
private float _targetValue;
private float _rate;
private PackedMultiplier _packedMultiplier => (PackedMultiplier)base._packedValue;
public MultiplierModule(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
if (((Object)this).name == "MultiplierDescriptor" || ((Object)this).name == "Descriptor")
{
ModuleType = UIModuleType.Descriptor;
}
}
public override void OnModuleEnable()
{
base.OnModuleEnable();
if (base._packedValue == null || _packedMultiplier == null)
{
return;
}
if (ModuleType == UIModuleType.Main)
{
SetText(base._value, ScoreTracker.Multiplier + "x");
}
else if (ModuleType == UIModuleType.Descriptor)
{
SetText(base._title, _packedMultiplier.Name);
SetText(base._value, _packedMultiplier.Multiplier + "x");
}
if ((Object)(object)base._timeBar != (Object)null)
{
if (_packedMultiplier.Condition != string.Empty)
{
((Component)base._timeBar).gameObject.SetActive(false);
return;
}
((Component)base._timeBar).gameObject.SetActive(true);
SetMaxValueToBar(base._timeBar, _packedMultiplier.DecayTime);
SetBarValue(base._timeBar, _packedMultiplier.DecayTime);
}
}
public override void OnModuleDisable()
{
}
public override void OnUpdate()
{
if (ModuleType == UIModuleType.Main)
{
SetTweenValue(ScoreTracker.Multiplier);
_currentValue = Mathf.MoveTowards(_currentValue, _targetValue, _rate * Time.unscaledDeltaTime);
if (Mathf.Approximately(_currentValue, _targetValue))
{
_currentValue = _targetValue;
}
SetText(base._value, _currentValue.ToString("F2"));
}
if (_packedMultiplier != null)
{
if (_packedMultiplier.condition != null)
{
if (!_packedMultiplier.condition())
{
UpdateDecay();
}
}
else
{
UpdateDecay();
}
}
else
{
UpdateDecay();
}
if ((Object)(object)base._timeBar != (Object)null)
{
SetBarValue(base._timeBar, base._tDecay);
}
}
private void SetTweenValue(float value)
{
_targetValue = value;
_rate = Mathf.Abs(_targetValue - _currentValue) / 1f;
}
}
[RegisterTypeInIl2Cpp]
public class ScoreModule : Module
{
private float _targetValue;
private float _currentValue;
private float _rate = 4f;
private PackedScore _packedScore => (PackedScore)base._packedValue;
public ScoreModule(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
if (((Object)this).name == "ScoreDescriptor" || ((Object)this).name == "Descriptor")
{
ModuleType = UIModuleType.Descriptor;
}
}
public override void OnModuleEnable()
{
base.OnModuleEnable();
if (ModuleType == UIModuleType.Main)
{
SetText(base._value, ScoreTracker.Score);
}
if (base._packedValue != null && ModuleType == UIModuleType.Descriptor)
{
SetText(base._title, _packedScore.Name);
SetText(base._value, $"+{Mathf.RoundToInt((float)_packedScore.Score * ScoreTracker.Multiplier)}");
}
}
public override void OnModuleDisable()
{
}
public override void OnUpdate()
{
UpdateDecay();
if (ModuleType == UIModuleType.Main)
{
SetTweenValue(ScoreTracker.Score);
_currentValue = Mathf.MoveTowards(_currentValue, _targetValue, _rate * Time.unscaledDeltaTime);
if (Mathf.Approximately(_currentValue, _targetValue))
{
_currentValue = _targetValue;
}
SetText(base._value, _currentValue.ToString("N0"));
}
}
private void SetTweenValue(int value)
{
_targetValue = value;
_rate = Mathf.Abs(_targetValue - _currentValue) / 1f;
}
}
[RegisterTypeInIl2Cpp]
public class HUD : MonoBehaviour
{
public Transform followTarget;
public Module ScoreModule { get; set; }
public Module MultiplierModule { get; set; }
public Module HighScoreModule { get; set; }
public HUD(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
if ((Object)(object)((Component)this).transform.Find("MainScore") != (Object)null)
{
ScoreModule = ((Component)((Component)this).transform.Find("MainScore")).GetComponent<ScoreModule>();
}
if (Object.op_Implicit((Object)(object)((Component)this).transform.Find("MainMultiplier")))
{
MultiplierModule = ((Component)((Component)this).transform.Find("MainMultiplier")).GetComponent<MultiplierModule>();
}
}
private void OnEnable()
{
UpdateModule(null);
UpdateModule(null);
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAdded, new Action<PackedValue>(UpdateModule));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, new Action<PackedValue>(UpdateModule));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAccumulated, new Action<PackedValue>(UpdateModule));
API.Value.OnValueRemoved = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueRemoved, new Action<PackedValue>(UpdateModule));
}
private void OnDisable()
{
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAdded, new Action<PackedValue>(UpdateModule));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, new Action<PackedValue>(UpdateModule));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAccumulated, new Action<PackedValue>(UpdateModule));
API.Value.OnValueRemoved = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueRemoved, new Action<PackedValue>(UpdateModule));
}
private void Start()
{
if ((Object)(object)Player.GetPhysicsRig() != (Object)null)
{
followTarget = ((Rig)Player.ControllerRig).m_head;
}
}
private void FixedUpdate()
{
//IL_0015: 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_002b: 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_003a: 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_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_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: 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)
if (!((Object)(object)followTarget == (Object)null))
{
Vector3 position = Vector3.Lerp(((Component)this).transform.position, followTarget.position + followTarget.forward * Settings.DistanceToCamera, Settings.MovementSmoothness * Time.unscaledDeltaTime);
Quaternion rotation = Quaternion.LookRotation(followTarget.forward);
((Component)this).transform.position = position;
((Component)this).transform.rotation = rotation;
}
}
public void SetParent(Transform parent)
{
((Component)this).transform.SetParent(parent);
}
public void SetScoreModule(Module module)
{
ScoreModule = module;
}
public void SetMultiplierModule(Module module)
{
MultiplierModule = module;
}
public void UpdateModule(PackedValue data)
{
if (data is PackedScore)
{
ScoreModule.AssignPackedData(data);
ScoreModule.OnModuleEnable();
}
else if (data is PackedMultiplier)
{
MultiplierModule.AssignPackedData(data);
MultiplierModule.OnModuleEnable();
}
}
}
[RegisterTypeInIl2Cpp]
public class DescriptorList : MonoBehaviour
{
public List<Module> ActiveModules;
public int count = 6;
public List<Module> Modules;
public PackedValue.PackedType packedType { get; set; }
public GameObject ModulePrefab { get; set; }
public DescriptorList(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
Modules = new List<Module>();
ActiveModules = new List<Module>();
for (int i = 0; i < ((Component)this).transform.childCount; i++)
{
Transform child = ((Component)this).transform.GetChild(i);
Modules.Add(((Component)child).GetComponent<Module>());
}
if (((Object)this).name == "ScoreDescriptors")
{
packedType = PackedValue.PackedType.Score;
}
else if (((Object)this).name == "MultiplierDescriptors")
{
packedType = PackedValue.PackedType.Multiplier;
}
}
private void OnEnable()
{
API.UI.OnModulePostDecayed = (Action<Module>)Delegate.Combine(API.UI.OnModulePostDecayed, (Action<Module>)delegate(Module item)
{
ActiveModules.Remove(item);
});
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAdded, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAccumulated, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, new Action<PackedValue>(SetModuleActive));
}
private void OnDisable()
{
API.UI.OnModulePostDecayed = (Action<Module>)Delegate.Remove(API.UI.OnModulePostDecayed, (Action<Module>)delegate(Module item)
{
ActiveModules.Remove(item);
});
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAdded, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAccumulated, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, new Action<PackedValue>(SetModuleActive));
}
public void SetPackedType(int packedType)
{
this.packedType = (PackedValue.PackedType)packedType;
}
public void SetModuleActive(PackedValue value)
{
if (Modules == null || Modules.Count == 0 || value.PackedValueType != packedType)
{
return;
}
foreach (Module module in Modules)
{
if (!((Component)module).gameObject.activeInHierarchy)
{
module.AssignPackedData(value);
module.SetDecayTime(value.DecayTime);
module.SetPostDecayTime(0.5f);
((Component)module).gameObject.SetActive(true);
ActiveModules.Add(module);
break;
}
if (ActiveModules.Contains(module) && !module.IsDecaying() && module.PackedValue.eventType == value.eventType)
{
if (value.Stackable)
{
module.AssignPackedData(value);
module.OnModuleEnable();
module.SetDecayTime(value.DecayTime);
module.SetPostDecayTime(0.5f);
break;
}
if (value.Tiers != null)
{
module.AssignPackedData(value);
module.OnModuleEnable();
module.SetDecayTime(value.DecayTime);
module.SetPostDecayTime(0.5f);
break;
}
}
}
}
public void PoolObjects()
{
if (!((Object)(object)ModulePrefab == (Object)null))
{
for (int i = 0; i < count; i++)
{
Module component = Object.Instantiate<GameObject>(ModulePrefab, ((Component)this).transform).GetComponent<Module>();
component.ModuleType = Module.UIModuleType.Descriptor;
Modules.Add(component);
}
}
}
}
public static class HUDManager
{
private static GameObject _parentObject;
public static List<HUD> LoadedHUDs { get; private set; }
public static HUD ActiveHUD { get; private set; }
public static HUD LastHUD { get; private set; }
internal static void Initialize()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
_parentObject = new GameObject("[ScoreLab] - HUD Container");
LoadedHUDs = new List<HUD>();
Populate();
if (HUDLoader.LoadedHUDs.ContainsKey(Settings.SavedHUD))
{
LoadHUD(Settings.SavedHUD);
}
else
{
LoadHUD("Coda");
}
}
internal static void Uninitialize()
{
}
public static void Populate()
{
for (int i = 0; i < HUDLoader.LoadedHUDManifests.Count; i++)
{
JSONHUDManifest jSONHUDManifest = HUDLoader.LoadedHUDManifests[i];
GameObject obj = Object.Instantiate<GameObject>(HUDLoader.LoadedHUDs[jSONHUDManifest.Name]);
((Object)obj).name = jSONHUDManifest.Name;
HUD component = obj.GetComponent<HUD>();
if (!((Object)(object)component == (Object)null))
{
LoadedHUDs.Add(component);
component.SetParent(_parentObject.transform);
((Component)component).gameObject.SetActive(false);
}
}
}
public static void HUDShowModeUpdated(HUDShowMode mode)
{
if (!((Object)(object)ActiveHUD == (Object)null))
{
switch (mode)
{
case HUDShowMode.Always:
((Component)ActiveHUD).gameObject.SetActive(true);
break;
case HUDShowMode.Never:
((Component)ActiveHUD).gameObject.SetActive(false);
break;
}
}
}
public static void LoadHUD(string name)
{
if ((Object)(object)ActiveHUD != (Object)null)
{
LastHUD = ActiveHUD;
}
UnloadHUD();
foreach (HUD loadedHUD in LoadedHUDs)
{
if (((Object)loadedHUD).name == name)
{
ActiveHUD = loadedHUD;
break;
}
}
if (!((Object)(object)ActiveHUD == (Object)null))
{
Settings.SavedHUD = name;
ValueManager.UsePackage(name);
((Component)ActiveHUD).gameObject.SetActive(true);
ActiveHUD.SetParent(null);
}
}
public static void UnloadHUD()
{
if ((Object)(object)ActiveHUD != (Object)null)
{
ActiveHUD.SetParent(_parentObject.transform);
((Component)ActiveHUD).gameObject.SetActive(false);
ActiveHUD = null;
}
}
public static void DestroyHUD()
{
if ((Object)(object)ActiveHUD != (Object)null)
{
Object.Destroy((Object)(object)ActiveHUD);
ActiveHUD = null;
}
}
public static void DestroyLoadedHUDs()
{
if (LoadedHUDs == null || LoadedHUDs.Count == 0)
{
return;
}
foreach (HUD loadedHUD in LoadedHUDs)
{
Object.Destroy((Object)(object)((Component)loadedHUD).gameObject);
}
LoadedHUDs.Clear();
}
}
}
namespace NEP.ScoreLab.Data
{
public static class HUDLoader
{
public static Dictionary<string, AudioClip> HUDAudioBank;
public static Dictionary<string, GameObject> LoadedHUDs;
public static List<JSONHUDManifest> LoadedHUDManifests;
private static List<AssetBundle> _assetBundles;
private static List<Object> _persistentBundleObjects;
public static void Initialize()
{
LoadedHUDs = new Dictionary<string, GameObject>();
HUDAudioBank = new Dictionary<string, AudioClip>();
LoadedHUDManifests = new List<JSONHUDManifest>();
_persistentBundleObjects = new List<Object>();
_assetBundles = new List<AssetBundle>();
LoadHUDs();
}
public static void SpawnDefaultUI()
{
SpawnUI("Coda");
}
public static void SpawnUI(string name)
{
foreach (JSONHUDManifest loadedHUDManifest in LoadedHUDManifests)
{
if (loadedHUDManifest.Name == name)
{
SpawnUI(LoadedHUDs[name]);
}
}
}
public static void SpawnUI(GameObject uiObject)
{
Object.Instantiate<GameObject>(uiObject);
}
public static void LoadHUDs()
{
foreach (string item2 in Directory.EnumerateDirectories(Path.Combine(MelonEnvironment.UserDataDirectory, "Not Enough Photons/ScoreLab")))
{
IEnumerable<string> enumerable = Directory.EnumerateFiles(item2);
string text = string.Empty;
string text2 = string.Empty;
foreach (string item3 in enumerable)
{
if (item3.EndsWith(".hud"))
{
text = item3;
}
if (item3.EndsWith(".hud_manifest"))
{
text2 = item3;
}
}
if (text == string.Empty)
{
Main.Logger.Error("Missing .HUD file in " + item2 + "!");
continue;
}
if (text2 == string.Empty)
{
Main.Logger.Error("Missing HUD manifest file in " + item2 + "!");
continue;
}
JSONHUDManifest item = default(JSONHUDManifest);
if (!item.FromJSON(text2))
{
Main.Logger.Error("Failed to read HUD manifest data! Source: " + item2);
continue;
}
AssetBundle val = AssetBundle.LoadFromFile(text);
GameObject value = HelperMethods.LoadPersistentAsset<GameObject>(val, item.AssetName);
Il2CppReferenceArray<Object> val2 = val.LoadAllAssets();
Texture2D val3 = HelperMethods.LoadPersistentAsset<Texture2D>(val, "Logo");
if ((Object)(object)val3 != (Object)null)
{
item.SetHUDLogo(val3);
}
_assetBundles.Add(val);
LoadedHUDManifests.Add(item);
LoadedHUDs.Add(item.Name, value);
if (val2 == null || ((Il2CppArrayBase<Object>)(object)val2).Length == 0)
{
continue;
}
foreach (Object item4 in (Il2CppArrayBase<Object>)(object)val2)
{
AudioClip val4 = ((Il2CppObjectBase)item4).TryCast<AudioClip>();
if ((Object)(object)val4 != (Object)null)
{
((Object)val4).hideFlags = (HideFlags)32;
HUDAudioBank.Add(item4.name, val4);
}
}
}
}
public static void ReloadHUDs()
{
if ((Object)(object)HUDManager.ActiveHUD != (Object)null)
{
HUDManager.DestroyHUD();
}
HUDManager.DestroyLoadedHUDs();
HUDAudioBank.Clear();
LoadedHUDManifests.Clear();
LoadedHUDs.Clear();
foreach (AssetBundle assetBundle in _assetBundles)
{
assetBundle.Unload(true);
}
_assetBundles.Clear();
LoadHUDs();
SLMenu.RefreshHUDPage();
HUDManager.Populate();
HUDManager.LoadHUD(Settings.SavedHUD);
}
}
public struct JSONAudioParams
{
public string[] sounds;
public float volume;
public float pitch;
public bool FromJSON(JObject jObject)
{
if (jObject == null)
{
return false;
}
JToken obj = jObject["Clips"];
JArray val = (JArray)(object)((obj is JArray) ? obj : null);
if (val != null)
{
sounds = new string[((JContainer)val).Count];
for (int i = 0; i < sounds.Length; i++)
{
sounds[i] = Extensions.Value<string>((IEnumerable<JToken>)val[i]);
}
}
volume = Extensions.Value<float>((IEnumerable<JToken>)jObject["Volume"]);
pitch = Extensions.Value<float>((IEnumerable<JToken>)jObject["Pitch"]);
return true;
}
}
public struct JSONHUDManifest
{
public string Name;
public string Author;
public string Description;
public string[] Tags;
public string AssetName;
public Texture2D Logo;
public bool FromJSON(string pathToJson)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using (StreamReader streamReader = new StreamReader(pathToJson))
{
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
JToken obj = JToken.ReadFrom((JsonReader)(object)val);
JObject val2 = (JObject)(object)((obj is JObject) ? obj : null);
if (val2 == null)
{
return false;
}
Name = Extensions.Value<string>((IEnumerable<JToken>)val2["name"]);
Author = Extensions.Value<string>((IEnumerable<JToken>)val2["author"]);
AssetName = Extensions.Value<string>((IEnumerable<JToken>)val2["assetName"]);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
return true;
}
public void SetHUDLogo(Texture2D texture)
{
Logo = texture;
}
}
public struct JSONMult
{
public string EventType;
public string TierEventType;
public float DecayTime;
public bool Stackable;
public JSONAudioParams EventAudio;
public string Name;
public float Multiplier;
public string Condition;
public int TierRequirement;
public JSONMult[] Tiers;
public bool FromJSON(string pathToJson)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using (StreamReader streamReader = new StreamReader(pathToJson))
{
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
JToken obj = JToken.ReadFrom((JsonReader)(object)val);
JObject val2 = (JObject)(object)((obj is JObject) ? obj : null);
if (val2 == null)
{
return false;
}
ReadMultObject(val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
return true;
}
private void ReadMultObject(JObject obj)
{
EventType = Extensions.Value<string>((IEnumerable<JToken>)obj["EventType"]);
DecayTime = Extensions.Value<float>((IEnumerable<JToken>)obj["DecayTime"]);
Stackable = Extensions.Value<bool>((IEnumerable<JToken>)obj["Stackable"]);
Condition = Extensions.Value<string>((IEnumerable<JToken>)obj["Condition"]);
EventAudio.FromJSON(Extensions.Value<JObject>((IEnumerable<JToken>)obj["EventAudio"]));
Name = Extensions.Value<string>((IEnumerable<JToken>)obj["Name"]);
Multiplier = Extensions.Value<float>((IEnumerable<JToken>)obj["Multiplier"]);
TierRequirement = Extensions.Value<int>((IEnumerable<JToken>)obj["TierRequirement"]);
JToken obj2 = obj["Tiers"];
JArray val = ((obj2 != null) ? Extensions.Value<JArray>((IEnumerable<JToken>)obj2) : null);
List<JSONMult> list = new List<JSONMult>();
if (val != null)
{
for (int i = 0; i < ((JContainer)val).Count; i++)
{
JSONMult item = default(JSONMult);
JToken obj3 = val[i];
JObject obj4 = (JObject)(object)((obj3 is JObject) ? obj3 : null);
item.ReadMultObject(obj4);
list.Add(item);
}
Tiers = list.ToArray();
}
}
}
public struct JSONScore
{
public string EventType;
public string TierEventType;
public float DecayTime;
public bool Stackable;
public JSONAudioParams EventAudio;
public string Name;
public int Score;
public int TierRequirement;
public JSONScore[] Tiers;
public bool FromJSON(string pathToJson)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using (StreamReader streamReader = new StreamReader(pathToJson))
{
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
JToken obj = JToken.ReadFrom((JsonReader)(object)val);
JObject val2 = (JObject)(object)((obj is JObject) ? obj : null);
if (val2 == null)
{
return false;
}
ReadScoreObject(val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
return true;
}
private void ReadScoreObject(JObject obj)
{
EventType = Extensions.Value<string>((IEnumerable<JToken>)obj["EventType"]);
DecayTime = Extensions.Value<float>((IEnumerable<JToken>)obj["DecayTime"]);
Stackable = Extensions.Value<bool>((IEnumerable<JToken>)obj["Stackable"]);
EventAudio.FromJSON(Extensions.Value<JObject>((IEnumerable<JToken>)obj["EventAudio"]));
Name = Extensions.Value<string>((IEnumerable<JToken>)obj["Name"]);
Score = Extensions.Value<int>((IEnumerable<JToken>)obj["Score"]);
TierRequirement = Extensions.Value<int>((IEnumerable<JToken>)obj["TierRequirement"]);
JToken obj2 = obj["Tiers"];
JArray val = ((obj2 != null) ? Extensions.Value<JArray>((IEnumerable<JToken>)obj2) : null);
List<JSONScore> list = new List<JSONScore>();
if (val != null)
{
for (int i = 0; i < ((JContainer)val).Count; i++)
{
JSONScore item = default(JSONScore);
JToken obj3 = val[i];
JObject obj4 = (JObject)(object)((obj3 is JObject) ? obj3 : null);
item.ReadScoreObject(obj4);
list.Add(item);
}
Tiers = list.ToArray();
}
}
}
public struct MarrowSceneInfo
{
public string LevelTitle;
public string Barcode;
public MarrowScene MarrowScene;
}
public static class EventType
{
public static class Score
{
public static readonly string Kill = "SCORE_KILL";
public static readonly string Headshot = "SCORE_HEADSHOT";
public static readonly string EnemyMidAirKill = "SCORE_MID_AIR";
public static readonly string GameWaveCompleted = "SCORE_WAVE_COMPLETED";
public static readonly string GameRoundCompleted = "SCORE_ROUND_COMPLETED";
public static readonly string Crabcest = "SCORE_CRABCEST";
public static readonly string Facehug = "SCORE_FACEHUG";
public static readonly string StealthKill = "SCORE_STEALTH_KILL";
}
public static class Mult
{
public static readonly string Kill = "MULT_KILL";
public static readonly string MidAir = "MULT_MIDAIR";
public static readonly string Seated = "MULT_SEATED";
public static readonly string SecondWind = "MULT_SECONDWIND";
public static readonly string Ragolled = "MULT_RAGDOLLED";
public static readonly string SwappedAvatars = "MULT_SWAPPED_AVATARS";
public static readonly string SlowMo = "MULT_SLOWMO";
}
public static readonly string None = "None";
}
public class PackedAudioParams
{
public AudioClip[] Clips { get; private set; }
public float Volume { get; private set; }
public float Pitch { get; private set; }
public PackedAudioParams()
{
Clips = null;
Volume = 1f;
Pitch = 1f;
}
public PackedAudioParams(JSONAudioParams audioParams)
{
Clips = (AudioClip[])(object)new AudioClip[audioParams.sounds.Length];
for (int i = 0; i < Clips.Length; i++)
{
Clips[i] = HUDLoader.HUDAudioBank[audioParams.sounds[i]];
}
Volume = audioParams.volume;
Pitch = audioParams.pitch;
}
}
public class PackedHighScore : PackedValue
{
public int bestScore;
public override PackedType PackedValueType => PackedType.HighScore;
public PackedHighScore(string name, int bestScore)
{
this.bestScore = bestScore;
}
public override void OnValueCreated()
{
}
public override void OnValueRemoved()
{
}
}
[Serializable]
public class PackedMultiplier : PackedValue
{
public float Multiplier;
public float AccumulatedMultiplier;
public string Condition;
private bool _timed;
private bool _timeBegin;
public override PackedType PackedValueType => PackedType.Multiplier;
public float Elapsed => _tDecay;
public Func<bool> condition { get; private set; }
public PackedMultiplier()
{
}
public PackedMultiplier(JSONMult mult, bool useTiers = false)
{
eventType = mult.EventType;
DecayTime = mult.DecayTime;
Stackable = mult.Stackable;
Name = mult.Name;
Multiplier = mult.Multiplier;
Condition = mult.Condition;
TierRequirement = mult.TierRequirement;
EventAudio = new PackedAudioParams(mult.EventAudio);
if (useTiers)
{
TierEventType = mult.TierEventType;
}
}
public override void OnValueCreated()
{
if (DecayTime != 0f)
{
_timed = true;
}
condition = API.GameConditions.GetCondition(Condition);
AccumulatedMultiplier = Multiplier;
_tDecay = DecayTime;
}
public override void OnValueRemoved()
{
_timeBegin = false;
ResetTier();
}
public override void OnUpdate()
{
if (condition != null && !condition())
{
ScoreTracker.Remove(this);
}
OnUpdateDecay();
}
public override void OnUpdateDecay()
{
if (_timed)
{
if (!_timeBegin)
{
API.Multiplier.OnMultiplierTimeBegin?.Invoke(this);
_timeBegin = true;
}
if (_tDecay <= 0f)
{
API.Multiplier.OnMultiplierTimeExpired?.Invoke(this);
_tDecay = DecayTime;
ScoreTracker.Remove(this);
}
_tDecay -= Time.deltaTime;
}
}
}
[Serializable]
public class PackedScore : PackedValue
{
public int Score;
public int AccumulatedScore;
public override PackedType PackedValueType => PackedType.Score;
public PackedScore()
{
}
public PackedScore(JSONScore score, bool useTiers = false)
{
eventType = score.EventType;
DecayTime = score.DecayTime;
Stackable = score.Stackable;
Name = score.Name;
Score = score.Score;
TierRequirement = score.TierRequirement;
EventAudio = new PackedAudioParams(score.EventAudio);
if (useTiers)
{
TierEventType = score.TierEventType;
}
else
{
AccumulatedScore = score.Score;
}
}
public override void OnValueCreated()
{
_tDecay = DecayTime;
AccumulatedScore = Score;
}
public override void OnValueRemoved()
{
ResetTier();
}
public override void OnUpdate()
{
OnUpdateDecay();
}
public override void OnUpdateDecay()
{
if (_tDecay <= 0f)
{
ScoreTracker.Remove(this);
}
_tDecay -= Time.deltaTime;
}
}
[Serializable]
public class PackedValue
{
public enum PackedType
{
Base,
Score,
Multiplier,
HighScore,
Misc
}
public string Name;
public string eventType;
public string TierEventType;
public PackedAudioParams EventAudio;
public bool Stackable;
public float DecayTime;
public float PostDecayTime;
public PackedValue Parent;
public PackedValue[] Tiers;
public int TierRequirement;
protected float _tDecay;
private int _tierIndex;
private int _tierRequirementIndex;
public virtual PackedType PackedValueType => PackedType.Base;
public PackedValue CurrentTier
{
get
{
if (Tiers == null || Tiers.Length == 0)
{
return this;
}
if (_tierIndex == Tiers.Length)
{
_tierIndex = Tiers.Length;
return Tiers[_tierIndex];
}
return Tiers[_tierIndex];
}
}
public PackedValue NextTier
{
get
{
if (_tierIndex + 1 >= Tiers.Length)
{
return Tiers[_tierIndex];
}
return Tiers[_tierIndex + 1];
}
}
public int TierIndex => _tierIndex;
public int TierRequirementIndex => _tierRequirementIndex;
public virtual bool IsActive { get; }
public virtual void OnValueCreated()
{
}
public virtual void OnValueRemoved()
{
}
public virtual void OnUpdate()
{
}
public virtual void OnUpdateDecay()
{
}
public void SetDecayTime(float decayTime)
{
_tDecay = decayTime;
}
public void ToNextTier()
{
_tierRequirementIndex++;
if (_tierRequirementIndex >= TierRequirement)
{
_tierRequirementIndex = TierRequirement;
API.Value.OnValueTierReached?.Invoke(CurrentTier);
if (_tierIndex + 1 < Tiers.Length)
{
_tierIndex++;
}
}
}
protected void ResetTier()
{
_tierIndex = 0;
}
}
public static class ValueManager
{
public static Dictionary<string, int> HighScoreTable;
public static readonly string Path_Developer = Path.Combine(MelonEnvironment.UserDataDirectory, "Not Enough Photons");
public static readonly string Path_Mod = Path.Combine(Path_Developer, "ScoreLab");
private static readonly string File_HighScores = Path.Combine(Path_Mod, "high_score_table.json");
public static Dictionary<string, ValuePackage> Packages { get; private set; }
public static ValuePackage ActivePackage { get; private set; }
public static void Initialize()
{
HighScoreTable = new Dictionary<string, int>();
Packages = new Dictionary<string, ValuePackage>();
foreach (JSONHUDManifest loadedHUDManifest in HUDLoader.LoadedHUDManifests)
{
JSONScore[] scoresForHUD = GetScoresForHUD(loadedHUDManifest.Name);
JSONMult[] multipliersForHUD = GetMultipliersForHUD(loadedHUDManifest.Name);
PackedScore[] scores = CreateScoreObjects(scoresForHUD);
PackedMultiplier[] multipliers = CreateMultiplierObjects(multipliersForHUD);
Packages.Add(loadedHUDManifest.Name, new ValuePackage(scores, multipliers));
}
UsePackage(Settings.SavedHUD);
}
public static string[] GetAllFiles(string path, string extensionFilter)
{
string[] files = Directory.GetFiles(path);
List<string> list = new List<string>();
string[] array = files;
foreach (string text in array)
{
if (text.EndsWith(extensionFilter))
{
list.Add(text);
}
}
return list.ToArray();
}
public static void UsePackage(string name)
{
if (Packages.TryGetValue(name, out var value))
{
ActivePackage = value;
}
}
public static PackedValue Get(string eventType)
{
if (ActivePackage.Values == null)
{
return null;
}
if (ActivePackage.Values.TryGetValue(eventType, out var value))
{
return value;
}
return null;
}
public static Dictionary<string, int> ReadHighScore()
{
return JsonConvert.DeserializeObject(File_HighScores) as Dictionary<string, int>;
}
public static void WriteHighScore()
{
string file_HighScores = File_HighScores;
if (!File.Exists(file_HighScores))
{
Main.Logger.Warning("High score file doesn't exist! Creating one.");
File.Create(file_HighScores);
}
else
{
string contents = JsonConvert.SerializeObject((object)HighScoreTable);
File.WriteAllText(file_HighScores, contents);
}
}
public static void WriteBestScore(PackedHighScore highScore)
{
string name = highScore.Name;
int bestScore = highScore.bestScore;
HighScoreTable.Add(name, bestScore);
}
private static JSONScore[] GetScoresForHUD(string name)
{
string path = Path.Combine(Path_Mod, name + "/Data/Score");
if (!Directory.Exists(path))
{
Main.Logger.Warning("HUD " + name + " doesn't have a score data folder!");
return null;
}
string[] allFiles = GetAllFiles(path, ".json");
List<JSONScore> list = new List<JSONScore>();
string[] array = allFiles;
for (int i = 0; i < array.Length; i++)
{
JSONScore item = ReadScoreData(array[i]);
list.Add(item);
}
return list.ToArray();
}
private static JSONMult[] GetMultipliersForHUD(string name)
{
string path = Path.Combine(Path_Mod, name + "/Data/Multiplier");
if (!Directory.Exists(path))
{
Main.Logger.Warning("HUD " + name + " doesn't have a multiplier data folder!");
return null;
}
string[] allFiles = GetAllFiles(path, ".json");
List<JSONMult> list = new List<JSONMult>();
string[] array = allFiles;
for (int i = 0; i < array.Length; i++)
{
JSONMult item = ReadMultiplierData(array[i]);
list.Add(item);
}
return list.ToArray();
}
private static PackedScore[] CreateScoreObjects(JSONScore[] scores)
{
if (scores == null)
{
return null;
}
List<PackedScore> list = new List<PackedScore>();
for (int i = 0; i < scores.Length; i++)
{
JSONScore score = scores[i];
PackedScore packedScore = new PackedScore(score);
if (score.Tiers != null && score.Tiers.Length != 0)
{
List<PackedScore> list2 = new List<PackedScore>();
JSONScore[] tiers = score.Tiers;
for (int j = 0; j < tiers.Length; j++)
{
PackedScore packedScore2 = new PackedScore(tiers[j], useTiers: true);
packedScore2.eventType = packedScore.eventType;
list2.Add(packedScore2);
}
PackedValue[] tiers2 = list2.ToArray();
packedScore.Tiers = tiers2;
}
list.Add(packedScore);
}
return list.ToArray();
}
private static PackedMultiplier[] CreateMultiplierObjects(JSONMult[] multipliers)
{
if (multipliers == null)
{
return null;
}
List<PackedMultiplier> list = new List<PackedMultiplier>();
for (int i = 0; i < multipliers.Length; i++)
{
JSONMult mult = multipliers[i];
PackedMultiplier packedMultiplier = new PackedMultiplier(mult);
if (mult.Tiers != null && mult.Tiers.Length != 0)
{
List<PackedMultiplier> list2 = new List<PackedMultiplier>();
JSONMult[] tiers = mult.Tiers;
for (int j = 0; j < tiers.Length; j++)
{
PackedMultiplier packedMultiplier2 = new PackedMultiplier(tiers[j], useTiers: true);
packedMultiplier2.eventType = packedMultiplier.eventType;
list2.Add(packedMultiplier2);
}
PackedValue[] tiers2 = list2.ToArray();
packedMultiplier.Tiers = tiers2;
}
list.Add(packedMultiplier);
}
return list.ToArray();
}
private static JSONScore ReadScoreData(string file)
{
JSONScore result = default(JSONScore);
result.FromJSON(file);
return result;
}
private static JSONMult ReadMultiplierData(string file)
{
JSONMult result = default(JSONMult);
result.FromJSON(file);
return result;
}
}
public struct ValuePackage
{
public Dictionary<string, PackedValue> Values;
public ValuePackage(PackedScore[] scores, PackedMultiplier[] multipliers)
{
Values = new Dictionary<string, PackedValue>();
if (scores != null)
{
foreach (PackedScore packedScore in scores)
{
Values.Add(packedScore.eventType, packedScore);
}
}
if (multipliers != null)
{
foreach (PackedMultiplier packedMultiplier in multipliers)
{
Values.Add(packedMultiplier.eventType, packedMultiplier);
}
}
}
}
}
namespace NEP.ScoreLab.Core
{
public static class API
{
public static class Value
{
public static Action<PackedValue> OnValueAdded;
public static Action<PackedValue> OnValueAccumulated;
public static Action<PackedValue> OnValueTierReached;
public static Action<PackedValue> OnValueRemoved;
}
public static class Score
{
public static Action<int> OnScoreUpdated;
public static Action<int> OnScoreDifferenceUpdated;
public static Action<int> OnLastScoreUpdated;
}
public static class Multiplier
{
public static Action<PackedMultiplier> OnMultiplierTimeBegin;
public static Action<PackedMultiplier> OnMultiplierTimeExpired;
}
public static class HighScore
{
public static Action<PackedHighScore> OnHighScoreReached;
public static Action<PackedHighScore> OnHighScoreUpdated;
public static Action<PackedHighScore> OnHighScoreLoaded;
public static Action<PackedHighScore> OnHighScoreSaved;
}
public static class GameConditions
{
private static Dictionary<string, Func<bool>> _conditionTable = new Dictionary<string, Func<bool>>
{
{
"IsPlayerMoving",
() => ScoreDirector.IsPlayerMoving
},
{
"IsPlayerSeated",
() => ScoreDirector.IsPlayerSeated
},
{
"IsPlayerInAir",
() => ScoreDirector.IsPlayerInAir
},
{
"IsPlayerRagdolled",
() => ScoreDirector.IsPlayerRagdolled
},
{
"IsSlowMoEnabled",
() => ScoreDirector.IsSlowMoEnabled
}
};
public static Func<bool> GetCondition(string cond)
{
if (string.IsNullOrEmpty(cond))
{
Debug.LogWarning(Object.op_Implicit(cond + " doesn't exist in the condition table."));
return null;
}
if (!_conditionTable.ContainsKey(cond))
{
Debug.LogWarning(Object.op_Implicit(cond + " doesn't exist in the condition table."));
return null;
}
return _conditionTable[cond];
}
}
public static class UI
{
public static Action<NEP.ScoreLab.HUD.Module> OnModuleEnabled;
public static Action<NEP.ScoreLab.HUD.Module> OnModuleDisabled;
public static Action<NEP.ScoreLab.HUD.Module> OnModuleDecayed;
public static Action<NEP.ScoreLab.HUD.Module> OnModulePostDecayed;
}
}
public static class ScoreDirector
{
public static class Patches
{
[HarmonyPatch(typeof(Projectile), "Awake")]
public static class ProjectilePatch
{
public static void Postfix(Projectile __instance)
{
Action<Collider, Vector3, Vector3> action = OnProjectileCollision;
((UnityEvent<Collider, Vector3, Vector3>)(object)__instance.onCollision).AddListener(UnityAction<Collider, Vector3, Vector3>.op_Implicit(action));
}
private static void OnProjectileCollision(Collider collider, Vector3 world, Vector3 normal)
{
MarrowBody val = MarrowBody.Cache.Get(((Component)collider).gameObject);
if (!((Object)(object)val == (Object)null))
{
TriggerRefProxy component = ((Component)val).GetComponent<TriggerRefProxy>();
if (!((Object)(object)component == (Object)null) && !component.aiManager.isDead && (Object)(object)((Component)component.targetHead).gameObject == (Object)(object)((Component)val).gameObject)
{
ScoreTracker.Add(EventType.Score.Headshot);
}
}
}
}
[HarmonyPatch(typeof(RigManager), "SwitchAvatar")]
public static class RigManagerSwapAvatarPatch
{
public static void Postfix(Avatar newAvatar)
{
_playerRecentlySwappedAvatars = true;
}
}
[HarmonyPatch(typeof(BehaviourCrablet))]
[HarmonyPatch("AttachToFace")]
public static class CrabletAttachToFacePatch
{
public static void Postfix(Rigidbody face, TriggerRefProxy trp, bool preAttach = false, bool isPlayer = true)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
if (!isPlayer)
{
if ((int)trp.npcType == 32)
{
ScoreTracker.Add(EventType.Score.Crabcest);
}
else
{
ScoreTracker.Add(EventType.Score.Facehug);
}
}
}
}
[HarmonyPatch(typeof(Seat))]
[HarmonyPatch("Register")]
public static class RegisterSeatPatch
{
public static void Postfix(RigManager rM)
{
IsPlayerSeated = true;
ScoreTracker.Add(EventType.Mult.Seated);
}
}
[HarmonyPatch(typeof(Seat))]
[HarmonyPatch("DeRegister")]
public static class DeRegisterSeatPatch
{
public static void Postfix()
{
IsPlayerSeated = false;
}
}
[HarmonyPatch(typeof(Player_Health))]
[HarmonyPatch("LifeSavingDamgeDealt")]
public static class SecondWindPatch
{
public static void Postfix()
{
ScoreTracker.Add(EventType.Mult.SecondWind);
}
}
[HarmonyPatch(typeof(Arena_GameController))]
[HarmonyPatch("StartNextWave")]
public static class StartNextWavePatch
{
public static void Postfix(Arena_GameController __instance)
{
ScoreTracker.Add(EventType.Score.GameWaveCompleted);
}
}
[HarmonyPatch(typeof(Arena_GameController))]
[HarmonyPatch("EndOfRound")]
public static class StartNextRoundPatch
{
public static void Postfix(Arena_GameController __instance)
{
ScoreTracker.Add(EventType.Score.GameRoundCompleted);
}
}
[HarmonyPatch(typeof(PhysicsRig))]
[HarmonyPatch("OnUpdate")]
public static class PhysRigPatch
{
private static bool _midAirTargetBool;
private static float _tMidAirDelay = 0.5f;
private static float _tAirTime;
private static bool _ragdolledTargetBool;
private static float _tRagdollDelay = 0.5f;
private static float _tRagdollTime;
public static void Postfix(PhysicsRig __instance)
{
IsPlayerInAir = !__instance.physG.isGrounded;
if (IsPlayerInAir)
{
if (!_midAirTargetBool)
{
_tAirTime += Time.deltaTime;
if (_tAirTime > _tMidAirDelay)
{
ScoreTracker.Add(EventType.Mult.MidAir);
_midAirTargetBool = true;
}
}
}
else
{
_tAirTime = 0f;
_midAirTargetBool = false;
}
if (IsPlayerRagdolled)
{
if (!_ragdolledTargetBool)
{
_ragdolledTargetBool = true;
}
}
else
{
_ragdolledTargetBool = false;
}
if (_playerRecentlySwappedAvatars)
{
ScoreTracker.Add(EventType.Mult.SwappedAvatars);
_playerRecentlySwappedAvatars = false;
}
}
}
[HarmonyPatch(typeof(PhysicsRig))]
[HarmonyPatch("RagdollRig")]
public static class PhysRigRagdollPatch
{
public static void Postfix(PhysicsRig __instance)
{
IsPlayerRagdolled = true;
}
}
[HarmonyPatch(typeof(PhysicsRig))]
[HarmonyPatch("UnRagdollRig")]
public static class PhysRigUnRagdollPatch
{
public static void Postfix(PhysicsRig __instance)
{
IsPlayerRagdolled = false;
}
}
[HarmonyPatch(typeof(TimeManager), "OnPostTimeUpdate")]
public static class TimeManagerUpdatePatch
{
private static bool _slowmoSwitch;
public static void Postfix()
{
}
}
[HarmonyPatch(typeof(TimeManager), "INCREASE_TIMESCALE")]
public static class TimeManagerIncreaseTimePatch
{
public static void Postfix()
{
}
}
[HarmonyPatch(typeof(TimeManager), "DECREASE_TIMESCALE")]
public static class TimeManagerDecreaseTimePatch
{
public static void Postfix()
{
}
}
public static void InitPatches()
{
Hooking.OnNPCKillStart += OnAIDeath;
}
public static void OnAIDeath(BehaviourBaseNav behaviour)
{
ScoreTracker.Add(ValueManager.Get(EventType.Score.Kill));
ScoreTracker.Add(ValueManager.Get(EventType.Mult.Kill));
if (!behaviour.sensors.isGrounded)
{
ScoreTracker.Add(EventType.Score.EnemyMidAirKill);
}
if ((Object)(object)behaviour.sensors.target == (Object)null)
{
ScoreTracker.Add(EventType.Score.StealthKill);
}
}
}
public static readonly string PlayerName = "";
public static bool IsPlayerMoving = false;
public static bool IsPlayerInAir = false;
public static bool IsPlayerSeated = false;
public static bool IsPlayerRagdolled = false;
public static bool IsSlowMoEnabled = false;
private static bool _playerRecentlySwappedAvatars = false;
}
public static class ScoreTracker
{
private static int _score = 0;
private static int _lastScore = 0;
private static float _multiplier = 1f;
private static float _baseMultiplier = 1f;
public static List<PackedValue> ActiveValues { get; private set; }
public static int Score => _score;
public static int LastScore => _lastScore;
public static float Multiplier => _multiplier;
public static void Initialize()
{
ActiveValues = new List<PackedValue>();
}
public static void Update()
{
if (ActiveValues != null)
{
for (int i = 0; i < ActiveValues.Count; i++)
{
ActiveValues[i].OnUpdate();
}
}
}
public static void Add(string eventType)
{
Add(Create(eventType));
}
public static void Add(PackedValue value)
{
if (value != null)
{
if (value.PackedValueType == PackedValue.PackedType.Score)
{
SetPackedScore((PackedScore)value);
}
else if (value.PackedValueType == PackedValue.PackedType.Multiplier)
{
SetPackedMultiplier((PackedMultiplier)value);
}
}
}
public static void Remove(PackedValue value)
{
if (value.PackedValueType == PackedValue.PackedType.Score)
{
ActiveValues.Remove(value);
value.OnValueRemoved();
API.Value.OnValueRemoved?.Invoke(value);
}
else if (value.PackedValueType == PackedValue.PackedType.Multiplier)
{
ActiveValues.Remove(value);
RemoveMultiplier((value as PackedMultiplier).AccumulatedMultiplier);
value.OnValueRemoved();
API.Value.OnValueRemoved?.Invoke(value);
}
}
public static void AddScore(int score)
{
_lastScore = _score;
_score += Mathf.RoundToInt((float)score * _multiplier);
}
public static void AddMultiplier(float multiplier)
{
_multiplier += multiplier;
}
public static void SetMultiplier(float multiplier)
{
_multiplier = multiplier;
}
public static void ResetScore()
{
_score = 0;
_lastScore = 0;
}
public static void ResetMultiplier()
{
_multiplier = 1f;
}
public static void ResetAll()
{
ResetScore();
ResetMultiplier();
ResetHighScore();
ActiveValues.Clear();
}
public static void ResetHighScore()
{
}
public static void RemoveMultiplier(float multiplier)
{
if (_multiplier < _baseMultiplier)
{
_multiplier = _baseMultiplier;
}
_multiplier -= multiplier;
}
public static bool CheckDuplicate(PackedValue value)
{
foreach (PackedValue activeValue in ActiveValues)
{
if (activeValue.eventType == value.eventType)
{
return true;
}
}
return false;
}
private static void SetPackedScore(PackedScore score)
{
if (score != null)
{
if (!CheckDuplicate(score))
{
InitializeValue(score);
AddScore(score.Score);
ActiveValues.Add(score);
API.Value.OnValueAdded?.Invoke(score);
}
else if (score.Tiers != null)
{
PackedScore clone = GetClone<PackedScore>(score);
PackedScore packedScore = (PackedScore)clone.CurrentTier;
clone.ToNextTier();
clone.TierRequirement = packedScore.TierRequirement;
clone.SetDecayTime(packedScore.DecayTime);
AddScore(packedScore.Score);
}
else if (score.Stackable)
{
PackedScore clone2 = GetClone<PackedScore>(score);
AddScore(score.Score);
clone2.SetDecayTime(clone2.DecayTime);
clone2.AccumulatedScore += clone2.Score;
API.Value.OnValueAccumulated?.Invoke(clone2);
}
else
{
PackedScore packedScore2 = CopyFromScore(score);
InitializeValue(packedScore2);
AddScore(packedScore2.Score);
ActiveValues.Add(packedScore2);
API.Value.OnValueAdded?.Invoke(packedScore2);
}
}
}
private static void SetPackedMultiplier(PackedMultiplier multiplier)
{
if (multiplier != null)
{
if (!CheckDuplicate(multiplier))
{
InitializeValue(multiplier);
AddMultiplier(multiplier.Multiplier);
ActiveValues.Add(multiplier);
API.Value.OnValueAdded?.Invoke(multiplier);
}
else if (multiplier.Tiers != null)
{
PackedMultiplier clone = GetClone<PackedMultiplier>(multiplier);
PackedMultiplier packedMultiplier = (PackedMultiplier)clone.CurrentTier;
clone.ToNextTier();
clone.TierRequirement = packedMultiplier.TierRequirement;
clone.SetDecayTime(packedMultiplier.DecayTime);
AddMultiplier(packedMultiplier.Multiplier);
multiplier.AccumulatedMultiplier += packedMultiplier.Multiplier;
API.Value.OnValueTierReached?.Invoke(packedMultiplier);
}
else if (multiplier.Stackable)
{
PackedMultiplier clone2 = GetClone<PackedMultiplier>(multiplier);
AddMultiplier(multiplier.Multiplier);
clone2.SetDecayTime(clone2.DecayTime);
clone2.AccumulatedMultiplier += clone2.Multiplier;
API.Value.OnValueAccumulated?.Invoke(clone2);
}
else
{
PackedMultiplier packedMultiplier2 = CopyFromMult(multiplier);
InitializeValue(packedMultiplier2);
AddMultiplier(multiplier.Multiplier);
ActiveValues.Add(packedMultiplier2);
API.Value.OnValueAdded?.Invoke(packedMultiplier2);
}
}
}
private static PackedScore CopyFromScore(PackedScore original)
{
return new PackedScore
{
eventType = original.eventType,
Name = original.Name,
Score = original.Score,
EventAudio = original.EventAudio,
DecayTime = original.DecayTime
};
}
private static PackedMultiplier CopyFromMult(PackedMultiplier original)
{
return new PackedMultiplier
{
eventType = original.eventType,
Name = original.Name,
Multiplier = original.Multiplier,
EventAudio = original.EventAudio,
DecayTime = original.DecayTime,
Condition = original.Condition
};
}
private static PackedValue Create(string eventType)
{
PackedValue packedValue = ValueManager.Get(eventType);
if (packedValue == null)
{
return null;
}
if (packedValue.PackedValueType == PackedValue.PackedType.Score)
{
PackedScore packedScore = (PackedScore)packedValue;
return new PackedScore
{
eventType = packedScore.eventType,
Stackable = packedScore.Stackable,
DecayTime = packedScore.DecayTime,
Name = packedScore.Name,
Score = packedScore.Score,
EventAudio = packedScore.EventAudio,
TierRequirement = packedScore.TierRequirement,
Tiers = packedScore.Tiers
};
}
if (packedValue.PackedValueType == PackedValue.PackedType.Multiplier)
{
PackedMultiplier packedMultiplier = (PackedMultiplier)packedValue;
return new PackedMultiplier
{
eventType = packedMultiplier.eventType,
Stackable = packedMultiplier.Stackable,
DecayTime = packedMultiplier.DecayTime,
Name = packedMultiplier.Name,
Multiplier = packedMultiplier.Multiplier,
Condition = packedMultiplier.Condition,
EventAudio = packedMultiplier.EventAudio,
TierRequirement = packedMultiplier.TierRequirement,
Tiers = packedMultiplier.Tiers
};
}
return null;
}
private static void InitializeValue(PackedValue value)
{
value.OnValueCreated();
value.SetDecayTime(value.DecayTime);
}
private static T GetClone<T>(PackedValue value) where T : PackedValue
{
return (T)ActiveValues.Find((PackedValue match) => match.eventType == value.eventType);
}
}
public static class Settings
{
public static float DistanceToCamera;
public static float MovementSmoothness;
public static bool UseAnnouncer;
public static string SavedHUD;
public static HUDShowMode HUDShowMode;
private static MelonPreferences_Category m_scorelabCategory;
private static MelonPreferences_Entry<float> m_eDistanceToCamera;
private static MelonPreferences_Entry<float> m_eMovementSmoothness;
private static MelonPreferences_Entry<bool> m_eUseAnnouncer;
private static MelonPreferences_Entry<string> m_eSavedHUD;
private static MelonPreferences_Entry<int> m_eHudShowMode;
public static void CreatePreferences()
{
m_scorelabCategory = MelonPreferences.CreateCategory("ScoreLab");
m_eDistanceToCamera = m_scorelabCategory.CreateEntry<float>("DistanceToCamera", 1.125f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eMovementSmoothness = m_scorelabCategory.CreateEntry<float>("MovementSmoothness", 16f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eUseAnnouncer = m_scorelabCategory.CreateEntry<bool>("UseAnnouncer", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eSavedHUD = m_scorelabCategory.CreateEntry<string>("SavedHUD", "Coda", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eHudShowMode = m_scorelabCategory.CreateEntry<int>("HUDShowMode", 0, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
DistanceToCamera = m_eDistanceToCamera.Value;
MovementSmoothness = m_eMovementSmoothness.Value;
UseAnnouncer = m_eUseAnnouncer.Value;
SavedHUD = m_eSavedHUD.Value;
HUDShowMode = (HUDShowMode)m_eHudShowMode.Value;
}
public static void Save(bool log = false)
{
m_eDistanceToCamera.Value = DistanceToCamera;
m_eMovementSmoothness.Value = MovementSmoothness;
m_eUseAnnouncer.Value = UseAnnouncer;
m_eSavedHUD.Value = SavedHUD;
m_scorelabCategory.SaveToFile(log);
}
public static void SetDistanceToCamera(float distance)
{
m_eDistanceToCamera.Value = distance;
}
public static void SetMovementSmoothness(float movementSmoothness)
{
m_eMovementSmoothness.Value = movementSmoothness;
}
public static void SetUseAnnouncer(bool useAnnouncer)
{
m_eUseAnnouncer.Value = useAnnouncer;
}
public static void SetHUDShowMode(HUDShowMode mode)
{
m_eHudShowMode.Value = (int)mode;
HUDManager.HUDShowModeUpdated(mode);
}
}
}
namespace NEP.ScoreLab.Audio
{
public static class AudioManager
{
public static void Initialize()
{
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAdded, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAccumulated, new Action<PackedValue>(OnValueReceived));
}
public static void Uninitialize()
{
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAdded, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAccumulated, new Action<PackedValue>(OnValueReceived));
}
private static void OnValueReceived(PackedValue value)
{
if (Settings.UseAnnouncer && value.EventAudio != null && value.EventAudio.Clips != null && value.EventAudio.Clips.Length != 0)
{
AudioClip val = null;
if (value.EventAudio.Clips.Length == 1)
{
val = value.EventAudio.Clips[0];
}
else
{
int num = Random.Range(0, value.EventAudio.Clips.Length);
val = value.EventAudio.Clips[num];
}
Play(val, value.EventAudio.Volume, value.EventAudio.Pitch);
}
}
public static void Play(AudioClip clip, float volume = 1f, float pitch = 1f)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
Audio.PlayAtPoint(clip, Vector3.zero, Audio.InHead, volume, pitch, 0f);
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.VRMK;
using Il2CppSystem;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using NEP.ScoreLab;
using NEP.ScoreLab.Audio;
using NEP.ScoreLab.Core;
using NEP.ScoreLab.Data;
using NEP.ScoreLab.HUD;
using NEP.ScoreLab.Menu;
using NEP.ScoreLab.Patches;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "ScoreLab", "1.0.0", "Not Enough Photons", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ScoreLab")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0140fb38dafe5a3ef9669f29b961df65def51cb4")]
[assembly: AssemblyProduct("ScoreLab")]
[assembly: AssemblyTitle("ScoreLab")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 NEP.ScoreLab
{
public static class BuildInfo
{
public const string Name = "ScoreLab";
public const string Author = "Not Enough Photons";
public const string Company = "Not Enough Photons";
public const string Version = "1.0.0";
public const string DownloadLink = "https://thunderstore.io/c/bonelab/p/NotEnoughPhotons/ScoreLab";
}
public class Main : MelonMod
{
internal static Instance Logger;
public override void OnLateInitializeMelon()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
Logger = new Instance("ScoreLab");
Settings.CreatePreferences();
Hooks.Initialize();
Hooks.Game.OnMarrowGameStarted = (Action)Delegate.Combine(Hooks.Game.OnMarrowGameStarted, new Action(OnMarrowGameStarted));
Hooks.Game.OnMarrowSceneLoaded = (Action<MarrowSceneInfo>)Delegate.Combine(Hooks.Game.OnMarrowSceneLoaded, new Action<MarrowSceneInfo>(OnMarrowSceneLoaded));
HUDLoader.Initialize();
SLMenu.Initialize();
}
public void OnMarrowGameStarted()
{
ScoreTracker.Initialize();
ValueManager.Initialize();
AudioManager.Initialize();
ScoreDirector.Patches.InitPatches();
}
public void OnMarrowSceneLoaded(MarrowSceneInfo sceneInfo)
{
HUDManager.Initialize();
ScoreTracker.ResetAll();
}
public override void OnUpdate()
{
ScoreTracker.Update();
}
public override void OnDeinitializeMelon()
{
HUDManager.Uninitialize();
AudioManager.Uninitialize();
Settings.Save();
}
}
}
namespace NEP.ScoreLab.Patches
{
public static class Hooks
{
public static class Game
{
public static Action OnMarrowGameStarted;
public static Action<MarrowSceneInfo> OnMarrowSceneLoaded;
private static MarrowSceneInfo _lastScene;
private static MarrowSceneInfo _currentScene;
private static MarrowSceneInfo _nextScene;
public static void Initialize()
{
MarrowGame.RegisterOnReadyAction(Action.op_Implicit((Action)delegate
{
OnMarrowGameStarted?.Invoke();
}));
Hooking.OnLevelLoaded += OnSceneMarrowLoaded;
}
private static void OnSceneMarrowLoaded(LevelInfo info)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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)
MarrowSceneInfo currentScene = default(MarrowSceneInfo);
currentScene.Barcode = info.barcode;
currentScene.LevelTitle = info.title;
currentScene.MarrowScene = ((CrateReferenceT<LevelCrate>)(object)info.levelReference).Crate.MainScene;
_currentScene = currentScene;
_lastScene = _currentScene;
OnMarrowSceneLoaded?.Invoke(_currentScene);
}
}
public static void Initialize()
{
Game.Initialize();
}
}
}
namespace NEP.ScoreLab.Menu
{
public static class SLMenu
{
private static Page _hudPage;
public static void Initialize()
{
//IL_000a: 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_002d: 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_0087: 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)
Page obj = Page.Root.CreatePage("Not Enough Photons", Color.white, 0, true).CreatePage("ScoreLab", Color.white, 0, true);
_hudPage = obj.CreatePage("HUDs", Color.white, 0, true);
obj.CreateFloat("HUD Distance", Color.white, 1.125f, 0.025f, 0f, 2f, (Action<float>)delegate(float value)
{
Settings.DistanceToCamera = value;
});
obj.CreateEnum("Show HUD", Color.white, (Enum)Settings.HUDShowMode, (Action<Enum>)delegate(Enum value)
{
Settings.SetHUDShowMode((HUDShowMode)(object)value);
});
for (int i = 0; i < HUDLoader.LoadedHUDManifests.Count; i++)
{
int index = i;
JSONHUDManifest manifest = HUDLoader.LoadedHUDManifests[index];
_hudPage.CreateFunction(manifest.Name, Color.white, (Action)delegate
{
HUDManager.LoadHUD(manifest.Name);
}).Logo = manifest.Logo;
}
}
public static void RefreshHUDPage()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
_hudPage.RemoveAll();
for (int i = 0; i < HUDLoader.LoadedHUDManifests.Count; i++)
{
int index = i;
JSONHUDManifest manifest = HUDLoader.LoadedHUDManifests[index];
_hudPage.CreateFunction(manifest.Name, Color.white, (Action)delegate
{
HUDManager.LoadHUD(manifest.Name);
}).Logo = manifest.Logo;
}
}
}
}
namespace NEP.ScoreLab.HUD
{
public enum HUDShowMode
{
Always,
UpdateOnly,
Never
}
[RegisterTypeInIl2Cpp]
public class Module : MonoBehaviour
{
public enum UIModuleType
{
Main,
Descriptor
}
public UIModuleType ModuleType;
private bool _reachedDecay;
private bool _reachedPostDecay;
public PackedValue PackedValue => _packedValue;
public virtual PackedValue.PackedType PackedType => PackedValue.PackedType.Base;
public virtual bool CanDecay => (Object)(object)((Component)this).transform.Find("-Persist") == (Object)null;
public float DecayTime => _decayTime;
public float PostDecayTime => _postDecayTime;
protected TextMeshProUGUI _title { get; private set; }
protected TextMeshProUGUI _value { get; private set; }
protected Slider _timeBar { get; private set; }
protected PackedValue _packedValue { get; private set; }
protected bool _canDecay { get; private set; }
protected bool _decayed { get; private set; }
protected float _decayTime { get; private set; }
protected float _postDecayTime { get; private set; }
protected float _tDecay { get; private set; }
protected float _tPostDecay { get; private set; }
private string Path_Root => ((Object)this).name;
protected virtual string Path_TitleText => "Title";
protected virtual string Path_ValueText => "Value";
protected virtual string Path_TimeBar => "TimeBar";
public Module(IntPtr ptr)
: base(ptr)
{
}
public virtual void OnModuleEnable()
{
API.UI.OnModuleEnabled?.Invoke(this);
}
public virtual void OnModuleDisable()
{
API.UI.OnModuleDisabled?.Invoke(this);
}
public virtual void OnUpdate()
{
}
public void AssignPackedData(PackedValue packedValue)
{
if (packedValue != null)
{
_packedValue = packedValue;
if (_packedValue.DecayTime != 0f)
{
SetDecayTime(_packedValue.DecayTime);
}
}
}
public void SetDecayTime(float decayTime)
{
_decayTime = decayTime;
_tDecay = _decayTime;
}
public void SetPostDecayTime(float postDecayTime)
{
_postDecayTime = postDecayTime;
_tPostDecay = _postDecayTime;
}
public bool IsDecaying()
{
return _reachedDecay;
}
public bool IsDecayed()
{
return _reachedPostDecay;
}
protected void SetText(TextMeshProUGUI text, string value)
{
if (!((Object)(object)text == (Object)null))
{
((TMP_Text)text).text = value;
}
}
protected void SetText(TextMeshProUGUI text, int value)
{
if (!((Object)(object)text == (Object)null))
{
SetText(text, value.ToString());
}
}
protected void SetText(TextMeshProUGUI text, float value)
{
if (!((Object)(object)text == (Object)null))
{
SetText(text, value.ToString());
}
}
protected void SetBarValue(Slider timeBar, float value)
{
timeBar.value = value;
}
protected void SetMaxValueToBar(Slider timeBar, float value)
{
if (!((Object)(object)timeBar == (Object)null))
{
timeBar.maxValue = value;
}
}
protected void UpdateDecay()
{
if (!CanDecay)
{
return;
}
if (_tDecay < 0f)
{
if (!_reachedDecay)
{
API.UI.OnModuleDecayed?.Invoke(this);
_reachedDecay = true;
}
_tPostDecay -= Time.deltaTime;
if (_tPostDecay < 0f)
{
if (!_reachedPostDecay)
{
API.UI.OnModulePostDecayed?.Invoke(this);
_reachedPostDecay = true;
}
_tDecay = _decayTime;
_tPostDecay = _postDecayTime;
_reachedDecay = false;
_reachedPostDecay = false;
((Component)this).gameObject.SetActive(false);
}
}
else
{
_tDecay -= Time.deltaTime;
}
}
private void Start()
{
Transform val = ((Component)this).transform.Find(Path_TitleText);
Transform val2 = ((Component)this).transform.Find(Path_ValueText);
Transform val3 = ((Component)this).transform.Find(Path_TimeBar);
_title = ((val != null) ? ((Component)val).GetComponent<TextMeshProUGUI>() : null);
_value = ((val2 != null) ? ((Component)val2).GetComponent<TextMeshProUGUI>() : null);
_timeBar = ((val3 != null) ? ((Component)val3).GetComponent<Slider>() : null);
}
private void OnEnable()
{
OnModuleEnable();
}
private void OnDisable()
{
OnModuleEnable();
}
private void Update()
{
OnUpdate();
}
}
[RegisterTypeInIl2Cpp]
public class ModuleAnimator : MonoBehaviour
{
public Animator Animator;
private Module _module;
public ModuleAnimator(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
_module = ((Component)this).GetComponent<Module>();
Animator = ((Component)this).GetComponent<Animator>();
}
private void OnEnable()
{
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, (Action<PackedValue>)delegate
{
OnTierReached();
});
API.UI.OnModuleDecayed = (Action<Module>)Delegate.Combine(API.UI.OnModuleDecayed, new Action<Module>(OnModuleDecayed));
}
private void OnDisable()
{
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, (Action<PackedValue>)delegate
{
OnTierReached();
});
API.UI.OnModuleDecayed = (Action<Module>)Delegate.Remove(API.UI.OnModuleDecayed, new Action<Module>(OnModuleDecayed));
}
private void PlayAnimation(string name)
{
if (!((Object)(object)Animator == (Object)null))
{
Animator.Play(name, -1, 0f);
}
}
private void OnModuleEnabled(Module module)
{
if (!((Object)(object)_module != (Object)(object)module))
{
if (_module.ModuleType == Module.UIModuleType.Descriptor)
{
PlayAnimation("descriptor_show");
}
else
{
PlayAnimation("show");
}
}
}
private void OnTierReached()
{
PlayAnimation("tier_reached");
}
private void OnModuleDecayed(Module module)
{
if (!((Object)(object)_module != (Object)(object)module))
{
if (_module.ModuleType == Module.UIModuleType.Descriptor)
{
PlayAnimation("descriptor_hide");
}
else
{
PlayAnimation("hide");
}
}
}
}
[RegisterTypeInIl2Cpp]
public class MultiplierModule : Module
{
private float _currentValue;
private float _targetValue;
private float _rate;
private PackedMultiplier _packedMultiplier => (PackedMultiplier)base._packedValue;
public MultiplierModule(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
if (((Object)this).name == "MultiplierDescriptor" || ((Object)this).name == "Descriptor")
{
ModuleType = UIModuleType.Descriptor;
}
}
public override void OnModuleEnable()
{
base.OnModuleEnable();
if (base._packedValue == null || _packedMultiplier == null)
{
return;
}
if (ModuleType == UIModuleType.Main)
{
SetText(base._value, ScoreTracker.Multiplier + "x");
}
else if (ModuleType == UIModuleType.Descriptor)
{
SetText(base._title, _packedMultiplier.Name);
SetText(base._value, _packedMultiplier.Multiplier + "x");
}
if ((Object)(object)base._timeBar != (Object)null)
{
if (_packedMultiplier.Condition != string.Empty)
{
((Component)base._timeBar).gameObject.SetActive(false);
return;
}
((Component)base._timeBar).gameObject.SetActive(true);
SetMaxValueToBar(base._timeBar, _packedMultiplier.DecayTime);
SetBarValue(base._timeBar, _packedMultiplier.DecayTime);
}
}
public override void OnModuleDisable()
{
}
public override void OnUpdate()
{
if (ModuleType == UIModuleType.Main)
{
SetTweenValue(ScoreTracker.Multiplier);
_currentValue = Mathf.MoveTowards(_currentValue, _targetValue, _rate * Time.unscaledDeltaTime);
if (Mathf.Approximately(_currentValue, _targetValue))
{
_currentValue = _targetValue;
}
SetText(base._value, _currentValue.ToString("F2"));
}
if (_packedMultiplier != null)
{
if (_packedMultiplier.condition != null)
{
if (!_packedMultiplier.condition())
{
UpdateDecay();
}
}
else
{
UpdateDecay();
}
}
else
{
UpdateDecay();
}
if ((Object)(object)base._timeBar != (Object)null)
{
SetBarValue(base._timeBar, base._tDecay);
}
}
private void SetTweenValue(float value)
{
_targetValue = value;
_rate = Mathf.Abs(_targetValue - _currentValue) / 1f;
}
}
[RegisterTypeInIl2Cpp]
public class ScoreModule : Module
{
private float _targetValue;
private float _currentValue;
private float _rate = 4f;
private PackedScore _packedScore => (PackedScore)base._packedValue;
public ScoreModule(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
if (((Object)this).name == "ScoreDescriptor" || ((Object)this).name == "Descriptor")
{
ModuleType = UIModuleType.Descriptor;
}
}
public override void OnModuleEnable()
{
base.OnModuleEnable();
if (ModuleType == UIModuleType.Main)
{
SetText(base._value, ScoreTracker.Score);
}
if (base._packedValue != null && ModuleType == UIModuleType.Descriptor)
{
SetText(base._title, _packedScore.Name);
SetText(base._value, $"+{Mathf.RoundToInt((float)_packedScore.Score * ScoreTracker.Multiplier)}");
}
}
public override void OnModuleDisable()
{
}
public override void OnUpdate()
{
UpdateDecay();
if (ModuleType == UIModuleType.Main)
{
SetTweenValue(ScoreTracker.Score);
_currentValue = Mathf.MoveTowards(_currentValue, _targetValue, _rate * Time.unscaledDeltaTime);
if (Mathf.Approximately(_currentValue, _targetValue))
{
_currentValue = _targetValue;
}
SetText(base._value, _currentValue.ToString("N0"));
}
}
private void SetTweenValue(int value)
{
_targetValue = value;
_rate = Mathf.Abs(_targetValue - _currentValue) / 1f;
}
}
[RegisterTypeInIl2Cpp]
public class HUD : MonoBehaviour
{
public Transform followTarget;
public Module ScoreModule { get; set; }
public Module MultiplierModule { get; set; }
public Module HighScoreModule { get; set; }
public HUD(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
if ((Object)(object)((Component)this).transform.Find("MainScore") != (Object)null)
{
ScoreModule = ((Component)((Component)this).transform.Find("MainScore")).GetComponent<ScoreModule>();
}
if (Object.op_Implicit((Object)(object)((Component)this).transform.Find("MainMultiplier")))
{
MultiplierModule = ((Component)((Component)this).transform.Find("MainMultiplier")).GetComponent<MultiplierModule>();
}
}
private void OnEnable()
{
UpdateModule(null);
UpdateModule(null);
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAdded, new Action<PackedValue>(UpdateModule));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, new Action<PackedValue>(UpdateModule));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAccumulated, new Action<PackedValue>(UpdateModule));
API.Value.OnValueRemoved = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueRemoved, new Action<PackedValue>(UpdateModule));
}
private void OnDisable()
{
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAdded, new Action<PackedValue>(UpdateModule));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, new Action<PackedValue>(UpdateModule));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAccumulated, new Action<PackedValue>(UpdateModule));
API.Value.OnValueRemoved = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueRemoved, new Action<PackedValue>(UpdateModule));
}
private void Start()
{
if ((Object)(object)Player.GetPhysicsRig() != (Object)null)
{
followTarget = ((Rig)Player.ControllerRig).m_head;
}
}
private void FixedUpdate()
{
//IL_0015: 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_002b: 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_003a: 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_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_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: 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)
if (!((Object)(object)followTarget == (Object)null))
{
Vector3 position = Vector3.Lerp(((Component)this).transform.position, followTarget.position + followTarget.forward * Settings.DistanceToCamera, Settings.MovementSmoothness * Time.unscaledDeltaTime);
Quaternion rotation = Quaternion.LookRotation(followTarget.forward);
((Component)this).transform.position = position;
((Component)this).transform.rotation = rotation;
}
}
public void SetParent(Transform parent)
{
((Component)this).transform.SetParent(parent);
}
public void SetScoreModule(Module module)
{
ScoreModule = module;
}
public void SetMultiplierModule(Module module)
{
MultiplierModule = module;
}
public void UpdateModule(PackedValue data)
{
if (data is PackedScore)
{
ScoreModule.AssignPackedData(data);
ScoreModule.OnModuleEnable();
}
else if (data is PackedMultiplier)
{
MultiplierModule.AssignPackedData(data);
MultiplierModule.OnModuleEnable();
}
}
}
[RegisterTypeInIl2Cpp]
public class DescriptorList : MonoBehaviour
{
public List<Module> ActiveModules;
public int count = 6;
public List<Module> Modules;
public PackedValue.PackedType packedType { get; set; }
public GameObject ModulePrefab { get; set; }
public DescriptorList(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
Modules = new List<Module>();
ActiveModules = new List<Module>();
for (int i = 0; i < ((Component)this).transform.childCount; i++)
{
Transform child = ((Component)this).transform.GetChild(i);
Modules.Add(((Component)child).GetComponent<Module>());
}
if (((Object)this).name == "ScoreDescriptors")
{
packedType = PackedValue.PackedType.Score;
}
else if (((Object)this).name == "MultiplierDescriptors")
{
packedType = PackedValue.PackedType.Multiplier;
}
}
private void OnEnable()
{
API.UI.OnModulePostDecayed = (Action<Module>)Delegate.Combine(API.UI.OnModulePostDecayed, (Action<Module>)delegate(Module item)
{
ActiveModules.Remove(item);
});
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAdded, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAccumulated, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, new Action<PackedValue>(SetModuleActive));
}
private void OnDisable()
{
API.UI.OnModulePostDecayed = (Action<Module>)Delegate.Remove(API.UI.OnModulePostDecayed, (Action<Module>)delegate(Module item)
{
ActiveModules.Remove(item);
});
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAdded, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAccumulated, new Action<PackedValue>(SetModuleActive));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, new Action<PackedValue>(SetModuleActive));
}
public void SetPackedType(int packedType)
{
this.packedType = (PackedValue.PackedType)packedType;
}
public void SetModuleActive(PackedValue value)
{
if (Modules == null || Modules.Count == 0 || value.PackedValueType != packedType)
{
return;
}
foreach (Module module in Modules)
{
if (!((Component)module).gameObject.activeInHierarchy)
{
module.AssignPackedData(value);
module.SetDecayTime(value.DecayTime);
module.SetPostDecayTime(0.5f);
((Component)module).gameObject.SetActive(true);
ActiveModules.Add(module);
break;
}
if (ActiveModules.Contains(module) && !module.IsDecaying() && module.PackedValue.eventType == value.eventType)
{
if (value.Stackable)
{
module.AssignPackedData(value);
module.OnModuleEnable();
module.SetDecayTime(value.DecayTime);
module.SetPostDecayTime(0.5f);
break;
}
if (value.Tiers != null)
{
module.AssignPackedData(value);
module.OnModuleEnable();
module.SetDecayTime(value.DecayTime);
module.SetPostDecayTime(0.5f);
break;
}
}
}
}
public void PoolObjects()
{
if (!((Object)(object)ModulePrefab == (Object)null))
{
for (int i = 0; i < count; i++)
{
Module component = Object.Instantiate<GameObject>(ModulePrefab, ((Component)this).transform).GetComponent<Module>();
component.ModuleType = Module.UIModuleType.Descriptor;
Modules.Add(component);
}
}
}
}
public static class HUDManager
{
private static GameObject _parentObject;
public static List<HUD> LoadedHUDs { get; private set; }
public static HUD ActiveHUD { get; private set; }
public static HUD LastHUD { get; private set; }
internal static void Initialize()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
_parentObject = new GameObject("[ScoreLab] - HUD Container");
LoadedHUDs = new List<HUD>();
Populate();
if (HUDLoader.LoadedHUDs.ContainsKey(Settings.SavedHUD))
{
LoadHUD(Settings.SavedHUD);
}
else
{
LoadHUD("Coda");
}
}
internal static void Uninitialize()
{
}
public static void Populate()
{
for (int i = 0; i < HUDLoader.LoadedHUDManifests.Count; i++)
{
JSONHUDManifest jSONHUDManifest = HUDLoader.LoadedHUDManifests[i];
GameObject obj = Object.Instantiate<GameObject>(HUDLoader.LoadedHUDs[jSONHUDManifest.Name]);
((Object)obj).name = jSONHUDManifest.Name;
HUD component = obj.GetComponent<HUD>();
if (!((Object)(object)component == (Object)null))
{
LoadedHUDs.Add(component);
component.SetParent(_parentObject.transform);
((Component)component).gameObject.SetActive(false);
}
}
}
public static void HUDShowModeUpdated(HUDShowMode mode)
{
if (!((Object)(object)ActiveHUD == (Object)null))
{
switch (mode)
{
case HUDShowMode.Always:
((Component)ActiveHUD).gameObject.SetActive(true);
break;
case HUDShowMode.Never:
((Component)ActiveHUD).gameObject.SetActive(false);
break;
}
}
}
public static void LoadHUD(string name)
{
if ((Object)(object)ActiveHUD != (Object)null)
{
LastHUD = ActiveHUD;
}
UnloadHUD();
foreach (HUD loadedHUD in LoadedHUDs)
{
if (((Object)loadedHUD).name == name)
{
ActiveHUD = loadedHUD;
break;
}
}
if (!((Object)(object)ActiveHUD == (Object)null))
{
Settings.SavedHUD = name;
ValueManager.UsePackage(name);
((Component)ActiveHUD).gameObject.SetActive(true);
ActiveHUD.SetParent(null);
}
}
public static void UnloadHUD()
{
if ((Object)(object)ActiveHUD != (Object)null)
{
ActiveHUD.SetParent(_parentObject.transform);
((Component)ActiveHUD).gameObject.SetActive(false);
ActiveHUD = null;
}
}
public static void DestroyHUD()
{
if ((Object)(object)ActiveHUD != (Object)null)
{
Object.Destroy((Object)(object)ActiveHUD);
ActiveHUD = null;
}
}
public static void DestroyLoadedHUDs()
{
if (LoadedHUDs == null || LoadedHUDs.Count == 0)
{
return;
}
foreach (HUD loadedHUD in LoadedHUDs)
{
Object.Destroy((Object)(object)((Component)loadedHUD).gameObject);
}
LoadedHUDs.Clear();
}
}
}
namespace NEP.ScoreLab.Data
{
public static class HUDLoader
{
public static Dictionary<string, AudioClip> HUDAudioBank;
public static Dictionary<string, GameObject> LoadedHUDs;
public static List<JSONHUDManifest> LoadedHUDManifests;
private static List<AssetBundle> _assetBundles;
private static List<Object> _persistentBundleObjects;
public static void Initialize()
{
LoadedHUDs = new Dictionary<string, GameObject>();
HUDAudioBank = new Dictionary<string, AudioClip>();
LoadedHUDManifests = new List<JSONHUDManifest>();
_persistentBundleObjects = new List<Object>();
_assetBundles = new List<AssetBundle>();
LoadHUDs();
}
public static void SpawnDefaultUI()
{
SpawnUI("Coda");
}
public static void SpawnUI(string name)
{
foreach (JSONHUDManifest loadedHUDManifest in LoadedHUDManifests)
{
if (loadedHUDManifest.Name == name)
{
SpawnUI(LoadedHUDs[name]);
}
}
}
public static void SpawnUI(GameObject uiObject)
{
Object.Instantiate<GameObject>(uiObject);
}
public static void LoadHUDs()
{
foreach (string item2 in Directory.EnumerateDirectories(Path.Combine(MelonEnvironment.UserDataDirectory, "Not Enough Photons/ScoreLab")))
{
IEnumerable<string> enumerable = Directory.EnumerateFiles(item2);
string text = string.Empty;
string text2 = string.Empty;
foreach (string item3 in enumerable)
{
if (item3.EndsWith(".hud"))
{
text = item3;
}
if (item3.EndsWith(".hud_manifest"))
{
text2 = item3;
}
}
if (text == string.Empty)
{
Main.Logger.Error("Missing .HUD file in " + item2 + "!");
continue;
}
if (text2 == string.Empty)
{
Main.Logger.Error("Missing HUD manifest file in " + item2 + "!");
continue;
}
JSONHUDManifest item = default(JSONHUDManifest);
if (!item.FromJSON(text2))
{
Main.Logger.Error("Failed to read HUD manifest data! Source: " + item2);
continue;
}
AssetBundle val = AssetBundle.LoadFromFile(text);
GameObject value = HelperMethods.LoadPersistentAsset<GameObject>(val, item.AssetName);
Il2CppReferenceArray<Object> val2 = val.LoadAllAssets();
Texture2D val3 = HelperMethods.LoadPersistentAsset<Texture2D>(val, "Logo");
if ((Object)(object)val3 != (Object)null)
{
item.SetHUDLogo(val3);
}
_assetBundles.Add(val);
LoadedHUDManifests.Add(item);
LoadedHUDs.Add(item.Name, value);
if (val2 == null || ((Il2CppArrayBase<Object>)(object)val2).Length == 0)
{
continue;
}
foreach (Object item4 in (Il2CppArrayBase<Object>)(object)val2)
{
AudioClip val4 = ((Il2CppObjectBase)item4).TryCast<AudioClip>();
if ((Object)(object)val4 != (Object)null)
{
((Object)val4).hideFlags = (HideFlags)32;
HUDAudioBank.Add(item4.name, val4);
}
}
}
}
public static void ReloadHUDs()
{
if ((Object)(object)HUDManager.ActiveHUD != (Object)null)
{
HUDManager.DestroyHUD();
}
HUDManager.DestroyLoadedHUDs();
HUDAudioBank.Clear();
LoadedHUDManifests.Clear();
LoadedHUDs.Clear();
foreach (AssetBundle assetBundle in _assetBundles)
{
assetBundle.Unload(true);
}
_assetBundles.Clear();
LoadHUDs();
SLMenu.RefreshHUDPage();
HUDManager.Populate();
HUDManager.LoadHUD(Settings.SavedHUD);
}
}
public struct JSONAudioParams
{
public string[] sounds;
public float volume;
public float pitch;
public bool FromJSON(JObject jObject)
{
if (jObject == null)
{
return false;
}
JToken obj = jObject["Clips"];
JArray val = (JArray)(object)((obj is JArray) ? obj : null);
if (val != null)
{
sounds = new string[((JContainer)val).Count];
for (int i = 0; i < sounds.Length; i++)
{
sounds[i] = Extensions.Value<string>((IEnumerable<JToken>)val[i]);
}
}
volume = Extensions.Value<float>((IEnumerable<JToken>)jObject["Volume"]);
pitch = Extensions.Value<float>((IEnumerable<JToken>)jObject["Pitch"]);
return true;
}
}
public struct JSONHUDManifest
{
public string Name;
public string Author;
public string Description;
public string[] Tags;
public string AssetName;
public Texture2D Logo;
public bool FromJSON(string pathToJson)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using (StreamReader streamReader = new StreamReader(pathToJson))
{
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
JToken obj = JToken.ReadFrom((JsonReader)(object)val);
JObject val2 = (JObject)(object)((obj is JObject) ? obj : null);
if (val2 == null)
{
return false;
}
Name = Extensions.Value<string>((IEnumerable<JToken>)val2["name"]);
Author = Extensions.Value<string>((IEnumerable<JToken>)val2["author"]);
AssetName = Extensions.Value<string>((IEnumerable<JToken>)val2["assetName"]);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
return true;
}
public void SetHUDLogo(Texture2D texture)
{
Logo = texture;
}
}
public struct JSONMult
{
public string EventType;
public string TierEventType;
public float DecayTime;
public bool Stackable;
public JSONAudioParams EventAudio;
public string Name;
public float Multiplier;
public string Condition;
public int TierRequirement;
public JSONMult[] Tiers;
public bool FromJSON(string pathToJson)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using (StreamReader streamReader = new StreamReader(pathToJson))
{
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
JToken obj = JToken.ReadFrom((JsonReader)(object)val);
JObject val2 = (JObject)(object)((obj is JObject) ? obj : null);
if (val2 == null)
{
return false;
}
ReadMultObject(val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
return true;
}
private void ReadMultObject(JObject obj)
{
EventType = Extensions.Value<string>((IEnumerable<JToken>)obj["EventType"]);
DecayTime = Extensions.Value<float>((IEnumerable<JToken>)obj["DecayTime"]);
Stackable = Extensions.Value<bool>((IEnumerable<JToken>)obj["Stackable"]);
Condition = Extensions.Value<string>((IEnumerable<JToken>)obj["Condition"]);
EventAudio.FromJSON(Extensions.Value<JObject>((IEnumerable<JToken>)obj["EventAudio"]));
Name = Extensions.Value<string>((IEnumerable<JToken>)obj["Name"]);
Multiplier = Extensions.Value<float>((IEnumerable<JToken>)obj["Multiplier"]);
TierRequirement = Extensions.Value<int>((IEnumerable<JToken>)obj["TierRequirement"]);
JToken obj2 = obj["Tiers"];
JArray val = ((obj2 != null) ? Extensions.Value<JArray>((IEnumerable<JToken>)obj2) : null);
List<JSONMult> list = new List<JSONMult>();
if (val != null)
{
for (int i = 0; i < ((JContainer)val).Count; i++)
{
JSONMult item = default(JSONMult);
JToken obj3 = val[i];
JObject obj4 = (JObject)(object)((obj3 is JObject) ? obj3 : null);
item.ReadMultObject(obj4);
list.Add(item);
}
Tiers = list.ToArray();
}
}
}
public struct JSONScore
{
public string EventType;
public string TierEventType;
public float DecayTime;
public bool Stackable;
public JSONAudioParams EventAudio;
public string Name;
public int Score;
public int TierRequirement;
public JSONScore[] Tiers;
public bool FromJSON(string pathToJson)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using (StreamReader streamReader = new StreamReader(pathToJson))
{
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
JToken obj = JToken.ReadFrom((JsonReader)(object)val);
JObject val2 = (JObject)(object)((obj is JObject) ? obj : null);
if (val2 == null)
{
return false;
}
ReadScoreObject(val2);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
return true;
}
private void ReadScoreObject(JObject obj)
{
EventType = Extensions.Value<string>((IEnumerable<JToken>)obj["EventType"]);
DecayTime = Extensions.Value<float>((IEnumerable<JToken>)obj["DecayTime"]);
Stackable = Extensions.Value<bool>((IEnumerable<JToken>)obj["Stackable"]);
EventAudio.FromJSON(Extensions.Value<JObject>((IEnumerable<JToken>)obj["EventAudio"]));
Name = Extensions.Value<string>((IEnumerable<JToken>)obj["Name"]);
Score = Extensions.Value<int>((IEnumerable<JToken>)obj["Score"]);
TierRequirement = Extensions.Value<int>((IEnumerable<JToken>)obj["TierRequirement"]);
JToken obj2 = obj["Tiers"];
JArray val = ((obj2 != null) ? Extensions.Value<JArray>((IEnumerable<JToken>)obj2) : null);
List<JSONScore> list = new List<JSONScore>();
if (val != null)
{
for (int i = 0; i < ((JContainer)val).Count; i++)
{
JSONScore item = default(JSONScore);
JToken obj3 = val[i];
JObject obj4 = (JObject)(object)((obj3 is JObject) ? obj3 : null);
item.ReadScoreObject(obj4);
list.Add(item);
}
Tiers = list.ToArray();
}
}
}
public struct MarrowSceneInfo
{
public string LevelTitle;
public string Barcode;
public MarrowScene MarrowScene;
}
public static class EventType
{
public static class Score
{
public static readonly string Kill = "SCORE_KILL";
public static readonly string Headshot = "SCORE_HEADSHOT";
public static readonly string EnemyMidAirKill = "SCORE_MID_AIR";
public static readonly string GameWaveCompleted = "SCORE_WAVE_COMPLETED";
public static readonly string GameRoundCompleted = "SCORE_ROUND_COMPLETED";
public static readonly string Crabcest = "SCORE_CRABCEST";
public static readonly string Facehug = "SCORE_FACEHUG";
public static readonly string StealthKill = "SCORE_STEALTH_KILL";
}
public static class Mult
{
public static readonly string Kill = "MULT_KILL";
public static readonly string MidAir = "MULT_MIDAIR";
public static readonly string Seated = "MULT_SEATED";
public static readonly string SecondWind = "MULT_SECONDWIND";
public static readonly string Ragolled = "MULT_RAGDOLLED";
public static readonly string SwappedAvatars = "MULT_SWAPPED_AVATARS";
public static readonly string SlowMo = "MULT_SLOWMO";
}
public static readonly string None = "None";
}
public class PackedAudioParams
{
public AudioClip[] Clips { get; private set; }
public float Volume { get; private set; }
public float Pitch { get; private set; }
public PackedAudioParams()
{
Clips = null;
Volume = 1f;
Pitch = 1f;
}
public PackedAudioParams(JSONAudioParams audioParams)
{
Clips = (AudioClip[])(object)new AudioClip[audioParams.sounds.Length];
for (int i = 0; i < Clips.Length; i++)
{
Clips[i] = HUDLoader.HUDAudioBank[audioParams.sounds[i]];
}
Volume = audioParams.volume;
Pitch = audioParams.pitch;
}
}
public class PackedHighScore : PackedValue
{
public int bestScore;
public override PackedType PackedValueType => PackedType.HighScore;
public PackedHighScore(string name, int bestScore)
{
this.bestScore = bestScore;
}
public override void OnValueCreated()
{
}
public override void OnValueRemoved()
{
}
}
[Serializable]
public class PackedMultiplier : PackedValue
{
public float Multiplier;
public float AccumulatedMultiplier;
public string Condition;
private bool _timed;
private bool _timeBegin;
public override PackedType PackedValueType => PackedType.Multiplier;
public float Elapsed => _tDecay;
public Func<bool> condition { get; private set; }
public PackedMultiplier()
{
}
public PackedMultiplier(JSONMult mult, bool useTiers = false)
{
eventType = mult.EventType;
DecayTime = mult.DecayTime;
Stackable = mult.Stackable;
Name = mult.Name;
Multiplier = mult.Multiplier;
Condition = mult.Condition;
TierRequirement = mult.TierRequirement;
EventAudio = new PackedAudioParams(mult.EventAudio);
if (useTiers)
{
TierEventType = mult.TierEventType;
}
}
public override void OnValueCreated()
{
if (DecayTime != 0f)
{
_timed = true;
}
condition = API.GameConditions.GetCondition(Condition);
AccumulatedMultiplier = Multiplier;
_tDecay = DecayTime;
}
public override void OnValueRemoved()
{
_timeBegin = false;
ResetTier();
}
public override void OnUpdate()
{
if (condition != null && !condition())
{
ScoreTracker.Remove(this);
}
OnUpdateDecay();
}
public override void OnUpdateDecay()
{
if (_timed)
{
if (!_timeBegin)
{
API.Multiplier.OnMultiplierTimeBegin?.Invoke(this);
_timeBegin = true;
}
if (_tDecay <= 0f)
{
API.Multiplier.OnMultiplierTimeExpired?.Invoke(this);
_tDecay = DecayTime;
ScoreTracker.Remove(this);
}
_tDecay -= Time.deltaTime;
}
}
}
[Serializable]
public class PackedScore : PackedValue
{
public int Score;
public int AccumulatedScore;
public override PackedType PackedValueType => PackedType.Score;
public PackedScore()
{
}
public PackedScore(JSONScore score, bool useTiers = false)
{
eventType = score.EventType;
DecayTime = score.DecayTime;
Stackable = score.Stackable;
Name = score.Name;
Score = score.Score;
TierRequirement = score.TierRequirement;
EventAudio = new PackedAudioParams(score.EventAudio);
if (useTiers)
{
TierEventType = score.TierEventType;
}
else
{
AccumulatedScore = score.Score;
}
}
public override void OnValueCreated()
{
_tDecay = DecayTime;
AccumulatedScore = Score;
}
public override void OnValueRemoved()
{
ResetTier();
}
public override void OnUpdate()
{
OnUpdateDecay();
}
public override void OnUpdateDecay()
{
if (_tDecay <= 0f)
{
ScoreTracker.Remove(this);
}
_tDecay -= Time.deltaTime;
}
}
[Serializable]
public class PackedValue
{
public enum PackedType
{
Base,
Score,
Multiplier,
HighScore,
Misc
}
public string Name;
public string eventType;
public string TierEventType;
public PackedAudioParams EventAudio;
public bool Stackable;
public float DecayTime;
public float PostDecayTime;
public PackedValue Parent;
public PackedValue[] Tiers;
public int TierRequirement;
protected float _tDecay;
private int _tierIndex;
private int _tierRequirementIndex;
public virtual PackedType PackedValueType => PackedType.Base;
public PackedValue CurrentTier
{
get
{
if (Tiers == null || Tiers.Length == 0)
{
return this;
}
if (_tierIndex == Tiers.Length)
{
_tierIndex = Tiers.Length;
return Tiers[_tierIndex];
}
return Tiers[_tierIndex];
}
}
public PackedValue NextTier
{
get
{
if (_tierIndex + 1 >= Tiers.Length)
{
return Tiers[_tierIndex];
}
return Tiers[_tierIndex + 1];
}
}
public int TierIndex => _tierIndex;
public int TierRequirementIndex => _tierRequirementIndex;
public virtual bool IsActive { get; }
public virtual void OnValueCreated()
{
}
public virtual void OnValueRemoved()
{
}
public virtual void OnUpdate()
{
}
public virtual void OnUpdateDecay()
{
}
public void SetDecayTime(float decayTime)
{
_tDecay = decayTime;
}
public void ToNextTier()
{
_tierRequirementIndex++;
if (_tierRequirementIndex >= TierRequirement)
{
_tierRequirementIndex = TierRequirement;
API.Value.OnValueTierReached?.Invoke(CurrentTier);
if (_tierIndex + 1 < Tiers.Length)
{
_tierIndex++;
}
}
}
protected void ResetTier()
{
_tierIndex = 0;
}
}
public static class ValueManager
{
public static Dictionary<string, int> HighScoreTable;
public static readonly string Path_Developer = Path.Combine(MelonEnvironment.UserDataDirectory, "Not Enough Photons");
public static readonly string Path_Mod = Path.Combine(Path_Developer, "ScoreLab");
private static readonly string File_HighScores = Path.Combine(Path_Mod, "high_score_table.json");
public static Dictionary<string, ValuePackage> Packages { get; private set; }
public static ValuePackage ActivePackage { get; private set; }
public static void Initialize()
{
HighScoreTable = new Dictionary<string, int>();
Packages = new Dictionary<string, ValuePackage>();
foreach (JSONHUDManifest loadedHUDManifest in HUDLoader.LoadedHUDManifests)
{
JSONScore[] scoresForHUD = GetScoresForHUD(loadedHUDManifest.Name);
JSONMult[] multipliersForHUD = GetMultipliersForHUD(loadedHUDManifest.Name);
PackedScore[] scores = CreateScoreObjects(scoresForHUD);
PackedMultiplier[] multipliers = CreateMultiplierObjects(multipliersForHUD);
Packages.Add(loadedHUDManifest.Name, new ValuePackage(scores, multipliers));
}
UsePackage(Settings.SavedHUD);
}
public static string[] GetAllFiles(string path, string extensionFilter)
{
string[] files = Directory.GetFiles(path);
List<string> list = new List<string>();
string[] array = files;
foreach (string text in array)
{
if (text.EndsWith(extensionFilter))
{
list.Add(text);
}
}
return list.ToArray();
}
public static void UsePackage(string name)
{
if (Packages.TryGetValue(name, out var value))
{
ActivePackage = value;
}
}
public static PackedValue Get(string eventType)
{
if (ActivePackage.Values == null)
{
return null;
}
if (ActivePackage.Values.TryGetValue(eventType, out var value))
{
return value;
}
return null;
}
public static Dictionary<string, int> ReadHighScore()
{
return JsonConvert.DeserializeObject(File_HighScores) as Dictionary<string, int>;
}
public static void WriteHighScore()
{
string file_HighScores = File_HighScores;
if (!File.Exists(file_HighScores))
{
Main.Logger.Warning("High score file doesn't exist! Creating one.");
File.Create(file_HighScores);
}
else
{
string contents = JsonConvert.SerializeObject((object)HighScoreTable);
File.WriteAllText(file_HighScores, contents);
}
}
public static void WriteBestScore(PackedHighScore highScore)
{
string name = highScore.Name;
int bestScore = highScore.bestScore;
HighScoreTable.Add(name, bestScore);
}
private static JSONScore[] GetScoresForHUD(string name)
{
string path = Path.Combine(Path_Mod, name + "/Data/Score");
if (!Directory.Exists(path))
{
Main.Logger.Warning("HUD " + name + " doesn't have a score data folder!");
return null;
}
string[] allFiles = GetAllFiles(path, ".json");
List<JSONScore> list = new List<JSONScore>();
string[] array = allFiles;
for (int i = 0; i < array.Length; i++)
{
JSONScore item = ReadScoreData(array[i]);
list.Add(item);
}
return list.ToArray();
}
private static JSONMult[] GetMultipliersForHUD(string name)
{
string path = Path.Combine(Path_Mod, name + "/Data/Multiplier");
if (!Directory.Exists(path))
{
Main.Logger.Warning("HUD " + name + " doesn't have a multiplier data folder!");
return null;
}
string[] allFiles = GetAllFiles(path, ".json");
List<JSONMult> list = new List<JSONMult>();
string[] array = allFiles;
for (int i = 0; i < array.Length; i++)
{
JSONMult item = ReadMultiplierData(array[i]);
list.Add(item);
}
return list.ToArray();
}
private static PackedScore[] CreateScoreObjects(JSONScore[] scores)
{
if (scores == null)
{
return null;
}
List<PackedScore> list = new List<PackedScore>();
for (int i = 0; i < scores.Length; i++)
{
JSONScore score = scores[i];
PackedScore packedScore = new PackedScore(score);
if (score.Tiers != null && score.Tiers.Length != 0)
{
List<PackedScore> list2 = new List<PackedScore>();
JSONScore[] tiers = score.Tiers;
for (int j = 0; j < tiers.Length; j++)
{
PackedScore packedScore2 = new PackedScore(tiers[j], useTiers: true);
packedScore2.eventType = packedScore.eventType;
list2.Add(packedScore2);
}
PackedValue[] tiers2 = list2.ToArray();
packedScore.Tiers = tiers2;
}
list.Add(packedScore);
}
return list.ToArray();
}
private static PackedMultiplier[] CreateMultiplierObjects(JSONMult[] multipliers)
{
if (multipliers == null)
{
return null;
}
List<PackedMultiplier> list = new List<PackedMultiplier>();
for (int i = 0; i < multipliers.Length; i++)
{
JSONMult mult = multipliers[i];
PackedMultiplier packedMultiplier = new PackedMultiplier(mult);
if (mult.Tiers != null && mult.Tiers.Length != 0)
{
List<PackedMultiplier> list2 = new List<PackedMultiplier>();
JSONMult[] tiers = mult.Tiers;
for (int j = 0; j < tiers.Length; j++)
{
PackedMultiplier packedMultiplier2 = new PackedMultiplier(tiers[j], useTiers: true);
packedMultiplier2.eventType = packedMultiplier.eventType;
list2.Add(packedMultiplier2);
}
PackedValue[] tiers2 = list2.ToArray();
packedMultiplier.Tiers = tiers2;
}
list.Add(packedMultiplier);
}
return list.ToArray();
}
private static JSONScore ReadScoreData(string file)
{
JSONScore result = default(JSONScore);
result.FromJSON(file);
return result;
}
private static JSONMult ReadMultiplierData(string file)
{
JSONMult result = default(JSONMult);
result.FromJSON(file);
return result;
}
}
public struct ValuePackage
{
public Dictionary<string, PackedValue> Values;
public ValuePackage(PackedScore[] scores, PackedMultiplier[] multipliers)
{
Values = new Dictionary<string, PackedValue>();
if (scores != null)
{
foreach (PackedScore packedScore in scores)
{
Values.Add(packedScore.eventType, packedScore);
}
}
if (multipliers != null)
{
foreach (PackedMultiplier packedMultiplier in multipliers)
{
Values.Add(packedMultiplier.eventType, packedMultiplier);
}
}
}
}
}
namespace NEP.ScoreLab.Core
{
public static class API
{
public static class Value
{
public static Action<PackedValue> OnValueAdded;
public static Action<PackedValue> OnValueAccumulated;
public static Action<PackedValue> OnValueTierReached;
public static Action<PackedValue> OnValueRemoved;
}
public static class Score
{
public static Action<int> OnScoreUpdated;
public static Action<int> OnScoreDifferenceUpdated;
public static Action<int> OnLastScoreUpdated;
}
public static class Multiplier
{
public static Action<PackedMultiplier> OnMultiplierTimeBegin;
public static Action<PackedMultiplier> OnMultiplierTimeExpired;
}
public static class HighScore
{
public static Action<PackedHighScore> OnHighScoreReached;
public static Action<PackedHighScore> OnHighScoreUpdated;
public static Action<PackedHighScore> OnHighScoreLoaded;
public static Action<PackedHighScore> OnHighScoreSaved;
}
public static class GameConditions
{
private static Dictionary<string, Func<bool>> _conditionTable = new Dictionary<string, Func<bool>>
{
{
"IsPlayerMoving",
() => ScoreDirector.IsPlayerMoving
},
{
"IsPlayerSeated",
() => ScoreDirector.IsPlayerSeated
},
{
"IsPlayerInAir",
() => ScoreDirector.IsPlayerInAir
},
{
"IsPlayerRagdolled",
() => ScoreDirector.IsPlayerRagdolled
},
{
"IsSlowMoEnabled",
() => ScoreDirector.IsSlowMoEnabled
}
};
public static Func<bool> GetCondition(string cond)
{
if (string.IsNullOrEmpty(cond))
{
Debug.LogWarning(Object.op_Implicit(cond + " doesn't exist in the condition table."));
return null;
}
if (!_conditionTable.ContainsKey(cond))
{
Debug.LogWarning(Object.op_Implicit(cond + " doesn't exist in the condition table."));
return null;
}
return _conditionTable[cond];
}
}
public static class UI
{
public static Action<NEP.ScoreLab.HUD.Module> OnModuleEnabled;
public static Action<NEP.ScoreLab.HUD.Module> OnModuleDisabled;
public static Action<NEP.ScoreLab.HUD.Module> OnModuleDecayed;
public static Action<NEP.ScoreLab.HUD.Module> OnModulePostDecayed;
}
}
public static class ScoreDirector
{
public static class Patches
{
[HarmonyPatch(typeof(Projectile), "Awake")]
public static class ProjectilePatch
{
public static void Postfix(Projectile __instance)
{
Action<Collider, Vector3, Vector3> action = OnProjectileCollision;
((UnityEvent<Collider, Vector3, Vector3>)(object)__instance.onCollision).AddListener(UnityAction<Collider, Vector3, Vector3>.op_Implicit(action));
}
private static void OnProjectileCollision(Collider collider, Vector3 world, Vector3 normal)
{
MarrowBody val = MarrowBody.Cache.Get(((Component)collider).gameObject);
if (!((Object)(object)val == (Object)null))
{
TriggerRefProxy component = ((Component)val).GetComponent<TriggerRefProxy>();
if (!((Object)(object)component == (Object)null) && !component.aiManager.isDead && (Object)(object)((Component)component.targetHead).gameObject == (Object)(object)((Component)val).gameObject)
{
ScoreTracker.Add(EventType.Score.Headshot);
}
}
}
}
[HarmonyPatch(typeof(RigManager), "SwitchAvatar")]
public static class RigManagerSwapAvatarPatch
{
public static void Postfix(Avatar newAvatar)
{
_playerRecentlySwappedAvatars = true;
}
}
[HarmonyPatch(typeof(BehaviourCrablet))]
[HarmonyPatch("AttachToFace")]
public static class CrabletAttachToFacePatch
{
public static void Postfix(Rigidbody face, TriggerRefProxy trp, bool preAttach = false, bool isPlayer = true)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
if (!isPlayer)
{
if ((int)trp.npcType == 32)
{
ScoreTracker.Add(EventType.Score.Crabcest);
}
else
{
ScoreTracker.Add(EventType.Score.Facehug);
}
}
}
}
[HarmonyPatch(typeof(Seat))]
[HarmonyPatch("Register")]
public static class RegisterSeatPatch
{
public static void Postfix(RigManager rM)
{
IsPlayerSeated = true;
ScoreTracker.Add(EventType.Mult.Seated);
}
}
[HarmonyPatch(typeof(Seat))]
[HarmonyPatch("DeRegister")]
public static class DeRegisterSeatPatch
{
public static void Postfix()
{
IsPlayerSeated = false;
}
}
[HarmonyPatch(typeof(Player_Health))]
[HarmonyPatch("LifeSavingDamgeDealt")]
public static class SecondWindPatch
{
public static void Postfix()
{
ScoreTracker.Add(EventType.Mult.SecondWind);
}
}
[HarmonyPatch(typeof(Arena_GameController))]
[HarmonyPatch("StartNextWave")]
public static class StartNextWavePatch
{
public static void Postfix(Arena_GameController __instance)
{
ScoreTracker.Add(EventType.Score.GameWaveCompleted);
}
}
[HarmonyPatch(typeof(Arena_GameController))]
[HarmonyPatch("EndOfRound")]
public static class StartNextRoundPatch
{
public static void Postfix(Arena_GameController __instance)
{
ScoreTracker.Add(EventType.Score.GameRoundCompleted);
}
}
[HarmonyPatch(typeof(PhysicsRig))]
[HarmonyPatch("OnUpdate")]
public static class PhysRigPatch
{
private static bool _midAirTargetBool;
private static float _tMidAirDelay = 0.5f;
private static float _tAirTime;
private static bool _ragdolledTargetBool;
private static float _tRagdollDelay = 0.5f;
private static float _tRagdollTime;
public static void Postfix(PhysicsRig __instance)
{
IsPlayerInAir = !__instance.physG.isGrounded;
if (IsPlayerInAir)
{
if (!_midAirTargetBool)
{
_tAirTime += Time.deltaTime;
if (_tAirTime > _tMidAirDelay)
{
ScoreTracker.Add(EventType.Mult.MidAir);
_midAirTargetBool = true;
}
}
}
else
{
_tAirTime = 0f;
_midAirTargetBool = false;
}
if (IsPlayerRagdolled)
{
if (!_ragdolledTargetBool)
{
_ragdolledTargetBool = true;
}
}
else
{
_ragdolledTargetBool = false;
}
if (_playerRecentlySwappedAvatars)
{
ScoreTracker.Add(EventType.Mult.SwappedAvatars);
_playerRecentlySwappedAvatars = false;
}
}
}
[HarmonyPatch(typeof(PhysicsRig))]
[HarmonyPatch("RagdollRig")]
public static class PhysRigRagdollPatch
{
public static void Postfix(PhysicsRig __instance)
{
IsPlayerRagdolled = true;
}
}
[HarmonyPatch(typeof(PhysicsRig))]
[HarmonyPatch("UnRagdollRig")]
public static class PhysRigUnRagdollPatch
{
public static void Postfix(PhysicsRig __instance)
{
IsPlayerRagdolled = false;
}
}
[HarmonyPatch(typeof(TimeManager), "OnPostTimeUpdate")]
public static class TimeManagerUpdatePatch
{
private static bool _slowmoSwitch;
public static void Postfix()
{
}
}
[HarmonyPatch(typeof(TimeManager), "INCREASE_TIMESCALE")]
public static class TimeManagerIncreaseTimePatch
{
public static void Postfix()
{
}
}
[HarmonyPatch(typeof(TimeManager), "DECREASE_TIMESCALE")]
public static class TimeManagerDecreaseTimePatch
{
public static void Postfix()
{
}
}
public static void InitPatches()
{
Hooking.OnNPCKillStart += OnAIDeath;
}
public static void OnAIDeath(BehaviourBaseNav behaviour)
{
ScoreTracker.Add(ValueManager.Get(EventType.Score.Kill));
ScoreTracker.Add(ValueManager.Get(EventType.Mult.Kill));
if (!behaviour.sensors.isGrounded)
{
ScoreTracker.Add(EventType.Score.EnemyMidAirKill);
}
if ((Object)(object)behaviour.sensors.target == (Object)null)
{
ScoreTracker.Add(EventType.Score.StealthKill);
}
}
}
public static readonly string PlayerName = "";
public static bool IsPlayerMoving = false;
public static bool IsPlayerInAir = false;
public static bool IsPlayerSeated = false;
public static bool IsPlayerRagdolled = false;
public static bool IsSlowMoEnabled = false;
private static bool _playerRecentlySwappedAvatars = false;
}
public static class ScoreTracker
{
private static int _score = 0;
private static int _lastScore = 0;
private static float _multiplier = 1f;
private static float _baseMultiplier = 1f;
public static List<PackedValue> ActiveValues { get; private set; }
public static int Score => _score;
public static int LastScore => _lastScore;
public static float Multiplier => _multiplier;
public static void Initialize()
{
ActiveValues = new List<PackedValue>();
}
public static void Update()
{
if (ActiveValues != null)
{
for (int i = 0; i < ActiveValues.Count; i++)
{
ActiveValues[i].OnUpdate();
}
}
}
public static void Add(string eventType)
{
Add(Create(eventType));
}
public static void Add(PackedValue value)
{
if (value != null)
{
if (value.PackedValueType == PackedValue.PackedType.Score)
{
SetPackedScore((PackedScore)value);
}
else if (value.PackedValueType == PackedValue.PackedType.Multiplier)
{
SetPackedMultiplier((PackedMultiplier)value);
}
}
}
public static void Remove(PackedValue value)
{
if (value.PackedValueType == PackedValue.PackedType.Score)
{
ActiveValues.Remove(value);
value.OnValueRemoved();
API.Value.OnValueRemoved?.Invoke(value);
}
else if (value.PackedValueType == PackedValue.PackedType.Multiplier)
{
ActiveValues.Remove(value);
RemoveMultiplier((value as PackedMultiplier).AccumulatedMultiplier);
value.OnValueRemoved();
API.Value.OnValueRemoved?.Invoke(value);
}
}
public static void AddScore(int score)
{
_lastScore = _score;
_score += Mathf.RoundToInt((float)score * _multiplier);
}
public static void AddMultiplier(float multiplier)
{
_multiplier += multiplier;
}
public static void SetMultiplier(float multiplier)
{
_multiplier = multiplier;
}
public static void ResetScore()
{
_score = 0;
_lastScore = 0;
}
public static void ResetMultiplier()
{
_multiplier = 1f;
}
public static void ResetAll()
{
ResetScore();
ResetMultiplier();
ResetHighScore();
ActiveValues.Clear();
}
public static void ResetHighScore()
{
}
public static void RemoveMultiplier(float multiplier)
{
if (_multiplier < _baseMultiplier)
{
_multiplier = _baseMultiplier;
}
_multiplier -= multiplier;
}
public static bool CheckDuplicate(PackedValue value)
{
foreach (PackedValue activeValue in ActiveValues)
{
if (activeValue.eventType == value.eventType)
{
return true;
}
}
return false;
}
private static void SetPackedScore(PackedScore score)
{
if (score != null)
{
if (!CheckDuplicate(score))
{
InitializeValue(score);
AddScore(score.Score);
ActiveValues.Add(score);
API.Value.OnValueAdded?.Invoke(score);
}
else if (score.Tiers != null)
{
PackedScore clone = GetClone<PackedScore>(score);
PackedScore packedScore = (PackedScore)clone.CurrentTier;
clone.ToNextTier();
clone.TierRequirement = packedScore.TierRequirement;
clone.SetDecayTime(packedScore.DecayTime);
AddScore(packedScore.Score);
}
else if (score.Stackable)
{
PackedScore clone2 = GetClone<PackedScore>(score);
AddScore(score.Score);
clone2.SetDecayTime(clone2.DecayTime);
clone2.AccumulatedScore += clone2.Score;
API.Value.OnValueAccumulated?.Invoke(clone2);
}
else
{
PackedScore packedScore2 = CopyFromScore(score);
InitializeValue(packedScore2);
AddScore(packedScore2.Score);
ActiveValues.Add(packedScore2);
API.Value.OnValueAdded?.Invoke(packedScore2);
}
}
}
private static void SetPackedMultiplier(PackedMultiplier multiplier)
{
if (multiplier != null)
{
if (!CheckDuplicate(multiplier))
{
InitializeValue(multiplier);
AddMultiplier(multiplier.Multiplier);
ActiveValues.Add(multiplier);
API.Value.OnValueAdded?.Invoke(multiplier);
}
else if (multiplier.Tiers != null)
{
PackedMultiplier clone = GetClone<PackedMultiplier>(multiplier);
PackedMultiplier packedMultiplier = (PackedMultiplier)clone.CurrentTier;
clone.ToNextTier();
clone.TierRequirement = packedMultiplier.TierRequirement;
clone.SetDecayTime(packedMultiplier.DecayTime);
AddMultiplier(packedMultiplier.Multiplier);
multiplier.AccumulatedMultiplier += packedMultiplier.Multiplier;
API.Value.OnValueTierReached?.Invoke(packedMultiplier);
}
else if (multiplier.Stackable)
{
PackedMultiplier clone2 = GetClone<PackedMultiplier>(multiplier);
AddMultiplier(multiplier.Multiplier);
clone2.SetDecayTime(clone2.DecayTime);
clone2.AccumulatedMultiplier += clone2.Multiplier;
API.Value.OnValueAccumulated?.Invoke(clone2);
}
else
{
PackedMultiplier packedMultiplier2 = CopyFromMult(multiplier);
InitializeValue(packedMultiplier2);
AddMultiplier(multiplier.Multiplier);
ActiveValues.Add(packedMultiplier2);
API.Value.OnValueAdded?.Invoke(packedMultiplier2);
}
}
}
private static PackedScore CopyFromScore(PackedScore original)
{
return new PackedScore
{
eventType = original.eventType,
Name = original.Name,
Score = original.Score,
EventAudio = original.EventAudio,
DecayTime = original.DecayTime
};
}
private static PackedMultiplier CopyFromMult(PackedMultiplier original)
{
return new PackedMultiplier
{
eventType = original.eventType,
Name = original.Name,
Multiplier = original.Multiplier,
EventAudio = original.EventAudio,
DecayTime = original.DecayTime,
Condition = original.Condition
};
}
private static PackedValue Create(string eventType)
{
PackedValue packedValue = ValueManager.Get(eventType);
if (packedValue == null)
{
return null;
}
if (packedValue.PackedValueType == PackedValue.PackedType.Score)
{
PackedScore packedScore = (PackedScore)packedValue;
return new PackedScore
{
eventType = packedScore.eventType,
Stackable = packedScore.Stackable,
DecayTime = packedScore.DecayTime,
Name = packedScore.Name,
Score = packedScore.Score,
EventAudio = packedScore.EventAudio,
TierRequirement = packedScore.TierRequirement,
Tiers = packedScore.Tiers
};
}
if (packedValue.PackedValueType == PackedValue.PackedType.Multiplier)
{
PackedMultiplier packedMultiplier = (PackedMultiplier)packedValue;
return new PackedMultiplier
{
eventType = packedMultiplier.eventType,
Stackable = packedMultiplier.Stackable,
DecayTime = packedMultiplier.DecayTime,
Name = packedMultiplier.Name,
Multiplier = packedMultiplier.Multiplier,
Condition = packedMultiplier.Condition,
EventAudio = packedMultiplier.EventAudio,
TierRequirement = packedMultiplier.TierRequirement,
Tiers = packedMultiplier.Tiers
};
}
return null;
}
private static void InitializeValue(PackedValue value)
{
value.OnValueCreated();
value.SetDecayTime(value.DecayTime);
}
private static T GetClone<T>(PackedValue value) where T : PackedValue
{
return (T)ActiveValues.Find((PackedValue match) => match.eventType == value.eventType);
}
}
public static class Settings
{
public static float DistanceToCamera;
public static float MovementSmoothness;
public static bool UseAnnouncer;
public static string SavedHUD;
public static HUDShowMode HUDShowMode;
private static MelonPreferences_Category m_scorelabCategory;
private static MelonPreferences_Entry<float> m_eDistanceToCamera;
private static MelonPreferences_Entry<float> m_eMovementSmoothness;
private static MelonPreferences_Entry<bool> m_eUseAnnouncer;
private static MelonPreferences_Entry<string> m_eSavedHUD;
private static MelonPreferences_Entry<int> m_eHudShowMode;
public static void CreatePreferences()
{
m_scorelabCategory = MelonPreferences.CreateCategory("ScoreLab");
m_eDistanceToCamera = m_scorelabCategory.CreateEntry<float>("DistanceToCamera", 1.125f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eMovementSmoothness = m_scorelabCategory.CreateEntry<float>("MovementSmoothness", 16f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eUseAnnouncer = m_scorelabCategory.CreateEntry<bool>("UseAnnouncer", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eSavedHUD = m_scorelabCategory.CreateEntry<string>("SavedHUD", "Coda", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
m_eHudShowMode = m_scorelabCategory.CreateEntry<int>("HUDShowMode", 0, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
DistanceToCamera = m_eDistanceToCamera.Value;
MovementSmoothness = m_eMovementSmoothness.Value;
UseAnnouncer = m_eUseAnnouncer.Value;
SavedHUD = m_eSavedHUD.Value;
HUDShowMode = (HUDShowMode)m_eHudShowMode.Value;
}
public static void Save(bool log = false)
{
m_eDistanceToCamera.Value = DistanceToCamera;
m_eMovementSmoothness.Value = MovementSmoothness;
m_eUseAnnouncer.Value = UseAnnouncer;
m_eSavedHUD.Value = SavedHUD;
m_scorelabCategory.SaveToFile(log);
}
public static void SetDistanceToCamera(float distance)
{
m_eDistanceToCamera.Value = distance;
}
public static void SetMovementSmoothness(float movementSmoothness)
{
m_eMovementSmoothness.Value = movementSmoothness;
}
public static void SetUseAnnouncer(bool useAnnouncer)
{
m_eUseAnnouncer.Value = useAnnouncer;
}
public static void SetHUDShowMode(HUDShowMode mode)
{
m_eHudShowMode.Value = (int)mode;
HUDManager.HUDShowModeUpdated(mode);
}
}
}
namespace NEP.ScoreLab.Audio
{
public static class AudioManager
{
public static void Initialize()
{
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAdded, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueTierReached, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Combine(API.Value.OnValueAccumulated, new Action<PackedValue>(OnValueReceived));
}
public static void Uninitialize()
{
API.Value.OnValueAdded = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAdded, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueTierReached = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueTierReached, new Action<PackedValue>(OnValueReceived));
API.Value.OnValueAccumulated = (Action<PackedValue>)Delegate.Remove(API.Value.OnValueAccumulated, new Action<PackedValue>(OnValueReceived));
}
private static void OnValueReceived(PackedValue value)
{
if (Settings.UseAnnouncer && value.EventAudio != null && value.EventAudio.Clips != null && value.EventAudio.Clips.Length != 0)
{
AudioClip val = null;
if (value.EventAudio.Clips.Length == 1)
{
val = value.EventAudio.Clips[0];
}
else
{
int num = Random.Range(0, value.EventAudio.Clips.Length);
val = value.EventAudio.Clips[num];
}
Play(val, value.EventAudio.Volume, value.EventAudio.Pitch);
}
}
public static void Play(AudioClip clip, float volume = 1f, float pitch = 1f)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
Audio.PlayAtPoint(clip, Vector3.zero, Audio.InHead, volume, pitch, 0f);
}
}
}