Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Train v1.0.2
Train.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Improve; using MenuLib; using MenuLib.MonoBehaviors; using MenuLib.Structs; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("headclef")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2+1f7c4646c97451df4d6379d8fb7c12d0e76c5820")] [assembly: AssemblyProduct("Train")] [assembly: AssemblyTitle("Train")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Train { public static class SaveData { public sealed class TrainStat { public readonly string Id; public readonly string CsKey; public readonly string GameField; public readonly string Display; public ConfigEntry<int> Progress; public TrainStat(string id, string csKey, string gameField, string display) { Id = id; CsKey = csKey; GameField = gameField; Display = display; } } public const int Tier1MaxLevel = 3; public const int Tier2MaxLevel = 10; public const int Tier1Factor = 9; public const int Tier2Factor = 25; public const int Tier3Factor = 100; public static readonly TrainStat[] Stats = new TrainStat[11] { new TrainStat("TumbleLaunch", "Launch", "playerUpgradeLaunch", "Tumble Launch"), new TrainStat("ExtraJump", "Extra Jump", "playerUpgradeExtraJump", "Extra Jump"), new TrainStat("Throw", "Throw", "playerUpgradeThrow", "Throw"), new TrainStat("GrabRange", "Range", "playerUpgradeRange", "Grab Range"), new TrainStat("GrabStrength", "Strength", "playerUpgradeStrength", "Grab Strength"), new TrainStat("TumbleClimb", "Tumble Climb", "playerUpgradeTumbleClimb", "Tumble Climb"), new TrainStat("TumbleWings", "Tumble Wings", "playerUpgradeTumbleWings", "Tumble Wings"), new TrainStat("Health", "Health", "playerUpgradeHealth", "Health"), new TrainStat("SprintSpeed", "Speed", "playerUpgradeSpeed", "Sprint Speed"), new TrainStat("Stamina", "Stamina", "playerUpgradeStamina", "Stamina"), new TrainStat("CrouchRest", "Crouch Rest", "playerUpgradeCrouchRest", "Crouch Rest") }; private static readonly Dictionary<string, TrainStat> _byId = new Dictionary<string, TrainStat>(); private static readonly Dictionary<string, TrainStat> _byGameField = new Dictionary<string, TrainStat>(); private static ConfigFile _save; internal static void Initialize() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown _save = new ConfigFile(Path.Combine(Application.persistentDataPath, "REPOModData/Train/save.cfg"), false); _save.SaveOnConfigSet = false; TrainStat[] stats = Stats; foreach (TrainStat trainStat in stats) { trainStat.Progress = _save.Bind<int>("Progress", trainStat.Id, 0, "Lifetime use-points accumulated for " + trainStat.Display + "."); _byId[trainStat.Id] = trainStat; _byGameField[trainStat.GameField] = trainStat; } } public static void Flush() { try { ConfigFile save = _save; if (save != null) { save.Save(); } } catch { } } public static TrainStat? ById(string id) { if (!_byId.TryGetValue(id, out TrainStat value)) { return null; } return value; } public static void AddProgress(TrainStat stat, int points) { if (points > 0) { ConfigEntry<int> progress = stat.Progress; progress.Value += points; } } public static void ResetAll() { TrainStat[] stats = Stats; foreach (TrainStat trainStat in stats) { trainStat.Progress.Value = 0; } Flush(); Train.Logger.LogInfo((object)"Train progress reset — all stats wiped."); } public static int Factor(int level) { if (level <= 0) { return 0; } if (level <= 3) { return 9; } if (level <= 10) { return 25; } return 100; } public static int Threshold(int level) { if (level > 0) { return level * Factor(level); } return 0; } public static int LevelFromProgress(int progress) { if (progress <= 0) { return 0; } int i; for (i = 0; Threshold(i + 1) <= progress; i++) { } return i; } public static int ImproveLevel() { try { return SaveData.CurrentLevel(); } catch { return 0; } } public static int TrainedLevel(TrainStat stat) { return LevelFromProgress(stat.Progress.Value); } public static int EffectiveLevel(TrainStat stat) { return Math.Min(TrainedLevel(stat), ImproveLevel()); } public static int EffectiveLevelForGameField(string gameField) { if (gameField == null || !_byGameField.TryGetValue(gameField, out TrainStat value)) { return 0; } return EffectiveLevel(value); } public static bool IsCapped(TrainStat stat) { return TrainedLevel(stat) > ImproveLevel(); } public static int ProgressToNext(TrainStat stat) { int level = TrainedLevel(stat) + 1; return Math.Max(Threshold(level) - stat.Progress.Value, 0); } } [BepInPlugin("headclef.Train", "Train", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Train : BaseUnityPlugin { private const string PluginGuid = "headclef.Train"; private const string PluginName = "Train"; private const string PluginVersion = "1.0.2"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> HealthHpPerPoint; internal static ConfigEntry<float> SprintMetresPerPoint; internal static ConfigEntry<float> WalkMetresPerPoint; internal static ConfigEntry<float> StandingStaminaPerPoint; internal static ConfigEntry<float> CrouchStaminaPerPoint; internal static ConfigEntry<float> WingsSecondsPerPoint; internal static Train Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0059: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; BindConfiguration(); SaveData.Initialize(); TrainMenu.Initialize(); if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private void OnDestroy() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void BindConfiguration() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for stat training. When off, nothing is counted or applied."); HealthHpPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Units", "Health HP Per Point", 25f, new ConfigDescription("HP cycled (damage taken + healing received, any source) per Health use-point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>())); SprintMetresPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Units", "Sprint Metres Per Point", 15f, new ConfigDescription("Metres sprinted per Sprint Speed use-point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>())); WalkMetresPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Units", "Walk Metres Per Point", 15f, new ConfigDescription("Metres walked (not sprinting) per Stamina use-point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>())); StandingStaminaPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Units", "Standing Stamina Per Point", 50f, new ConfigDescription("Stamina regained while standing per Stamina use-point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>())); CrouchStaminaPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Units", "Crouch Stamina Per Point", 50f, new ConfigDescription("Stamina regained while crouching per Crouch Rest use-point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>())); WingsSecondsPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Units", "Wings Seconds Per Point", 2f, new ConfigDescription("Seconds gliding with Tumble Wings per use-point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 60f), Array.Empty<object>())); } } internal static class TrainApplier { private static PlayerController? _pc; private static PlayerAvatar? _avatar; private static readonly Dictionary<string, int> _spawnLevel = new Dictionary<string, int>(); private static readonly Dictionary<string, int> _appliedLevel = new Dictionary<string, int>(); internal static void BaselineSpawn() { PlayerController instance = PlayerController.instance; PlayerAvatar val = (((Object)(object)instance != (Object)null) ? instance.playerAvatarScript : null); if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null) { Invalidate(); return; } _pc = instance; _avatar = val; _appliedLevel.Clear(); SaveData.TrainStat[] stats = SaveData.Stats; foreach (SaveData.TrainStat trainStat in stats) { _spawnLevel[trainStat.Id] = SaveData.EffectiveLevel(trainStat); } } internal static void Invalidate() { _pc = null; _avatar = null; _spawnLevel.Clear(); _appliedLevel.Clear(); } internal static void Apply() { if (!Train.Enabled.Value || !SemiFunc.RunIsLevel()) { return; } PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null) { return; } PlayerAvatar playerAvatarScript = instance.playerAvatarScript; if ((Object)(object)playerAvatarScript == (Object)null || playerAvatarScript.deadSet) { return; } if ((Object)(object)_pc != (Object)(object)instance || (Object)(object)_avatar != (Object)(object)playerAvatarScript) { BaselineSpawn(); return; } SaveData.TrainStat[] stats = SaveData.Stats; foreach (SaveData.TrainStat trainStat in stats) { if (_spawnLevel.TryGetValue(trainStat.Id, out var value)) { int num = Math.Max(0, SaveData.EffectiveLevel(trainStat) - value); int value2; int num2 = (_appliedLevel.TryGetValue(trainStat.Id, out value2) ? value2 : 0); int num3 = num - num2; if (num3 > 0) { ApplyLevels(trainStat.Id, num3, instance, playerAvatarScript); _appliedLevel[trainStat.Id] = num; Train.Logger.LogInfo((object)$"{trainStat.Display} trained to Lv {SaveData.EffectiveLevel(trainStat)} — applied live (+{num3})."); } } } } private static void ApplyLevels(string statId, int levels, PlayerController pc, PlayerAvatar avatar) { if (statId == null) { return; } switch (statId.Length) { case 9: switch (statId[0]) { case 'E': if (statId == "ExtraJump") { pc.JumpExtra += levels; } break; case 'G': if (statId == "GrabRange" && (Object)(object)avatar.physGrabber != (Object)null) { PhysGrabber physGrabber2 = avatar.physGrabber; physGrabber2.grabRange += (float)levels; } break; } break; case 11: switch (statId[6]) { case 'S': if (statId == "SprintSpeed") { pc.SprintSpeed += (float)levels; pc.SprintSpeedUpgrades += (float)levels; pc.playerOriginalSprintSpeed += (float)levels; } break; case 'C': if (statId == "TumbleClimb") { avatar.upgradeTumbleClimb += (float)levels; } break; case 'W': if (statId == "TumbleWings") { avatar.upgradeTumbleWings += (float)levels; } break; } break; case 12: switch (statId[0]) { case 'T': if (statId == "TumbleLaunch" && (Object)(object)avatar.tumble != (Object)null) { PlayerTumble tumble = avatar.tumble; tumble.tumbleLaunch += levels; } break; case 'G': if (statId == "GrabStrength" && (Object)(object)avatar.physGrabber != (Object)null) { PhysGrabber physGrabber3 = avatar.physGrabber; physGrabber3.grabStrength += 0.2f * (float)levels; } break; } break; case 6: if (statId == "Health" && (Object)(object)avatar.playerHealth != (Object)null) { PlayerHealth playerHealth = avatar.playerHealth; playerHealth.maxHealth += 20 * levels; avatar.playerHealth.Heal(20 * levels, false); TrainTracker.Invalidate(); } break; case 7: if (statId == "Stamina") { pc.EnergyStart += (float)(10 * levels); pc.EnergyCurrent = pc.EnergyStart; TrainTracker.Invalidate(); } break; case 10: if (statId == "CrouchRest") { avatar.upgradeCrouchRest += (float)levels; } break; case 5: if (statId == "Throw" && (Object)(object)avatar.physGrabber != (Object)null) { PhysGrabber physGrabber = avatar.physGrabber; physGrabber.throwStrength += 0.3f * (float)levels; } break; case 8: break; } } } public static class TrainMenu { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static BuilderDelegate <>9__1_0; public static BuilderDelegate <>9__1_1; public static BuilderDelegate <>9__1_2; public static Action <>9__4_2; public static Action <>9__4_0; public static Action <>9__4_1; internal void <Initialize>b__1_0(Transform parent) { AddTrainButton(parent); } internal void <Initialize>b__1_1(Transform parent) { AddTrainButton(parent); } internal void <Initialize>b__1_2(Transform parent) { AddTrainButton(parent); } internal void <OpenTrainMenu>b__4_0() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) MenuAPI.OpenPopup("Reset Train", Color.red, "Wipe ALL trained progress? Your earned stat levels will be lost. This cannot be undone.", (Action)delegate { SaveData.ResetAll(); TrainApplier.Apply(); _page.ClosePage(true); }, (Action)null); } internal void <OpenTrainMenu>b__4_2() { SaveData.ResetAll(); TrainApplier.Apply(); _page.ClosePage(true); } internal void <OpenTrainMenu>b__4_1() { _page.ClosePage(true); } } private static REPOPopupPage _page; internal static void Initialize() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown object obj = <>c.<>9__1_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { AddTrainButton(parent); }; <>c.<>9__1_0 = val; obj = (object)val; } MenuAPI.AddElementToMainMenu((BuilderDelegate)obj); object obj2 = <>c.<>9__1_1; if (obj2 == null) { BuilderDelegate val2 = delegate(Transform parent) { AddTrainButton(parent); }; <>c.<>9__1_1 = val2; obj2 = (object)val2; } MenuAPI.AddElementToEscapeMenu((BuilderDelegate)obj2); object obj3 = <>c.<>9__1_2; if (obj3 == null) { BuilderDelegate val3 = delegate(Transform parent) { AddTrainButton(parent); }; <>c.<>9__1_2 = val3; obj3 = (object)val3; } MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj3); } private static void AddTrainButton(Transform parent) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) REPOButton btn = MenuAPI.CreateREPOButton("Train", (Action)OpenTrainMenu, parent, new Vector2(0f, 300f)); ((MonoBehaviour)Train.Instance).StartCoroutine(FixRepoButton(btn, parent)); } private static IEnumerator FixRepoButton(REPOButton btn, Transform parent) { yield return null; Canvas.ForceUpdateCanvases(); TextMeshProUGUI componentInChildren = ((Component)btn).GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren != (Object)null) { RectTransform rectTransform = ((REPOElement)btn).rectTransform; RectTransform val = (RectTransform)((TMP_Text)componentInChildren).transform; ((Transform)val).SetParent((Transform)(object)rectTransform, false); val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.pivot = new Vector2(0.5f, 0.5f); val.offsetMin = new Vector2(14f, 6f); val.offsetMax = new Vector2(-14f, -6f); ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4614; ((TMP_Text)componentInChildren).enableWordWrapping = false; } RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val2 != null) { float num = 40f; Rect rect = ((REPOElement)btn).rectTransform.rect; float num2 = 20f + ((Rect)(ref rect)).height + 10f; rect = val2.rect; float width = ((Rect)(ref rect)).width; rect = ((REPOElement)btn).rectTransform.rect; float num3 = width - ((Rect)(ref rect)).width - num; ((Transform)((REPOElement)btn).rectTransform).localPosition = new Vector3(num3, num2, 0f); } } private static void OpenTrainMenu() { //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)Train.Instance).Config.Reload(); _page = MenuAPI.CreateREPOPopupPage("Train", false, true, 5f, (Vector2?)null); RectTransform rectTransform = _page.rectTransform; Transform obj = ((Transform)rectTransform).Find("Panel"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); Transform parent = ((Component)_page).transform.parent; RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); float num = 0f; float x = 0f; Rect rect; if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { rect = val2.rect; if (((Rect)(ref rect)).height > 0f) { rect = val.rect; if (((Rect)(ref rect)).height > 0f) { Rect rect2 = val.rect; float height = ((Rect)(ref rect2)).height; rect = val2.rect; float width = ((Rect)(ref rect)).width; rect = val2.rect; float num2 = height * (width / ((Rect)(ref rect)).height); num = Mathf.Max(0f, num2 - ((Rect)(ref rect2)).width); val.sizeDelta += new Vector2(num, 0f); ((Transform)val).localPosition = ((Transform)val).localPosition - new Vector3((0.5f - val.pivot.x) * num, 0f, 0f); _page.maskPadding = new Padding(0f, 0f, 0f, 60f); RectTransform maskRectTransform = _page.maskRectTransform; maskRectTransform.sizeDelta += new Vector2(num, 0f); ((Transform)maskRectTransform).localPosition = ((Transform)maskRectTransform).localPosition - new Vector3((0.5f - maskRectTransform.pivot.x) * num, 0f, 0f); RectTransform scrollBarRectTransform = _page.scrollBarRectTransform; ((Transform)scrollBarRectTransform).localPosition = ((Transform)scrollBarRectTransform).localPosition + new Vector3(num / 2f, 0f, 0f); x = (0f - maskRectTransform.pivot.x) * num; goto IL_0233; } } } _page.maskPadding = new Padding(0f, 0f, 0f, 60f); goto IL_0233; IL_0233: AddScrollLabel($"Improve Level (cap): {SaveData.ImproveLevel()}", 0.75f, x); SaveData.TrainStat[] stats = SaveData.Stats; foreach (SaveData.TrainStat trainStat in stats) { int num3 = SaveData.EffectiveLevel(trainStat); int num4 = SaveData.TrainedLevel(trainStat); int num5 = SaveData.ProgressToNext(trainStat); string text = (SaveData.IsCapped(trainStat) ? $"{trainStat.Display}: Lv {num3} (earned {num4}, capped) - {num5} to next" : $"{trainStat.Display}: Lv {num3} - {num5} to next"); AddScrollLabel(text, 0.75f, x); } Rect val3 = (Rect)(((Object)(object)val != (Object)null) ? val.rect : new Rect(0f, 0f, 340f, 260f)); Vector2 val4 = (((Object)(object)val != (Object)null) ? (Vector2.op_Implicit(((Transform)val).localPosition) + ((Rect)(ref val3)).min) : ((Rect)(ref val3)).min); float num6 = val4.y + 20f; float num7 = val4.x + ((Rect)(ref val3)).width / 2f; REPOButton val5 = MenuAPI.CreateREPOButton("Reset Train", (Action)delegate { //IL_0005: Unknown result type (might be due to invalid IL or missing references) MenuAPI.OpenPopup("Reset Train", Color.red, "Wipe ALL trained progress? Your earned stat levels will be lost. This cannot be undone.", (Action)delegate { SaveData.ResetAll(); TrainApplier.Apply(); _page.ClosePage(true); }, (Action)null); }, (Transform)(object)rectTransform, new Vector2(num7 - 190f, num6)); if ((Object)(object)val5.labelTMP != (Object)null) { TextMeshProUGUI labelTMP = val5.labelTMP; ((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * 0.75f; } ((REPOElement)val5).rectTransform.sizeDelta = new Vector2(160f, ((REPOElement)val5).rectTransform.sizeDelta.y); REPOButton val6 = MenuAPI.CreateREPOButton("Close", (Action)delegate { _page.ClosePage(true); }, (Transform)(object)rectTransform, new Vector2(num7 + 30f, num6)); if ((Object)(object)val6.labelTMP != (Object)null) { TextMeshProUGUI labelTMP2 = val6.labelTMP; ((TMP_Text)labelTMP2).fontSize = ((TMP_Text)labelTMP2).fontSize * 0.75f; } ((REPOElement)val6).rectTransform.sizeDelta = new Vector2(160f, ((REPOElement)val6).rectTransform.sizeDelta.y); float num8 = 1.3f; if ((Object)(object)val2 != (Object)null) { rect = val2.rect; if (((Rect)(ref rect)).width > 0f && ((Rect)(ref val3)).width > 0f && ((Rect)(ref val3)).height > 0f) { rect = val2.rect; float num9 = ((Rect)(ref rect)).width / ((Rect)(ref val3)).width; rect = val2.rect; num8 = Mathf.Min(num9, ((Rect)(ref rect)).height / ((Rect)(ref val3)).height) * 0.92f; } } ((Transform)rectTransform).localScale = new Vector3(num8, num8, 1f); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { rect = val2.rect; Vector3 val7 = ((Transform)val2).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)); rect = val.rect; Vector3 val8 = ((Transform)val).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center)); ((Transform)rectTransform).position = ((Transform)rectTransform).position + (val7 - val8); } _page.OpenPage(false); } private static void AddScrollLabel(string text, float fontScale, float x) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) REPOLabel val = MenuAPI.CreateREPOLabel(text, ((Component)_page).transform, default(Vector2)); if ((Object)(object)val.labelTMP != (Object)null) { TextMeshProUGUI labelTMP = val.labelTMP; ((TMP_Text)labelTMP).fontSize = ((TMP_Text)labelTMP).fontSize * fontScale; } _page.AddElementToScrollView(((REPOElement)val).rectTransform, new Vector2(x, 0f), 0f, 0f); } } internal static class TrainTracker { private static bool _baselined; private static int _prevHealth; private static float _prevEnergy; private static Vector3 _prevPos; private static int _prevJumpExtraCurrent; private static float _healthBuf; private static float _sprintBuf; private static float _walkBuf; private static float _standStaminaBuf; private static float _crouchBuf; private static SaveData.TrainStat Health => SaveData.ById("Health"); private static SaveData.TrainStat Sprint => SaveData.ById("SprintSpeed"); private static SaveData.TrainStat Stamina => SaveData.ById("Stamina"); private static SaveData.TrainStat CrouchRest => SaveData.ById("CrouchRest"); private static SaveData.TrainStat ExtraJump => SaveData.ById("ExtraJump"); internal static void Baseline() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null) { _baselined = false; return; } PlayerAvatar playerAvatarScript = instance.playerAvatarScript; _prevHealth = (((Object)(object)playerAvatarScript != (Object)null && (Object)(object)playerAvatarScript.playerHealth != (Object)null) ? playerAvatarScript.playerHealth.health : 0); _prevEnergy = instance.EnergyCurrent; _prevPos = ((Component)instance).transform.position; _prevJumpExtraCurrent = instance.JumpExtraCurrent; _baselined = true; } internal static void Invalidate() { _baselined = false; } internal static void SampleFrame() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!Train.Enabled.Value) { return; } if (!SemiFunc.RunIsLevel()) { _baselined = false; return; } PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null) { return; } PlayerAvatar playerAvatarScript = instance.playerAvatarScript; if ((Object)(object)playerAvatarScript == (Object)null || playerAvatarScript.deadSet) { _baselined = false; return; } if (!_baselined) { Baseline(); return; } if ((Object)(object)playerAvatarScript.playerHealth != (Object)null) { int health = playerAvatarScript.playerHealth.health; int num = health - _prevHealth; if (num != 0 && Mathf.Abs(num) <= playerAvatarScript.playerHealth.maxHealth) { _healthBuf += Mathf.Abs(num); } _prevHealth = health; } Vector3 position = ((Component)instance).transform.position; Vector3 val = position - _prevPos; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; _prevPos = position; if (magnitude > 0.001f && magnitude < 10f) { if (instance.sprinting) { _sprintBuf += magnitude; } else if (instance.moving) { _walkBuf += magnitude; } } float energyCurrent = instance.EnergyCurrent; float num2 = energyCurrent - _prevEnergy; _prevEnergy = energyCurrent; if (num2 > 0f) { if (instance.Crouching) { _crouchBuf += num2; } else { _standStaminaBuf += num2; } } int jumpExtraCurrent = instance.JumpExtraCurrent; if (jumpExtraCurrent < _prevJumpExtraCurrent) { SaveData.AddProgress(ExtraJump, _prevJumpExtraCurrent - jumpExtraCurrent); } _prevJumpExtraCurrent = jumpExtraCurrent; FlushBuffer(ref _healthBuf, Health, Train.HealthHpPerPoint.Value); FlushBuffer(ref _sprintBuf, Sprint, Train.SprintMetresPerPoint.Value); FlushBuffer(ref _walkBuf, Stamina, Train.WalkMetresPerPoint.Value); FlushBuffer(ref _standStaminaBuf, Stamina, Train.StandingStaminaPerPoint.Value); FlushBuffer(ref _crouchBuf, CrouchRest, Train.CrouchStaminaPerPoint.Value); } private static void FlushBuffer(ref float buf, SaveData.TrainStat stat, float unit) { if (unit <= 0f) { buf = 0f; } else if (!(buf < unit)) { int num = (int)(buf / unit); buf -= (float)num * unit; SaveData.AddProgress(stat, num); } } internal static void AddEvent(string statId, int points) { if (Train.Enabled.Value && SemiFunc.RunIsLevel()) { SaveData.TrainStat trainStat = SaveData.ById(statId); if (trainStat != null) { SaveData.AddProgress(trainStat, points); } } } } } namespace Train.Patches { [HarmonyPatch] internal static class TrainImproveBridgePatch { [HarmonyPatch(typeof(SaveData), "GetAllocationForStat")] [HarmonyPostfix] private static void GetAllocationForStat_Postfix(string statName, ref int __result) { if (Train.Enabled.Value) { __result += SaveData.EffectiveLevelForGameField(statName); } } } [HarmonyPatch] internal static class TrainSamplerPatch { [HarmonyPatch(typeof(PlayerController), "Update")] [HarmonyPostfix] private static void PlayerController_Update_Postfix(PlayerController __instance) { if (!((Object)(object)__instance != (Object)(object)PlayerController.instance)) { TrainTracker.SampleFrame(); } } } [HarmonyPatch] internal static class TrainLifecyclePatch { private static Coroutine? _watchdog; private static Coroutine? _deferredApply; [HarmonyPatch(typeof(StatsManager), "PlayerAdd")] [HarmonyPostfix] private static void PlayerAdd_Postfix(string _steamID) { if (SemiFunc.RunIsLevel() && !((Object)(object)PlayerAvatar.instance == (Object)null) && !(_steamID != PlayerAvatar.instance.steamID)) { TrainTracker.Invalidate(); ScheduleApply(); StartWatchdog(); } } [HarmonyPatch(typeof(SemiFunc), "OnSceneSwitch")] [HarmonyPrefix] private static void OnSceneSwitch_Prefix() { SaveData.Flush(); TrainApplier.Invalidate(); TrainTracker.Invalidate(); StopWatchdog(); StopDeferredApply(); } [HarmonyPatch(typeof(RunManager), "ResetProgress")] [HarmonyPostfix] private static void ResetProgress_Postfix() { StopWatchdog(); StopDeferredApply(); TrainApplier.Invalidate(); SaveData.Flush(); TrainTracker.Invalidate(); } private static void ScheduleApply() { StopDeferredApply(); _deferredApply = ((MonoBehaviour)Train.Instance).StartCoroutine(DeferredApply()); } private static void StopDeferredApply() { if (_deferredApply != null) { ((MonoBehaviour)Train.Instance).StopCoroutine(_deferredApply); _deferredApply = null; } } private static IEnumerator DeferredApply() { yield return null; yield return null; yield return null; yield return null; _deferredApply = null; if (SemiFunc.RunIsLevel()) { TrainTracker.Baseline(); TrainApplier.BaselineSpawn(); } } private static void StartWatchdog() { StopWatchdog(); _watchdog = ((MonoBehaviour)Train.Instance).StartCoroutine(WatchdogLoop()); } private static void StopWatchdog() { if (_watchdog != null) { ((MonoBehaviour)Train.Instance).StopCoroutine(_watchdog); _watchdog = null; } } private static IEnumerator WatchdogLoop() { yield return (object)new WaitForSeconds(1f); while (SemiFunc.RunIsLevel()) { TrainApplier.Apply(); SaveData.Flush(); yield return (object)new WaitForSeconds(1f); } _watchdog = null; } } [HarmonyPatch] internal static class TrainEventPatch { [HarmonyPatch(typeof(PlayerTumble), "TumbleRequest")] [HarmonyPostfix] private static void TumbleRequest_Postfix(PlayerTumble __instance, bool _isTumbling, bool _playerInput) { if (_isTumbling && _playerInput) { PlayerTumble val = ((!((Object)(object)PlayerController.instance != (Object)null)) ? null : PlayerController.instance.playerAvatarScript?.tumble); if (!((Object)(object)__instance != (Object)(object)val)) { TrainTracker.AddEvent("TumbleLaunch", 1); } } } [HarmonyPatch(typeof(PhysGrabber), "PhysGrabStarted")] [HarmonyPostfix] private static void PhysGrabStarted_Postfix(PhysGrabber __instance) { if (!((Object)(object)__instance != (Object)(object)PhysGrabber.instance)) { TrainTracker.AddEvent("GrabRange", 1); TrainTracker.AddEvent("GrabStrength", 1); } } [HarmonyPatch(typeof(PhysGrabber), "GrabLinkClimb")] [HarmonyPostfix] private static void GrabLinkClimb_Postfix(PhysGrabber __instance) { if (!((Object)(object)__instance != (Object)(object)PhysGrabber.instance)) { TrainTracker.AddEvent("TumbleClimb", 1); } } } }