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 SLRUpgradePack v0.5.1
plugins/SLRUpgradePack.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using KeybindLib.Classes; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Photon.Pun; using Photon.Realtime; using REPOLib.Modules; using REPOLib.Objects.Sdk; using SLRUpgradePack.Properties; using SLRUpgradePack.UpgradeManagers; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.UIElements; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SolarAaron")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c1597210e846d56390baa80b3d73081f87399f8c")] [assembly: AssemblyProduct("SLRUpgradePack")] [assembly: AssemblyTitle("SLRUpgradePack")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.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 SLRUpgradePack { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("SolarAaron.SLRUpgradePack", "SLRUpgradePack", "0.5.1")] public class SLRUpgradePack : BaseUnityPlugin { private static readonly FieldRef<PlayerUpgrade, Action<PlayerAvatar, int>> PlayerUpgradeStartActionRef = AccessTools.FieldRefAccess<PlayerUpgrade, Action<PlayerAvatar, int>>("StartAction"); internal static readonly Dictionary<string, int> LimitedUse = new Dictionary<string, int>(); private readonly HashSet<(string Upgrade, string SteamId)> _initializedStartingLevels = new HashSet<(string, string)>(); private readonly Dictionary<(string Upgrade, string SteamId), int> _initializedStartActionLevels = new Dictionary<(string, string), int>(); private readonly HashSet<string> _playersWithStartActions = new HashSet<string>(); internal Dictionary<string, Action> Actions { get; private set; } = new Dictionary<string, Action>(); internal static SLRUpgradePack Instance { get; private set; } = null; internal static ManualLogSource Logger => Instance._logger; internal Harmony? Harmony { get; set; } private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; public static OverchargeUpgrade OverchargeUpgradeInstance { get; private set; } public static ArmorUpgrade ArmorUpgradeInstance { get; private set; } public static ObjectValueUpgrade ObjectValueUpgradeInstance { get; private set; } public static ObjectDurabilityUpgrade ObjectDurabilityUpgradeInstance { get; private set; } public static ValuableDensityUpgrade ValuableDensityUpgradeInstance { get; private set; } public static HeartOfGoldUpgrade HeartOfGoldUpgradeInstance { get; private set; } public static RegenerationUpgrade RegenerationUpgradeInstance { get; private set; } public static ExtraLifeUpgrade ExtraLifeUpgradeInstance { get; private set; } public static InventorySlotUpgrade InventorySlotUpgradeInstance { get; private set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; _logger.LogInfo((object)"Configuring upgrade pack..."); AssetBundle val = AssetBundle.LoadFromMemory(Resources.slr_assets); ((Object)val).name = "slr"; string[] allAssetNames = val.GetAllAssetNames(); foreach (string text in allAssetNames) { _logger.LogInfo((object)("Found asset: " + text)); } if (PhysGrabberPatch.Prepare()) { OverchargeUpgradeInstance = new OverchargeUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 0.75f); } ArmorUpgradeInstance = new ArmorUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 1f); ObjectValueUpgradeInstance = new ObjectValueUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 2.5f); ObjectDurabilityUpgradeInstance = new ObjectDurabilityUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 2.5f); ValuableDensityUpgradeInstance = new ValuableDensityUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 2.5f); HeartOfGoldUpgradeInstance = new HeartOfGoldUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 10f, 3.5f); RegenerationUpgradeInstance = new RegenerationUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 0.1f, 4.5f); ExtraLifeUpgradeInstance = new ExtraLifeUpgrade(enabled: true, 0.1f, exponential: false, 1.1f, ((BaseUnityPlugin)this).Config, val, 5, 10f); InventorySlotUpgradeInstance = new InventorySlotUpgrade(enabled: true, 1, ((BaseUnityPlugin)this).Config, val, 2f); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { if (!SemiFunc.IsMasterClientOrSingleplayer() || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated) { return; } foreach (Action item in new List<Action>(Actions.Values)) { item(); } } internal void InitializeStartingLevelsForPlayer(string steamId) { if (SemiFunc.IsMasterClientOrSingleplayer() && !string.IsNullOrWhiteSpace(steamId)) { if (PhysGrabberPatch.Prepare()) { InitializeStartingLevel("Overcharge", OverchargeUpgradeInstance, steamId); } InitializeStartingLevel("Armor", ArmorUpgradeInstance, steamId); InitializeStartingLevel("ObjectValue", ObjectValueUpgradeInstance, steamId); InitializeStartingLevel("ObjectDurability", ObjectDurabilityUpgradeInstance, steamId); InitializeStartingLevel("ValuableDensity", ValuableDensityUpgradeInstance, steamId); InitializeStartingLevel("HeartOfGold", HeartOfGoldUpgradeInstance, steamId); InitializeStartingLevel("Regeneration", RegenerationUpgradeInstance, steamId); InitializeStartingLevel("ExtraLife", ExtraLifeUpgradeInstance, steamId); InitializeStartingLevel("InventorySlot", InventorySlotUpgradeInstance, steamId); } } internal void InitializeStartingLevelsForActivePlayers() { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>(); foreach (PlayerAvatar val in array) { if (Object.op_Implicit((Object)(object)val)) { InitializeStartingLevelsForPlayer(SemiFunc.PlayerGetSteamID(val)); } } } private void InitializeStartingLevel<T>(string upgradeName, UpgradeBase<T> upgrade, string steamId) { if (upgrade == null || !upgrade.UpgradeEnabled.Value || upgrade.UpgradeRegister == null) { return; } int value = upgrade.StartingAmount.Value; if (value <= 0) { return; } (string, string) item = (upgradeName, steamId); if (!_initializedStartingLevels.Add(item)) { return; } try { int level = upgrade.UpgradeRegister.GetLevel(steamId); if (level < value) { Logger.LogInfo((object)$"Applying configured starting level for {upgradeName} to player {steamId}: {level} -> {value}"); upgrade.UpgradeRegister.SetLevel(steamId, value); } } catch (Exception arg) { _initializedStartingLevels.Remove(item); Logger.LogError((object)$"Failed to initialize {upgradeName} for player {steamId}: {arg}"); } } internal void RecordPlayerStartActions(string steamId) { if (string.IsNullOrWhiteSpace(steamId)) { return; } _playersWithStartActions.Add(steamId); foreach (PlayerUpgrade playerUpgrade in Upgrades.PlayerUpgrades) { _initializedStartActionLevels[(playerUpgrade.UpgradeId, steamId)] = playerUpgrade.GetLevel(steamId); } } internal void RepairRemotePlayerStartAction(PlayerUpgrade upgrade, string steamId, int level) { if (SemiFunc.IsMasterClientOrSingleplayer() || string.IsNullOrWhiteSpace(steamId) || !_playersWithStartActions.Contains(steamId)) { return; } int configuredStartingLevel = GetConfiguredStartingLevel(upgrade); Action<PlayerAvatar, int> action = PlayerUpgradeStartActionRef.Invoke(upgrade); if (configuredStartingLevel <= 0 || level < configuredStartingLevel || action == null) { return; } (string, string) key = (upgrade.UpgradeId, steamId); if (_initializedStartActionLevels.TryGetValue(key, out var value) && value >= configuredStartingLevel) { return; } PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(steamId); if (!Object.op_Implicit((Object)(object)val)) { return; } try { action(val, upgrade.GetLevel(steamId)); _initializedStartActionLevels[key] = upgrade.GetLevel(steamId); } catch (Exception arg) { Logger.LogError((object)$"Failed to initialize synchronized {upgrade.UpgradeId} for player {steamId}: {arg}"); } } private int GetConfiguredStartingLevel(PlayerUpgrade upgrade) { if (OverchargeUpgradeInstance?.UpgradeRegister == upgrade) { return OverchargeUpgradeInstance.StartingAmount.Value; } if (ArmorUpgradeInstance?.UpgradeRegister == upgrade) { return ArmorUpgradeInstance.StartingAmount.Value; } if (ObjectValueUpgradeInstance?.UpgradeRegister == upgrade) { return ObjectValueUpgradeInstance.StartingAmount.Value; } if (ObjectDurabilityUpgradeInstance?.UpgradeRegister == upgrade) { return ObjectDurabilityUpgradeInstance.StartingAmount.Value; } if (ValuableDensityUpgradeInstance?.UpgradeRegister == upgrade) { return ValuableDensityUpgradeInstance.StartingAmount.Value; } if (HeartOfGoldUpgradeInstance?.UpgradeRegister == upgrade) { return HeartOfGoldUpgradeInstance.StartingAmount.Value; } if (RegenerationUpgradeInstance?.UpgradeRegister == upgrade) { return RegenerationUpgradeInstance.StartingAmount.Value; } if (ExtraLifeUpgradeInstance?.UpgradeRegister == upgrade) { return ExtraLifeUpgradeInstance.StartingAmount.Value; } if (InventorySlotUpgradeInstance?.UpgradeRegister == upgrade) { return InventorySlotUpgradeInstance.StartingAmount.Value; } return 0; } internal void ResetStartingLevelInitialization() { _initializedStartingLevels.Clear(); _initializedStartActionLevels.Clear(); _playersWithStartActions.Clear(); } } [HarmonyPatch(typeof(MenuPageSaves), "OnNewGame")] internal static class NewGameStartingUpgradeLevelsPatch { private static void Prefix() { SLRUpgradePack.Instance.ResetStartingLevelInitialization(); } } [HarmonyPatch(typeof(RunManager), "ResetProgress")] internal static class ResetRunStartingUpgradeLevelsPatch { private static void Postfix() { if ((Object)(object)SLRUpgradePack.Instance != (Object)null) { SLRUpgradePack.Instance.ResetStartingLevelInitialization(); } } } [HarmonyPatch(typeof(Upgrades), "InvokeStartActions")] internal static class InitializeStartingUpgradeLevelsPatch { private static void Prefix(string steamId) { if ((Object)(object)SLRUpgradePack.Instance != (Object)null) { SLRUpgradePack.Instance.InitializeStartingLevelsForPlayer(steamId); } } private static void Postfix(string steamId) { if ((Object)(object)SLRUpgradePack.Instance != (Object)null) { SLRUpgradePack.Instance.RecordPlayerStartActions(steamId); } } } [HarmonyPatch(typeof(PlayerUpgrade), "ApplyUpgrade")] internal static class RepairRemoteStartingUpgradeActionsPatch { private static void Postfix(PlayerUpgrade __instance, string steamId, int level) { if ((Object)(object)SLRUpgradePack.Instance != (Object)null) { SLRUpgradePack.Instance.RepairRemotePlayerStartAction(__instance, steamId, level); } } } [HarmonyPatch(typeof(LevelGenerator), "Start")] internal static class LevelGeneratorStartingUpgradeLevelsPatch { [HarmonyPriority(800)] private static void Prefix() { if ((Object)(object)SLRUpgradePack.Instance != (Object)null) { SLRUpgradePack.Instance.InitializeStartingLevelsForActivePlayers(); } } } } namespace SLRUpgradePack.UpgradeManagers { public class ArmorUpgrade : UpgradeBase<float> { public ArmorUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier) : base("Armor", "assets/repo/mods/resources/items/items/item upgrade armor lib.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, canBeExponential: true, (int?)null) { } public override float Calculate(float value, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatReduce(this, "Armor", value, player, level); } } [HarmonyPatch(typeof(PlayerHealth), "Hurt")] public class PlayerHealthArmorPatch { private static void Prefix(PlayerHealth __instance, ref int damage, PlayerAvatar ___playerAvatar) { ArmorUpgrade armorUpgradeInstance = SLRUpgradePack.ArmorUpgradeInstance; if (armorUpgradeInstance.UpgradeEnabled.Value) { SLRUpgradePack.Logger.LogDebug((object)$"Original damage amount: {damage}"); damage = (int)Math.Ceiling(armorUpgradeInstance.Calculate(damage, ___playerAvatar, armorUpgradeInstance.UpgradeRegister.GetLevel(___playerAvatar))); SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with level {0}: {1}", Upgrades.GetUpgrade("Armor").GetLevel(___playerAvatar), damage)); } } } public class ExtraLifeUpgrade : UpgradeBase<float> { private readonly Dictionary<string, Coroutine?> _reviveCoroutines = new Dictionary<string, Coroutine>(); private static readonly FieldRef<PlayerHealth, int>? MaxHealthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("maxHealth"); private readonly FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health"); private static readonly FieldRef<PlayerAvatar, bool> _deadSetRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("deadSet"); private readonly FieldRef<PlayerDeathHead, bool> _inExtractionPointRef = AccessTools.FieldRefAccess<PlayerDeathHead, bool>("inExtractionPoint"); private readonly FieldRef<PlayerDeathHead, PhysGrabObject> _physGrabObjectRef = AccessTools.FieldRefAccess<PlayerDeathHead, PhysGrabObject>("physGrabObject"); private static readonly FieldRef<PlayerAvatar, PlayerDeathHead> _playerDeathHeadRef = AccessTools.FieldRefAccess<PlayerAvatar, PlayerDeathHead>("playerDeathHead"); private static readonly FieldRef<RoundDirector, bool> _extractionPointsFetchedRef = AccessTools.FieldRefAccess<RoundDirector, bool>("extractionPointsFetched"); private static readonly FieldRef<PlayerAvatar, PlayerTumble> _playerTumbleRef = AccessTools.FieldRefAccess<PlayerAvatar, PlayerTumble>("tumble"); private static readonly FieldRef<PlayerTumble, bool> _isTumblingRef = AccessTools.FieldRefAccess<PlayerTumble, bool>("isTumbling"); private static readonly Vector3 ExtraLifeRespawnPosition = new Vector3(0f, 0.5f, 0f); public ConfigEntry<int> RevivePercent { get; protected set; } public ExtraLifeUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, int revivePercent, float priceMultiplier) : base("Extra Life", "assets/repo/mods/resources/items/items/item upgrade extra life lib.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: false, canBeExponential: true, (int?)null) { RevivePercent = config.Bind<int>("Extra Life Upgrade", "revivePercent", revivePercent, "Percentage of health to recover when revived"); } public override float Calculate(float value, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ExtraLife", value, player, level); } internal override void InitUpgrade(PlayerAvatar player, int level) { base.InitUpgrade(player, level); if (SemiFunc.IsMasterClientOrSingleplayer()) { SLRUpgradePack.Instance.Actions["Extra Life"] = ExtraLifeUpdateAction; } } private void ExtraLifeUpdateAction() { if (!base.UpgradeEnabled.Value || base.UpgradeRegister == null || !Object.op_Implicit((Object)(object)RoundDirector.instance) || !_extractionPointsFetchedRef.Invoke(RoundDirector.instance)) { return; } foreach (var activePlayerLevel in GetActivePlayerLevels()) { var (val, _) = activePlayerLevel; if (activePlayerLevel.Level <= 0 || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.playerHealth)) { continue; } string key = SemiFunc.PlayerGetSteamID(val); PlayerDeathHead val2 = _playerDeathHeadRef.Invoke(val); if (Object.op_Implicit((Object)(object)val2)) { Coroutine value; bool flag = _reviveCoroutines.TryGetValue(key, out value); if (_deadSetRef.Invoke(val) && _healthRef.Invoke(val.playerHealth) == 0 && !IsExtractionReviveBlocked(val2) && (!flag || value == null)) { _reviveCoroutines[key] = ((MonoBehaviour)SLRUpgradePack.Instance).StartCoroutine(BeginReviving(val)); } } } } private IEnumerator BeginReviving(PlayerAvatar player) { string playerID = SemiFunc.PlayerGetSteamID(player); try { yield return (object)new WaitForEndOfFrame(); if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)player.playerHealth) || !base.UpgradeEnabled.Value || base.UpgradeRegister.GetLevel(player) == 0 || !_deadSetRef.Invoke(player) || _healthRef.Invoke(player.playerHealth) != 0) { yield break; } PlayerDeathHead val = _playerDeathHeadRef.Invoke(player); if (!Object.op_Implicit((Object)(object)val)) { yield break; } SLRUpgradePack.Logger.LogInfo((object)("Preparing to revive " + SemiFunc.PlayerGetName(player))); if (IsExtractionReviveBlocked(val)) { SLRUpgradePack.Logger.LogInfo((object)"Delaying extra life because the extraction point can revive this dead head"); yield break; } ReviveLogic(player); while (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.playerHealth) && _deadSetRef.Invoke(player) && _healthRef.Invoke(player.playerHealth) == 0) { yield return null; } } finally { _reviveCoroutines.Remove(playerID); } } private bool IsExtractionReviveBlocked(PlayerDeathHead playerHead) { if (!Object.op_Implicit((Object)(object)playerHead)) { return false; } return _inExtractionPointRef.Invoke(playerHead); } private void ReviveLogic(PlayerAvatar player) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) ExtraLifeUpgrade extraLifeUpgradeInstance = SLRUpgradePack.ExtraLifeUpgradeInstance; PlayerDeathHead val = _playerDeathHeadRef.Invoke(player); PhysGrabObject val2 = (Object.op_Implicit((Object)(object)val) ? _physGrabObjectRef.Invoke(val) : null); if (Object.op_Implicit((Object)(object)val2)) { val2.centerPoint = ExtraLifeRespawnPosition + Vector3.up * 0.25f; } PlayerTumble val3 = _playerTumbleRef.Invoke(player); if (Object.op_Implicit((Object)(object)val3) && _isTumblingRef.Invoke(val3)) { val3.TumbleSet(false, false); } try { player.Revive(false); } catch { } player.Spawn(ExtraLifeRespawnPosition, Quaternion.identity); player.playerHealth.HealOther(Mathf.FloorToInt((float)MaxHealthRef.Invoke(player.playerHealth) * ((float)extraLifeUpgradeInstance.RevivePercent.Value / 100f)), true); extraLifeUpgradeInstance.UpgradeRegister.RemoveLevel(player, 1); } } public class HeartOfGoldUpgrade : UpgradeBase<float> { internal const byte RegistrationAckMessageType = 1; public static NetworkedEvent HeartOfGoldEvent = new NetworkedEvent("Heart Of Gold", (Action<EventData>)HeartOfGoldAction); public ConfigEntry<float> BaseHeartValue { get; protected set; } internal Dictionary<string, GoldenHeart> GoldenHearts { get; set; } = new Dictionary<string, GoldenHeart>(); private static void HeartOfGoldAction(EventData e) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) NetworkMessage networkMessage = NetworkMessage.FromByteArray((byte[])e.CustomData); HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (networkMessage.MessageType == 1) { if (!string.IsNullOrEmpty(networkMessage.PlayerId) && networkMessage.PhotonId.HasValue && heartOfGoldUpgradeInstance.GoldenHearts.TryGetValue(networkMessage.PlayerId, out GoldenHeart value) && Object.op_Implicit((Object)(object)value)) { value.RecordRegistrationAck(networkMessage.PhotonId.Value, e.Sender); } } else { if (networkMessage.MessageType != 0 || string.IsNullOrEmpty(networkMessage.PlayerId) || !networkMessage.PhotonId.HasValue) { return; } PlayerAvatar val = SemiFunc.PlayerAvatarGetFromSteamID(networkMessage.PlayerId); if (Object.op_Implicit((Object)(object)val)) { if (!heartOfGoldUpgradeInstance.GoldenHearts.TryGetValue(networkMessage.PlayerId, out GoldenHeart value2) || !Object.op_Implicit((Object)(object)value2)) { heartOfGoldUpgradeInstance.InitUpgrade(val, heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(val)); value2 = heartOfGoldUpgradeInstance.GoldenHearts[networkMessage.PlayerId]; } if (value2.SetViewId(networkMessage.PhotonId.Value)) { NetworkMessage msg = new NetworkMessage { PlayerId = networkMessage.PlayerId, PhotonId = networkMessage.PhotonId, MessageType = 1 }; NetworkedEvent heartOfGoldEvent = HeartOfGoldEvent; byte[] array = NetworkMessage.ToByteArray(msg); RaiseEventOptions val2 = new RaiseEventOptions(); val2.TargetActors = new int[1] { e.Sender }; heartOfGoldEvent.RaiseEvent((object)array, val2, SendOptions.SendReliable); } } } } public HeartOfGoldUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float baseValue, float priceMultiplier) : base("Heart Of Gold", "assets/repo/mods/resources/items/items/item upgrade heart of gold lib.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, canBeExponential: true, (int?)null) { BaseHeartValue = config.Bind<float>("Heart Of Gold Upgrade", "Base Value", baseValue, "Base value to scale by player health"); } public override float Calculate(float value, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "HeartOfGold", value, player, level); } internal override void InitUpgrade(PlayerAvatar player, int level) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) base.InitUpgrade(player, level); if (GoldenHearts.TryGetValue(SemiFunc.PlayerGetSteamID(player), out GoldenHeart value)) { Object.Destroy((Object)(object)value); } value = new GameObject("Golden Heart: " + SemiFunc.PlayerGetName(player)).AddComponent<GoldenHeart>(); value.player = player; GoldenHearts[SemiFunc.PlayerGetSteamID(player)] = value; } } public class GoldenHeart : MonoBehaviour { private const float RegistrationRetryInterval = 1f; private bool createRpcPending; private bool createRequested; private bool valueSyncPending = true; private bool hasQueuedMasterBaseValue; private float queuedMasterBaseValue; private bool hasQueuedFinalValue; private float queuedFinalBaseValue; private float queuedFinalValue; private float pendingBaseValue; private float nextRegistrationRetryTime; private readonly HashSet<int> registeredActorNumbers = new HashSet<int>(); private readonly HashSet<int> knownRemoteActorNumbers = new HashSet<int>(); private PhotonView photonView; private readonly FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health"); private static readonly FieldRef<RoundDirector, bool>? ExtractionPointsFetchedRef = AccessTools.FieldRefAccess<RoundDirector, bool>("extractionPointsFetched"); private readonly FieldRef<ValuableObject, PhysAttribute> _physAttributePresetRef = AccessTools.FieldRefAccess<ValuableObject, PhysAttribute>("physAttributePreset"); private readonly FieldRef<ValuableObject, bool> _discoveredRef = AccessTools.FieldRefAccess<ValuableObject, bool>("discovered"); private readonly FieldRef<ValuableObject, float> _dollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent"); internal PlayerAvatar player { get; set; } internal bool Pause { get; set; } internal int lastLevel { get; set; } = -1; internal int lastHealth { get; set; } = -1; internal ValuableObject? ValuableComponent { get; private set; } private void Awake() { if (!((Component)this).TryGetComponent<PhotonView>(ref photonView)) { photonView = ((Component)this).gameObject.AddComponent<PhotonView>(); } } public void DestroyOnlyMe() { if (Object.op_Implicit((Object)(object)ValuableComponent) || createRequested) { if (SemiFunc.IsMultiplayer()) { photonView.RPC("DestroyOnlyMeRPC", (RpcTarget)0, Array.Empty<object>()); } else { DestroyOnlyMeRPC(); } } } [PunRPC] private void DestroyOnlyMeRPC() { createRequested = false; createRpcPending = false; hasQueuedMasterBaseValue = false; hasQueuedFinalValue = false; ValuableObject valuableComponent = ValuableComponent; if (!((Object)(object)valuableComponent == (Object)null) && Object.op_Implicit((Object)(object)valuableComponent)) { SLRUpgradePack.Logger.LogInfo((object)("Components in GoldenHeart: " + string.Join(',', from v in ((Component)this).GetComponents<Object>() select ((object)v).ToString()))); PhysGrabObject component = ((Component)valuableComponent).GetComponent<PhysGrabObject>(); if (Object.op_Implicit((Object)(object)RoundDirector.instance) && Object.op_Implicit((Object)(object)component)) { RoundDirector.instance.PhysGrabObjectRemove(component); } Object.Destroy((Object)(object)valuableComponent); ValuableComponent = null; } } public void CreateOnlyMe() { if (!Object.op_Implicit((Object)(object)ValuableComponent) && !createRpcPending && !createRequested && !Pause) { createRpcPending = true; if (SemiFunc.IsMultiplayer()) { photonView.RPC("CreateOnlyMeRPC", (RpcTarget)0, Array.Empty<object>()); } else { CreateOnlyMeRPC(); } } } [PunRPC] private void CreateOnlyMeRPC() { createRpcPending = false; if (Object.op_Implicit((Object)(object)ValuableComponent)) { createRequested = false; return; } createRequested = true; TryCreateValuableComponent(); } private void TryCreateValuableComponent() { //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) if (createRequested && !Pause && Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.healthGrab) && Object.op_Implicit((Object)(object)player.playerHealth) && !Object.op_Implicit((Object)(object)ValuableComponent)) { HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; SLRUpgradePack.Logger.LogInfo((object)("Adding valuable component to player " + SemiFunc.PlayerGetName(player))); ValuableComponent = ((Component)player.healthGrab).gameObject.AddComponent<ValuableObject>(); ValuableObjectValuePatch.MarkExcludedFromExtractionGoal(ValuableComponent); SLRUpgradePack.Logger.LogInfo((object)("Valuable component " + SemiFunc.PlayerGetName(player) + " instantiated at " + JsonConvert.SerializeObject((object)((Component)ValuableComponent).transform))); ValuableComponent.valuePreset = ScriptableObject.CreateInstance<Value>(); ValuableComponent.valuePreset.valueMin = (ValuableComponent.valuePreset.valueMax = heartOfGoldUpgradeInstance.Calculate((float)_healthRef.Invoke(player.playerHealth) * heartOfGoldUpgradeInstance.BaseHeartValue.Value, player, heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player))); ValuableComponent.durabilityPreset = ScriptableObject.CreateInstance<Durability>(); ValuableComponent.durabilityPreset.durability = 999f; ValuableComponent.durabilityPreset.fragility = 0f; ValuableComponent.physAttributePreset = ScriptableObject.CreateInstance<PhysAttribute>(); ((Component)ValuableComponent).transform.localScale = Vector3.zero; ((Component)ValuableComponent).transform.SetParent(((Component)player).transform, false); ((Component)ValuableComponent).gameObject.AddComponent<Rigidbody>(); PhotonTransformView item = ((Component)ValuableComponent).gameObject.AddComponent<PhotonTransformView>(); PhysGrabObjectImpactDetector val = ((Component)ValuableComponent).gameObject.AddComponent<PhysGrabObjectImpactDetector>(); PhysGrabObject val2 = ((Component)ValuableComponent).gameObject.AddComponent<PhysGrabObject>(); ((Component)ValuableComponent).gameObject.AddComponent<PhotonView>().ObservedComponents = new List<Component>(3) { (Component)(object)val2, (Component)(object)val, (Component)(object)item }; ((Behaviour)val).enabled = false; ((Behaviour)val2).enabled = false; ((Component)val2).transform.localScale = Vector3.zero; ((Component)val2).transform.SetParent(((Component)ValuableComponent).transform, false); ((Component)val).transform.localScale = Vector3.zero; ((Component)val).transform.SetParent(((Component)ValuableComponent).transform, false); ((Component)ValuableComponent).gameObject.AddComponent<RoomVolumeCheck>().CurrentRooms = new List<RoomVolume>(); ValuableObject? valuableComponent = ValuableComponent; Gradient val3 = new Gradient(); val3.alphaKeys = (GradientAlphaKey[])(object)new GradientAlphaKey[1] { new GradientAlphaKey(1f, 0f) }; val3.colorKeys = (GradientColorKey[])(object)new GradientColorKey[1] { new GradientColorKey(Color.yellow, 0f) }; valuableComponent.particleColors = val3; _physAttributePresetRef.Invoke(ValuableComponent) = ScriptableObject.CreateInstance<PhysAttribute>(); int num = (lastLevel = -1); lastHealth = num; createRequested = false; if (hasQueuedMasterBaseValue) { float baseValue = queuedMasterBaseValue; hasQueuedMasterBaseValue = false; ApplyHeartValue(baseValue); } else if (hasQueuedFinalValue) { float baseValue2 = queuedFinalBaseValue; float finalValue = queuedFinalValue; hasQueuedFinalValue = false; ApplySyncedHeartValue(baseValue2, finalValue); } } } private void Update() { if (!Object.op_Implicit((Object)(object)player)) { Object.Destroy((Object)(object)this); return; } if (createRequested) { TryCreateValuableComponent(); } if ((Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)(object)player || !Object.op_Implicit((Object)(object)player.playerHealth) || !Object.op_Implicit((Object)(object)RoundDirector.instance) || !ExtractionPointsFetchedRef.Invoke(RoundDirector.instance)) { return; } HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!heartOfGoldUpgradeInstance.UpgradeEnabled.Value || Pause) { return; } int level = heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player); int num = _healthRef.Invoke(player.playerHealth); if (level == 0 || num == 0) { return; } if (lastLevel != level || lastHealth != num) { lastLevel = level; lastHealth = num; valueSyncPending = true; } float num2 = (pendingBaseValue = heartOfGoldUpgradeInstance.Calculate((float)num * heartOfGoldUpgradeInstance.BaseHeartValue.Value, player, level)); if (SemiFunc.IsMultiplayer() && !EnsureRemoteViewsRegistered()) { return; } if (!Object.op_Implicit((Object)(object)ValuableComponent)) { CreateOnlyMe(); } if (Object.op_Implicit((Object)(object)ValuableComponent) && valueSyncPending) { if (!SemiFunc.IsMultiplayer()) { ApplyHeartValue(num2); } else { photonView.RPC("UpdateOnlyMeRPC", (RpcTarget)2, new object[1] { num2 }); } valueSyncPending = false; } } private bool EnsureRemoteViewsRegistered() { //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (photonView.ViewID == 0) { PhotonNetwork.AllocateViewID(photonView); if (photonView.ViewID == 0) { return false; } registeredActorNumbers.Clear(); knownRemoteActorNumbers.Clear(); } HashSet<int> hashSet = PhotonNetwork.PlayerListOthers.Select((Player remotePlayer) => remotePlayer.ActorNumber).ToHashSet(); if (!knownRemoteActorNumbers.SetEquals(hashSet)) { knownRemoteActorNumbers.Clear(); knownRemoteActorNumbers.UnionWith(hashSet); registeredActorNumbers.IntersectWith(hashSet); valueSyncPending = true; } if (hashSet.All(registeredActorNumbers.Contains)) { return true; } if (Time.unscaledTime < nextRegistrationRetryTime) { return false; } NetworkMessage msg = new NetworkMessage { PlayerId = SemiFunc.PlayerGetSteamID(player), PhotonId = photonView.ViewID }; HeartOfGoldUpgrade.HeartOfGoldEvent.RaiseEvent((object)NetworkMessage.ToByteArray(msg), NetworkingEvents.RaiseOthers, SendOptions.SendReliable); nextRegistrationRetryTime = Time.unscaledTime + 1f; return false; } internal void RecordRegistrationAck(int photonId, int actorNumber) { if (photonView.ViewID == photonId && actorNumber > 0) { registeredActorNumbers.Add(actorNumber); } } [PunRPC] private void UpdateOnlyMeRPC(float baseValue) { if (SemiFunc.IsMasterClient()) { ApplyHeartValue(baseValue); } } private void ApplyHeartValue(float baseValue) { ValuableObject valuableComponent = ValuableComponent; if ((Object)(object)valuableComponent == (Object)null || !Object.op_Implicit((Object)(object)valuableComponent)) { queuedMasterBaseValue = baseValue; hasQueuedMasterBaseValue = true; createRequested = true; TryCreateValuableComponent(); return; } if (!_discoveredRef.Invoke(valuableComponent)) { valuableComponent.Discover((State)0); } valuableComponent.valuePreset.valueMin = baseValue; valuableComponent.valuePreset.valueMax = baseValue; _dollarValueCurrentRef.Invoke(valuableComponent) = baseValue; ValuableObjectValuePatch.Action(valuableComponent); float num = _dollarValueCurrentRef.Invoke(valuableComponent); valuableComponent.valuePreset.valueMin = baseValue; valuableComponent.valuePreset.valueMax = baseValue; if (!SemiFunc.IsMultiplayer()) { HeartOfGoldValueSetRPC(baseValue, num); return; } photonView.RPC("HeartOfGoldValueSetRPC", (RpcTarget)0, new object[2] { baseValue, num }); } [PunRPC] private void HeartOfGoldValueSetRPC(float baseValue, float finalValue) { ValuableObject valuableComponent = ValuableComponent; if ((Object)(object)valuableComponent == (Object)null || !Object.op_Implicit((Object)(object)valuableComponent)) { queuedFinalBaseValue = baseValue; queuedFinalValue = finalValue; hasQueuedFinalValue = true; createRequested = true; TryCreateValuableComponent(); } else { ApplySyncedHeartValue(baseValue, finalValue); } } private void ApplySyncedHeartValue(float baseValue, float finalValue) { ValuableObject valuableComponent = ValuableComponent; if (!((Object)(object)valuableComponent == (Object)null) && Object.op_Implicit((Object)(object)valuableComponent)) { if (!_discoveredRef.Invoke(valuableComponent)) { valuableComponent.Discover((State)0); } valuableComponent.valuePreset.valueMin = baseValue; valuableComponent.valuePreset.valueMax = baseValue; _dollarValueCurrentRef.Invoke(valuableComponent) = finalValue; } } public void PauseLogic(bool pause) { if (!SemiFunc.IsMultiplayer()) { PauseLogicRPC(pause); return; } photonView.RPC("PauseLogicRPC", (RpcTarget)0, new object[1] { pause }); } [PunRPC] private void PauseLogicRPC(bool pause) { Pause = pause; } internal bool SetViewId(int id) { if (id <= 0 || !Object.op_Implicit((Object)(object)photonView)) { return false; } if (photonView.ViewID != id) { photonView.ViewID = id; if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.photonView)) { photonView.TransferOwnership(player.photonView.Owner); } } return photonView.ViewID == id; } } [HarmonyPatch(typeof(ExtractionPoint))] public class ExtractionPointDestroyPatch { private static readonly FieldRef<RoundDirector, int>? TotalHaulRef = AccessTools.FieldRefAccess<RoundDirector, int>("totalHaul"); private static readonly FieldRef<ValuableObject, float>? DollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent"); private static readonly FieldRef<ProgressionManager, float>? HaulingPointsRef = AccessTools.FieldRefAccess<ProgressionManager, float>("roundPointsHauling"); private static readonly MethodInfo ExtractCosmeticMethod = AccessTools.Method(typeof(ExtractionPoint), "ExtractCosmeticWorldObject", new Type[1] { typeof(bool) }, (Type[])null); private static bool TryGetGoldenHeart(HeartOfGoldUpgrade upgrade, ValuableObject valuableObject, out GoldenHeart goldenHeart) { foreach (GoldenHeart value in upgrade.GoldenHearts.Values) { if (Object.op_Implicit((Object)(object)value) && (Object)(object)value.ValuableComponent == (Object)(object)valuableObject) { goldenHeart = value; return true; } } goldenHeart = null; return false; } private static void AddGoldenHeartHaulValue(ExtractionPoint extractionPoint, ValuableObject valuableObject) { float num = DollarValueCurrentRef.Invoke(valuableObject); TotalHaulRef.Invoke(RoundDirector.instance) += (int)num; float localPlayerHaulScore = valuableObject.GetLocalPlayerHaulScore(((Component)extractionPoint).gameObject); if (localPlayerHaulScore > 0f) { HaulingPointsRef.Invoke(ProgressionManager.instance) += num / 10f * localPlayerHaulScore; } } [HarmonyPatch("DestroyAllPhysObjectsInHaulList")] [HarmonyPrefix] private static bool DestroyAllPrefix(ExtractionPoint __instance) { HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!SemiFunc.IsMasterClientOrSingleplayer() || !heartOfGoldUpgradeInstance.UpgradeEnabled.Value) { return true; } List<GameObject> dollarHaulList = RoundDirector.instance.dollarHaulList; PhysGrabObject val = default(PhysGrabObject); ValuableObject val2 = default(ValuableObject); foreach (GameObject item in new List<GameObject>(dollarHaulList)) { if (Object.op_Implicit((Object)(object)item) && item.TryGetComponent<PhysGrabObject>(ref val) && Object.op_Implicit((Object)(object)val) && item.TryGetComponent<ValuableObject>(ref val2) && Object.op_Implicit((Object)(object)val2) && TryGetGoldenHeart(heartOfGoldUpgradeInstance, val2, out GoldenHeart goldenHeart)) { AddGoldenHeartHaulValue(__instance, val2); dollarHaulList.Remove(item); SLRUpgradePack.Logger.LogInfo((object)("Player " + SemiFunc.PlayerGetName(goldenHeart.player) + " in extraction zone counts as valuable")); goldenHeart.PauseLogic(pause: true); goldenHeart.DestroyOnlyMe(); } } return true; } [HarmonyPatch("DestroyTheFirstPhysObjectsInHaulList")] [HarmonyPrefix] private static bool DestroyFirstPrefix(ExtractionPoint __instance) { HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!SemiFunc.IsMasterClientOrSingleplayer() || !heartOfGoldUpgradeInstance.UpgradeEnabled.Value) { return true; } if ((bool)ExtractCosmeticMethod.Invoke(__instance, new object[1] { false })) { return false; } List<GameObject> dollarHaulList = RoundDirector.instance.dollarHaulList; PhysGrabObject val = default(PhysGrabObject); ValuableObject val2 = default(ValuableObject); if (dollarHaulList.Count == 0 || !Object.op_Implicit((Object)(object)dollarHaulList[0]) || !dollarHaulList[0].TryGetComponent<PhysGrabObject>(ref val) || !Object.op_Implicit((Object)(object)val) || !dollarHaulList[0].TryGetComponent<ValuableObject>(ref val2) || !Object.op_Implicit((Object)(object)val2) || !TryGetGoldenHeart(heartOfGoldUpgradeInstance, val2, out GoldenHeart goldenHeart)) { return true; } AddGoldenHeartHaulValue(__instance, val2); dollarHaulList.RemoveAt(0); SLRUpgradePack.Logger.LogInfo((object)("Player " + SemiFunc.PlayerGetName(goldenHeart.player) + " in extraction zone counts as valuable")); goldenHeart.PauseLogic(pause: true); goldenHeart.DestroyOnlyMe(); return false; } } [HarmonyPatch(typeof(RoundDirector), "Update")] public class RoundDirectorUpdatePatch { private static void Prefix(RoundDirector __instance) { ValuableObject val = default(ValuableObject); __instance.dollarHaulList.RemoveAll((GameObject go) => (Object)(object)go == (Object)null || !go.TryGetComponent<ValuableObject>(ref val) || !Object.op_Implicit((Object)(object)val)); } } public class InventorySlotUpgrade : UpgradeBase<int> { internal static readonly Dictionary<string, Dictionary<int, int>> serverMonitoredInventoryItems = new Dictionary<string, Dictionary<int, int>>(); private Coroutine? _deferredInventoryRefresh; public Keybind ItemSlot4 { get; set; } public Keybind ItemSlot5 { get; set; } public Keybind ItemSlot6 { get; set; } public Keybind ItemSlot7 { get; set; } public Keybind ItemSlot8 { get; set; } public Keybind ItemSlot9 { get; set; } internal string? BoundPlayer { get; set; } public Inventory? InventoryRef { get; set; } public InventoryUI? UIRef { get; set; } public InventorySlotUpgrade(bool enabled, int upgradeAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier) : base("Inventory Slot", "assets/repo/mods/resources/items/items/item upgrade inventory slot lib.asset", enabled, upgradeAmount, exponential: false, 0, config, assetBundle, priceMultiplier, configureAmount: false, canBeExponential: false, (int?)6) { AccessTools.Method(typeof(Keybinds), "Register", (Type[])null, (Type[])null); ((MemberInfo)typeof(SLRUpgradePack)).GetCustomAttribute<BepInPlugin>(); ItemSlot4 = Keybinds.Bind("Item slots", "Item Slot 4", "<keyboard>/z"); ItemSlot5 = Keybinds.Bind("Item Slots", "Item Slot 5", "<keyboard>/x"); ItemSlot6 = Keybinds.Bind("Item Slots", "Item Slot 6", "<keyboard>/c"); ItemSlot7 = Keybinds.Bind("Item Slots", "Item Slot 7", "<keyboard>/n"); ItemSlot8 = Keybinds.Bind("Item Slots", "Item Slot 8", "<keyboard>/m"); ItemSlot9 = Keybinds.Bind("Item Slots", "Item Slot 9", "<keyboard>/,"); } public override int Calculate(int value, PlayerAvatar player, int level) { return value + level; } internal override void InitUpgrade(PlayerAvatar player, int level) { base.InitUpgrade(player, level); if ((Object)(object)player == (Object)(object)SemiFunc.PlayerAvatarLocal()) { BoundPlayer = SemiFunc.PlayerGetSteamID(player); RefreshLocalInventory(); } } internal override void UseUpgrade(PlayerAvatar player, int level) { base.UseUpgrade(player, level); if ((Object)(object)player == (Object)(object)SemiFunc.PlayerAvatarLocal()) { BoundPlayer = SemiFunc.PlayerGetSteamID(player); RefreshLocalInventory(); ScheduleLocalInventoryRefresh(); } } private void RefreshLocalInventory() { if (Object.op_Implicit((Object)(object)InventoryRef)) { InventoryStartPatch.Postfix(InventoryRef); } if (Object.op_Implicit((Object)(object)UIRef)) { InventoryUIStartPatch.Postfix(UIRef); } } private void ScheduleLocalInventoryRefresh() { if (_deferredInventoryRefresh != null) { ((MonoBehaviour)SLRUpgradePack.Instance).StopCoroutine(_deferredInventoryRefresh); } _deferredInventoryRefresh = ((MonoBehaviour)SLRUpgradePack.Instance).StartCoroutine(RefreshLocalInventoryNextFrame()); } private IEnumerator RefreshLocalInventoryNextFrame() { yield return null; _deferredInventoryRefresh = null; RefreshLocalInventory(); } } [HarmonyPatch(typeof(InventoryUI), "Start")] public class InventoryUIStartPatch { private static readonly FieldRef<InventoryUI, List<GameObject>> allChildren = AccessTools.FieldRefAccess<InventoryUI, List<GameObject>>("allChildren"); private static readonly FieldRef<SemiUI, Vector3> initialPosition = AccessTools.FieldRefAccess<SemiUI, Vector3>("initialPosition"); private static readonly FieldRef<SemiUI, Vector2> hidePositionCurrent = AccessTools.FieldRefAccess<SemiUI, Vector2>("hidePositionCurrent"); private static readonly FieldRef<InventorySpot, ItemEquippable> currentItem = AccessTools.FieldRefAccess<InventorySpot, ItemEquippable>("<CurrentItem>k__BackingField"); private static readonly FieldRef<BatteryVisualLogic, ItemBattery> previousItemBattery = AccessTools.FieldRefAccess<BatteryVisualLogic, ItemBattery>("itemBatteryPrev"); private static readonly FieldRef<BatteryVisualLogic, List<GameObject>> batteryBars = AccessTools.FieldRefAccess<BatteryVisualLogic, List<GameObject>>("bars"); private static readonly FieldRef<InventorySpot, BatteryVisualLogic> inventorySpotBatteryVisual = AccessTools.FieldRefAccess<InventorySpot, BatteryVisualLogic>("batteryVisualLogic"); private static readonly FieldRef<BatteryVisualLogic, Vector3> batteryTargetPosition = AccessTools.FieldRefAccess<BatteryVisualLogic, Vector3>("targetPosition"); private static readonly FieldRef<BatteryVisualLogic, Vector3> batteryTargetPositionOriginal = AccessTools.FieldRefAccess<BatteryVisualLogic, Vector3>("targetPositionOriginal"); private static readonly FieldRef<BatteryVisualLogic, float> batteryTargetScale = AccessTools.FieldRefAccess<BatteryVisualLogic, float>("targetScale"); private static readonly FieldRef<BatteryVisualLogic, float> batteryTargetScaleOriginal = AccessTools.FieldRefAccess<BatteryVisualLogic, float>("targetScaleOriginal"); private static readonly FieldRef<BatteryVisualLogic, float> batteryTargetRotation = AccessTools.FieldRefAccess<BatteryVisualLogic, float>("targetRotation"); private static readonly FieldRef<BatteryVisualLogic, float> batteryTargetRotationOriginal = AccessTools.FieldRefAccess<BatteryVisualLogic, float>("targetRotationOriginal"); private static readonly FieldRef<BatteryVisualLogic, bool> batteryDoOutro = AccessTools.FieldRefAccess<BatteryVisualLogic, bool>("doOutro"); private static readonly FieldRef<BatteryVisualLogic, SpringFloat> batterySpringScale = AccessTools.FieldRefAccess<BatteryVisualLogic, SpringFloat>("springScale"); private static readonly FieldRef<BatteryVisualLogic, SpringFloat> batterySpringRotation = AccessTools.FieldRefAccess<BatteryVisualLogic, SpringFloat>("springRotation"); private static readonly FieldRef<BatteryVisualLogic, SpringVector3> batterySpringPosition = AccessTools.FieldRefAccess<BatteryVisualLogic, SpringVector3>("springPosition"); private static readonly FieldRef<SpringFloat, float> springFloatDamping = AccessTools.FieldRefAccess<SpringFloat, float>("damping"); private static readonly FieldRef<SpringFloat, float> springFloatSpeed = AccessTools.FieldRefAccess<SpringFloat, float>("speed"); private static readonly FieldRef<SpringFloat, float> springFloatLastPosition = AccessTools.FieldRefAccess<SpringFloat, float>("lastPosition"); private static readonly FieldRef<SpringVector3, float> springVectorDamping = AccessTools.FieldRefAccess<SpringVector3, float>("damping"); private static readonly FieldRef<SpringVector3, float> springVectorSpeed = AccessTools.FieldRefAccess<SpringVector3, float>("speed"); private static readonly FieldRef<SpringVector3, Vector3> springVectorLastPosition = AccessTools.FieldRefAccess<SpringVector3, Vector3>("lastPosition"); private static readonly FieldRef<InventoryBattery, Vector3> originalBatteryScale = AccessTools.FieldRefAccess<InventoryBattery, Vector3>("originalLocalScale"); private static readonly Dictionary<int, (int frame, int batteryId)> batteryVisualRefreshes = new Dictionary<int, (int, int)>(); private static readonly Dictionary<int, (Vector3 position, float scale, float rotation)> clonedBatteryVisualsPendingStart = new Dictionary<int, (Vector3, float, float)>(); private static int batteryVisualRefreshFrame = -1; internal static void Postfix(InventoryUI __instance) { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_06a5: Unknown result type (might be due to invalid IL or missing references) //IL_06ac: Expected O, but got Unknown //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) InventorySlotUpgrade inventorySlotUpgradeInstance = SLRUpgradePack.InventorySlotUpgradeInstance; inventorySlotUpgradeInstance.UIRef = __instance; if (!inventorySlotUpgradeInstance.UpgradeEnabled.Value || inventorySlotUpgradeInstance.BoundPlayer == null) { return; } int num = inventorySlotUpgradeInstance.Calculate(3, SemiFunc.PlayerAvatarLocal(), inventorySlotUpgradeInstance.UpgradeRegister.GetLevel(inventorySlotUpgradeInstance.BoundPlayer)); if (num <= 3) { return; } SLRUpgradePack.Logger.LogInfo((object)$"Redrawing for {num} slots"); float num2 = (float)(-(num * 40)) / 2f + 20f; Dictionary<int, InventorySpot> dictionary = (from spot in ((Component)__instance).GetComponentsInChildren<InventorySpot>(true) where Object.op_Implicit((Object)(object)spot) group spot by spot.inventorySpotIndex).ToDictionary((IGrouping<int, InventorySpot> group) => group.Key, (IGrouping<int, InventorySpot> group) => group.First()); if (!dictionary.TryGetValue(0, out var templateSpot) || !Object.op_Implicit((Object)(object)templateSpot)) { SLRUpgradePack.Logger.LogWarning((object)"Could not resize inventory UI: no base InventorySpot template was found."); return; } BatteryVisualLogic componentInChildren = ((Component)templateSpot).GetComponentInChildren<BatteryVisualLogic>(true); SemiUI component = ((Component)templateSpot).GetComponent<SemiUI>(); Vector2 val = (Object.op_Implicit((Object)(object)component) ? component.showPosition : Vector2.op_Implicit(((Component)templateSpot).transform.localPosition)); Vector2 val2 = (Object.op_Implicit((Object)(object)component) ? (component.hidePosition - val) : Vector2.zero); Vector2 templateHideCurrentOffset = (Object.op_Implicit((Object)(object)component) ? (hidePositionCurrent.Invoke(component) - val) : val2); Vector3 templateInitialOffset = (Object.op_Implicit((Object)(object)component) ? (initialPosition.Invoke(component) - Vector2.op_Implicit(val)) : Vector3.zero); InventoryBattery val3 = ((IEnumerable<InventoryBattery>)((Component)__instance).GetComponentsInChildren<InventoryBattery>(true)).FirstOrDefault((Func<InventoryBattery, bool>)((InventoryBattery battery) => Object.op_Implicit((Object)(object)battery) && battery.inventorySpot == templateSpot.inventorySpotIndex && !Object.op_Implicit((Object)(object)((Component)battery).GetComponentInParent<InventorySpot>()))); Vector3 localScale = (Object.op_Implicit((Object)(object)val3) ? GetBatteryDisplayScale(val3) : Vector3.zero); Vector3 val4 = (Object.op_Implicit((Object)(object)val3) ? ((Component)templateSpot).transform.InverseTransformPoint(((Component)val3).transform.position) : Vector3.zero); Quaternion val5 = (Object.op_Implicit((Object)(object)val3) ? (Quaternion.Inverse(((Component)templateSpot).transform.rotation) * ((Component)val3).transform.rotation) : Quaternion.identity); Vector2 position = default(Vector2); int num4; for (int num3 = 0; num3 < num; num3++) { ((Vector2)(ref position))..ctor(num2 + (float)num3 * 40f, -175.3f); if (dictionary.TryGetValue(num3, out var value) && Object.op_Implicit((Object)(object)value)) { SetSpotPosition(value, position, val, val2, templateHideCurrentOffset, templateInitialOffset, startHasRun: true); continue; } Transform val6 = Object.Instantiate<Transform>(((Component)templateSpot).transform, ((Component)templateSpot).transform.parent, false); ((Object)((Component)val6).gameObject).name = $"Inventory Spot {num3 + 1}"; BatteryVisualLogic componentInChildren2 = ((Component)val6).GetComponentInChildren<BatteryVisualLogic>(true); if (Object.op_Implicit((Object)(object)componentInChildren2)) { ((Component)componentInChildren2).gameObject.SetActive(true); } InventorySpot component2 = ((Component)val6).GetComponent<InventorySpot>(); if (!Object.op_Implicit((Object)(object)component2)) { Object.Destroy((Object)(object)((Component)val6).gameObject); SLRUpgradePack.Logger.LogWarning((object)$"Could not create inventory slot {num3 + 1}: cloned template has no InventorySpot."); continue; } component2.inventorySpotIndex = num3; currentItem.Invoke(component2) = null; if (Object.op_Implicit((Object)(object)componentInChildren2)) { inventorySpotBatteryVisual.Invoke(component2) = componentInChildren2; componentInChildren2.itemBattery = null; previousItemBattery.Invoke(componentInChildren2) = null; RebindBatteryBars(componentInChildren2); if (Object.op_Implicit((Object)(object)componentInChildren)) { ResetClonedBatteryVisual(componentInChildren2, componentInChildren); } } InventoryBattery[] componentsInChildren = ((Component)component2).GetComponentsInChildren<InventoryBattery>(true); for (num4 = 0; num4 < componentsInChildren.Length; num4++) { componentsInChildren[num4].inventorySpot = num3; } RestoreClonedBatteryScales(templateSpot, val6); num4 = num3 + 1; string text = num4.ToString(); if (Object.op_Implicit((Object)(object)component2.noItem)) { ((TMP_Text)component2.noItem).text = text; } Transform obj = val6.Find("Numbers"); TextMeshProUGUI val7 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null); if (Object.op_Implicit((Object)(object)val7)) { ((TMP_Text)val7).text = text; } SetSpotPosition(component2, position, val, val2, templateHideCurrentOffset, templateInitialOffset, startHasRun: false); dictionary[num3] = component2; } if (Object.op_Implicit((Object)(object)val3)) { HashSet<int> hashSet = new HashSet<int>(); InventoryBattery[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<InventoryBattery>(true); for (num4 = 0; num4 < componentsInChildren.Length; num4++) { InventoryBattery val8 = componentsInChildren[num4]; InventorySpot componentInParent = ((Component)val8).GetComponentInParent<InventorySpot>(); if (Object.op_Implicit((Object)(object)componentInParent)) { val8.inventorySpot = componentInParent.inventorySpotIndex; } hashSet.Add(val8.inventorySpot); } for (int num5 = 3; num5 < num; num5++) { if (!hashSet.Contains(num5) && dictionary.TryGetValue(num5, out var value2) && Object.op_Implicit((Object)(object)value2)) { Transform val9 = Object.Instantiate<Transform>(((Component)val3).transform, ((Component)val3).transform.parent, false); ((Object)((Component)val9).gameObject).name = $"Inventory Battery {num5 + 1}"; val9.position = ((Component)value2).transform.TransformPoint(val4); val9.rotation = ((Component)value2).transform.rotation * val5; InventoryBattery component3 = ((Component)val9).GetComponent<InventoryBattery>(); if (!Object.op_Implicit((Object)(object)component3)) { Object.Destroy((Object)(object)((Component)val9).gameObject); SLRUpgradePack.Logger.LogWarning((object)$"Could not create battery indicator for inventory slot {num5 + 1}: cloned template has no InventoryBattery."); } else { component3.inventorySpot = num5; val9.localScale = localScale; hashSet.Add(num5); } } } } foreach (KeyValuePair<int, InventorySpot> item in dictionary) { item.Deconstruct(out num4, out var value3); int num6 = num4; InventorySpot val10 = value3; if (Object.op_Implicit((Object)(object)val10)) { InventoryBattery[] componentsInChildren = ((Component)val10).GetComponentsInChildren<InventoryBattery>(true); for (num4 = 0; num4 < componentsInChildren.Length; num4++) { componentsInChildren[num4].inventorySpot = num6; } InventoryStartPatch.RegisterSpot(val10, num6); } } List<GameObject> list = allChildren.Invoke(__instance); list.Clear(); foreach (Transform item2 in ((Component)__instance).transform) { Transform val11 = item2; list.Add(((Component)val11).gameObject); } Canvas.ForceUpdateCanvases(); } private static void SetSpotPosition(InventorySpot spot, Vector2 position, Vector2 templateShowPosition, Vector2 templateHideOffset, Vector2 templateHideCurrentOffset, Vector3 templateInitialOffset, bool startHasRun) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0051: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) _ = position - templateShowPosition; Vector3 localPosition = Vector2.op_Implicit(position); localPosition.z = ((Component)spot).transform.localPosition.z; ((Component)spot).transform.localPosition = localPosition; SemiUI component = ((Component)spot).GetComponent<SemiUI>(); if (Object.op_Implicit((Object)(object)component)) { component.showPosition = position; component.hidePosition = (startHasRun ? (position + templateHideOffset) : templateHideOffset); hidePositionCurrent.Invoke(component) = position + templateHideCurrentOffset; initialPosition.Invoke(component) = Vector2.op_Implicit(position) + templateInitialOffset; } } private static Vector3 GetBatteryDisplayScale(InventoryBattery battery) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = originalBatteryScale.Invoke(battery); if (!(val == Vector3.zero)) { return val; } return ((Component)battery).transform.localScale; } private static void RebindBatteryBars(BatteryVisualLogic batteryVisual) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)batteryVisual.batteryBarContainer)) { SLRUpgradePack.Logger.LogWarning((object)"Could not rebind cloned battery bars: the bar container reference is missing."); batteryBars.Invoke(batteryVisual) = new List<GameObject>(); return; } List<GameObject> list = new List<GameObject>(batteryVisual.batteryBarContainer.childCount); foreach (Transform item in batteryVisual.batteryBarContainer) { Transform val = item; list.Add(((Component)val).gameObject); } batteryBars.Invoke(batteryVisual) = list; } internal static BatteryVisualLogic? BindBatteryVisual(InventorySpot spot, bool activateForVanillaStart) { if (!Object.op_Implicit((Object)(object)spot)) { return null; } BatteryVisualLogic val = inventorySpotBatteryVisual.Invoke(spot); if (Object.op_Implicit((Object)(object)val) && (Object)(object)((Component)val).transform != (Object)(object)((Component)spot).transform && !((Component)val).transform.IsChildOf(((Component)spot).transform)) { val = null; } if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)spot).GetComponentInChildren<BatteryVisualLogic>(true); } if (!Object.op_Implicit((Object)(object)val)) { return null; } inventorySpotBatteryVisual.Invoke(spot) = val; if (activateForVanillaStart && !((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } return val; } private static void ResetClonedBatteryVisual(BatteryVisualLogic visual, BatteryVisualLogic template) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) Vector3 val = batteryTargetPositionOriginal.Invoke(template); if (float.IsNaN(val.x) || float.IsInfinity(val.x) || float.IsNaN(val.y) || float.IsInfinity(val.y) || float.IsNaN(val.z) || float.IsInfinity(val.z)) { val = ((Component)visual).transform.localPosition; } float num = batteryTargetScaleOriginal.Invoke(template); if (!IsUsableScale(num)) { num = batteryTargetScale.Invoke(template); } if (!IsUsableScale(num)) { num = Mathf.Max(((Component)visual).transform.localScale.x, ((Component)visual).transform.localScale.y); } if (!IsUsableScale(num)) { num = 0.5f; } float num2 = batteryTargetRotationOriginal.Invoke(template); if (float.IsNaN(num2) || float.IsInfinity(num2)) { num2 = 0f; } ApplyClonedBatteryVisualState(visual, val, num, num2); clonedBatteryVisualsPendingStart[((Object)visual).GetInstanceID()] = (val, num, num2); } private static void ApplyClonedBatteryVisualState(BatteryVisualLogic visual, Vector3 targetPosition, float targetScale, float targetRotation) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) ((Component)visual).transform.localPosition = targetPosition; ((Component)visual).transform.localScale = Vector3.one * targetScale; ((Component)visual).transform.localRotation = Quaternion.Euler(0f, 0f, targetRotation); batteryTargetPosition.Invoke(visual) = targetPosition; batteryTargetPositionOriginal.Invoke(visual) = targetPosition; batteryTargetScale.Invoke(visual) = targetScale; batteryTargetScaleOriginal.Invoke(visual) = targetScale; batteryTargetRotation.Invoke(visual) = targetRotation; batteryTargetRotationOriginal.Invoke(visual) = targetRotation; batteryDoOutro.Invoke(visual) = false; ResetBatteryVisualSprings(visual, targetScale); } private static bool IsUsableScale(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value > 0.001f; } return false; } private static void ResetBatteryVisualSprings(BatteryVisualLogic visual, float targetScale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) SpringFloat val = new SpringFloat(); springFloatDamping.Invoke(val) = 0.4f; springFloatSpeed.Invoke(val) = 30f; springFloatLastPosition.Invoke(val) = targetScale; batterySpringScale.Invoke(visual) = val; SpringFloat val2 = new SpringFloat(); springFloatDamping.Invoke(val2) = 0.3f; springFloatSpeed.Invoke(val2) = 40f; springFloatLastPosition.Invoke(val2) = 0f; batterySpringRotation.Invoke(visual) = val2; SpringVector3 val3 = new SpringVector3(); springVectorDamping.Invoke(val3) = 0.35f; springVectorSpeed.Invoke(val3) = 30f; springVectorLastPosition.Invoke(val3) = ((Component)visual).transform.localPosition; batterySpringPosition.Invoke(visual) = val3; } internal static void ResetPendingClonedBatteryVisualStart(BatteryVisualLogic visual) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)visual)) { int instanceID = ((Object)visual).GetInstanceID(); if (clonedBatteryVisualsPendingStart.TryGetValue(instanceID, out (Vector3, float, float) value)) { clonedBatteryVisualsPendingStart.Remove(instanceID); ApplyClonedBatteryVisualState(visual, value.Item1, value.Item2, value.Item3); } } } internal static void ClearPendingClonedBatteryVisuals() { clonedBatteryVisualsPendingStart.Clear(); } internal static void RefreshBatteryVisual(InventorySpot spot, bool forceRefresh = true) { if (!Object.op_Implicit((Object)(object)spot)) { return; } ItemEquippable val = spot.CurrentItem; ItemBattery val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ItemBattery>() : null); int num = (Object.op_Implicit((Object)(object)val2) ? ((Object)val2).GetInstanceID() : 0); int frameCount = Time.frameCount; if (batteryVisualRefreshFrame != frameCount) { batteryVisualRefreshes.Clear(); batteryVisualRefreshFrame = frameCount; } int instanceID = ((Object)spot).GetInstanceID(); if (!forceRefresh && batteryVisualRefreshes.TryGetValue(instanceID, out (int, int) value) && value.Item2 == num) { return; } BatteryVisualLogic batteryVisual = BindBatteryVisual(spot, activateForVanillaStart: false); if (!Object.op_Implicit((Object)(object)batteryVisual) || !Object.op_Implicit((Object)(object)batteryVisual.batteryBarContainer)) { return; } List<GameObject> list = batteryBars.Invoke(batteryVisual); if (list == null || list.Count != batteryVisual.batteryBarContainer.childCount || list.Any((GameObject bar) => !Object.op_Implicit((Object)(object)bar) || (Object)(object)bar.transform.parent != (Object)(object)batteryVisual.batteryBarContainer)) { RebindBatteryBars(batteryVisual); } batteryVisual.itemBattery = val2; previousItemBattery.Invoke(batteryVisual) = val2; if (Object.op_Implicit((Object)(object)val2)) { if (!((Component)batteryVisual).gameObject.activeSelf) { ((Component)batteryVisual).gameObject.SetActive(true); } if (batteryTargetScale.Invoke(batteryVisual) == 0f) { batteryVisual.ResetOutro(); } } batteryVisual.BatteryBarsSet(); if (Object.op_Implicit((Object)(object)val2)) { batteryVisual.BatteryBarsUpdate(-1, true); } else { batteryVisual.BatteryOutro(); } batteryVisualRefreshes[instanceID] = (frameCount, num); } private static void RestoreClonedBatteryScales(InventorySpot templateSpot, Transform clonedSpot) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) InventoryBattery[] componentsInChildren = ((Component)templateSpot).GetComponentsInChildren<InventoryBattery>(true); InventoryBattery[] componentsInChildren2 = ((Component)clonedSpot).GetComponentsInChildren<InventoryBattery>(true); for (int i = 0; i < componentsInChildren.Length && i < componentsInChildren2.Length; i++) { if (Object.op_Implicit((Object)(object)componentsInChildren[i]) && Object.op_Implicit((Object)(object)componentsInChildren2[i])) { ((Component)componentsInChildren2[i]).transform.localScale = GetBatteryDisplayScale(componentsInChildren[i]); } } } } [HarmonyPatch(typeof(InventorySpot), "EquipItem")] public class InventorySpotEquipBatteryVisualPatch { private static void Postfix(InventorySpot __instance) { InventoryUIStartPatch.RefreshBatteryVisual(__instance, forceRefresh: false); } } [HarmonyPatch(typeof(InventorySpot), "UnequipItem")] public class InventorySpotUnequipBatteryVisualPatch { private static void Postfix(InventorySpot __instance) { InventoryUIStartPatch.RefreshBatteryVisual(__instance, forceRefresh: false); } } [HarmonyPatch(typeof(InventorySpot), "UpdateUI")] public class InventorySpotUpdateUIBatteryVisualPatch { private static void Postfix(InventorySpot __instance) { InventoryUIStartPatch.RefreshBatteryVisual(__instance); } } [HarmonyPatch(typeof(InventorySpot), "Start")] public class InventorySpotStartPatch { private static void Prefix(InventorySpot __instance) { InventoryUIStartPatch.BindBatteryVisual(__instance, __instance.inventorySpotIndex >= 3); } private static void Postfix(InventorySpot __instance) { InventoryUIStartPatch.BindBatteryVisual(__instance, activateForVanillaStart: false); } } [HarmonyPatch(typeof(BatteryVisualLogic), "Start")] public class BatteryVisualLogicStartPatch { private static void Postfix(BatteryVisualLogic __instance) { InventoryUIStartPatch.ResetPendingClonedBatteryVisualStart(__instance); } } [HarmonyPatch(typeof(InventorySpot), "StateOccupied")] public class InventorySpotStateOccupiedBatteryVisualPatch { private static void Prefix(InventorySpot __instance) { InventoryUIStartPatch.BindBatteryVisual(__instance, activateForVanillaStart: false); } } [HarmonyPatch(typeof(StatsManager), "PlayerInventoryUpdate")] public class StatsManagerUpdatePatch { private static void Postfix(StatsManager __instance, string _steamID, string itemName, int spot, bool sync) { if (!SemiFunc.IsMasterClientOrSingleplayer() || spot < 3) { return; } Dictionary<int, int> value; bool flag = InventorySlotUpgrade.serverMonitoredInventoryItems.TryGetValue(_steamID, out value); if (string.IsNullOrEmpty(itemName)) { if (flag) { value.Remove(spot); if (value.Count == 0) { InventorySlotUpgrade.serverMonitoredInventoryItems.Remove(_steamID); } } } else { if (!flag) { InventorySlotUpgrade.serverMonitoredInventoryItems.Add(_steamID, value = new Dictionary<int, int>()); } value[spot] = itemName.GetHashCode(); } } } [HarmonyPatch(typeof(MainMenuOpen), "Start")] public class MainMenuOpenStartPatch { private static void Postfix(MainMenuOpen __instance) { InventorySlotUpgrade.serverMonitoredInventoryItems.Clear(); InventoryUIStartPatch.ClearPendingClonedBatteryVisuals(); } } [HarmonyPatch(typeof(Inventory), "Start")] public class InventoryStartPatch { private static readonly FieldRef<Inventory, List<InventorySpot>> inventorySpots = AccessTools.FieldRefAccess<Inventory, List<InventorySpot>>("inventorySpots"); internal static void Postfix(Inventory __instance) { InventorySlotUpgrade inventorySlotUpgradeInstance = SLRUpgradePack.InventorySlotUpgradeInstance; inventorySlotUpgradeInstance.InventoryRef = __instance; if (inventorySlotUpgradeInstance.UpgradeEnabled.Value && inventorySlotUpgradeInstance.BoundPlayer != null) { int num = inventorySlotUpgradeInstance.Calculate(3, SemiFunc.PlayerAvatarLocal(), inventorySlotUpgradeInstance.UpgradeRegister.GetLevel(inventorySlotUpgradeInstance.BoundPlayer)); SLRUpgradePack.Logger.LogInfo((object)$"Player has {num} slots"); while (inventorySpots.Invoke(__instance).Count < num) { inventorySpots.Invoke(__instance).Add(null); } } } internal static void RegisterSpot(InventorySpot spot, int index) { if (index < 3 || !Object.op_Implicit((Object)(object)spot) || SemiFunc.RunIsArena()) { return; } Inventory instance = Inventory.instance; if (Object.op_Implicit((Object)(object)instance)) { List<InventorySpot> list = inventorySpots.Invoke(instance); while (list.Count <= index) { list.Add(null); } instance.InventorySpotAddAtIndex(spot, index); } } } [HarmonyPatch(typeof(InventorySpot), "Update")] public class InventorySpotUpdatePatch { private static readonly MethodInfo HandleInputMethod = AccessTools.Method(typeof(InventorySpot), "HandleInput", (Type[])null, (Type[])null); private static void Prefix(InventorySpot __instance) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) InventorySlotUpgrade inventorySlotUpgradeInstance = SLRUpgradePack.InventorySlotUpgradeInstance; if (!inventorySlotUpgradeInstance.UpgradeEnabled.Value || inventorySlotUpgradeInstance.BoundPlayer == null) { return; } int num = inventorySlotUpgradeInstance.Calculate(3, SemiFunc.PlayerAvatarLocal(), inventorySlotUpgradeInstance.UpgradeRegister.GetLevel(inventorySlotUpgradeInstance.BoundPlayer)); List<Keybind> list = new List<Keybind>(9) { null, null, null, inventorySlotUpgradeInstance.ItemSlot4, inventorySlotUpgradeInstance.ItemSlot5, inventorySlotUpgradeInstance.ItemSlot6, inventorySlotUpgradeInstance.ItemSlot7, inventorySlotUpgradeInstance.ItemSlot8, inventorySlotUpgradeInstance.ItemSlot9 }; if (__instance.inventorySpotIndex > 2 && __instance.inventorySpotIndex < num) { Keybind val = list[__instance.inventorySpotIndex]; if (val != null && InputManager.instance.KeyDown(val.inputKey)) { HandleInputMethod.Invoke(__instance, null); } } } } [HarmonyPatch(typeof(PunManager), "SetItemNameLOGIC")] public class PunManagerSetItemNameLOGICPatch { private static bool Prefix(PunManager __instance, string _name, int photonViewID, ItemAttributes _itemAttributes, StatsManager ___statsManager) { if (photonViewID == -1 && SemiFunc.IsMultiplayer()) { return true; } ItemAttributes val = _itemAttributes; if (SemiFunc.IsMultiplayer()) { PhotonView val2 = PhotonView.Find(photonViewID); if (!Object.op_Implicit((Object)(object)val2)) { return true; } val = ((Component)val2).GetComponent<ItemAttributes>(); } if (!Object.op_Implicit((Object)(object)val)) { return true; } AccessTools.FieldRefAccess<ItemAttributes, string>("instanceName").Invoke(val) = _name; ItemBattery component = ((Component)val).GetComponent<ItemBattery>(); if (Object.op_Implicit((Object)(object)component)) { component.SetBatteryLife(___statsManager.GetBatteryLevel(_name)); } ItemEquippable component2 = ((Component)val).GetComponent<ItemEquippable>(); if (!Object.op_Implicit((Object)(object)component2)) { return true; } int hashCode = _name.GetHashCode(); foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if (InventorySlotUpgrade.serverMonitoredInventoryItems.TryGetValue(SemiFunc.PlayerGetSteamID(item), out Dictionary<int, int> value) && value.ContainsValue(hashCode)) { component2.RequestEquip(value.First((KeyValuePair<int, int> element) => element.Value == hashCode).Key, SemiFunc.IsMultiplayer() ? item.photonView.ViewID : (-1)); return false; } } return true; } } public class ObjectDurabilityUpgrade : UpgradeBase<float> { public ObjectDurabilityUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier) : base("Object Durability", "assets/repo/mods/resources/items/items/item upgrade durability lib.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, canBeExponential: true, (int?)null) { } public override float Calculate(float damage, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatReduce(this, "ObjectDurability", damage, player, level); } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "Break")] public static class ObjectDurabilityDamagePatch { internal static void Prefix(PhysGrabObjectImpactDetector __instance, ref float valueLost) { ObjectDurabilityUpgrade objectDurabilityUpgradeInstance = SLRUpgradePack.ObjectDurabilityUpgradeInstance; if (!SemiFunc.IsMasterClientOrSingleplayer() || !__instance.isValuable || valueLost <= 0f || !objectDurabilityUpgradeInstance.UpgradeEnabled.Value) { return; } int totalActivePlayerLevels = objectDurabilityUpgradeInstance.GetTotalActivePlayerLevels(); if (totalActivePlayerLevels > 0) { float num = objectDurabilityUpgradeInstance.Calculate(valueLost, null, totalActivePlayerLevels); if (!float.IsNaN(num) && !float.IsInfinity(num)) { valueLost = Math.Min(valueLost, Math.Max(0f, num)); } } } } public class ObjectValueUpgrade : UpgradeBase<float> { public ConfigEntry<bool> UpgradeScalesSurplus { get; protected set; } public ConfigEntry<float> SurplusPercentScale { get; protected set; } public ObjectValueUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier) : base("Object Value", "assets/repo/mods/resources/items/items/item upgrade value lib.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, canBeExponential: true, (int?)null) { UpgradeScalesSurplus = config.Bind<bool>("Object Value Upgrade", "Scale Surplus Bag", false, "Should the Object Value Upgrade scale the extraction surplus bag?"); SurplusPercentScale = config.Bind<float>("Object Value Upgrade", "Surplus Scaled Percentage", 0.1f, "Percentage of the extraction surplus bag that is scaled by this upgrade"); } public override float Calculate(float value, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ObjectValue", value, player, level); } } [HarmonyPatch(typeof(ValuableObject), "DollarValueSetLogic")] public class ValuableObjectValuePatch { private sealed class ExtractionGoalValueData { internal float BaseValue; internal float UpgradeBonus; internal bool HasBaseValue; internal bool Excluded; } internal static readonly FieldRef<ValuableObject, int> FixedValueRef = AccessTools.FieldRefAccess<ValuableObject, int>("dollarValueOverride"); internal static readonly FieldRef<ValuableObject, float> DollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent"); private static readonly FieldRef<ValuableObject, bool> DollarValueSetRef = AccessTools.FieldRefAccess<ValuableObject, bool>("dollarValueSet"); private static readonly ConditionalWeakTable<ValuableObject, ExtractionGoalValueData> ExtractionGoalValues = new ConditionalWeakTable<ValuableObject, ExtractionGoalValueData>(); private static readonly FieldInfo DollarValueCurrentField = AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent"); private static readonly FieldInfo RoundDirectorHaulGoalMaxField = AccessTools.Field(typeof(RoundDirector), "haulGoalMax"); private static readonly MethodInfo GetExtractionGoalValueMethod = AccessTools.Method(typeof(ValuableObjectValuePatch), "GetExtractionGoalValue", new Type[1] { typeof(ValuableObject) }, (Type[])null); internal static readonly Queue<ValuableObject> DollarValueQueue = new Queue<ValuableObject>(); [HarmonyPriority(800)] internal static void Prefix(ValuableObject __instance) { if (Object.op_Implicit((Object)(object)__instance) && !DollarValueSetRef.Invoke(__instance) && ExtractionGoalValues.TryGetValue(__instance, out ExtractionGoalValueData value)) { value.HasBaseValue = false; value.UpgradeBonus = 0f; } } [HarmonyPriority(800)] internal static void Postfix(ValuableObject __instance) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 ObjectValueUpgrade objectValueUpgradeInstance = SLRUpgradePack.ObjectValueUpgradeInstance; if ((Object)(object)__instance == (Object)null || SemiFunc.RunIsLobby() || SemiFunc.RunIsShop() || SemiFunc.RunIsArena()) { return; } if (objectValueUpgradeInstance.UpgradeEnabled.Value && (int)LevelGenerator.Instance.State <= 11) { if (!DollarValueQueue.Contains(__instance)) { DollarValueQueue.Enqueue(__instance); } } else { Action(__instance); } } internal static void Action(ValuableObject instance) { if (!Object.op_Implicit((Object)(object)instance)) { return; } EnsureBaseExtractionGoalValue(instance, DollarValueCurrentRef.Invoke(instance)); ObjectValueUpgrade objectValueUpgradeInstance = SLRUpgradePack.ObjectValueUpgradeInstance; if (SemiFunc.IsMasterClientOrSingleplayer() && objectValueUpgradeInstance.UpgradeEnabled.Value && (objectValueUpgradeInstance.UpgradeScalesSurplus.Value || !StringUtilsExtensions.StartsWithIgnoreCaseFast(((Object)instance).name, "surplus"))) { SLRUpgradePack.Logger.LogDebug((object)$"{((Object)instance).name} Original value: {instance.valuePreset.valueMin} - {instance.valuePreset.valueMax} ({DollarValueCurrentRef.Invoke(instance)} / {FixedValueRef.Invoke(instance)})"); Value val = Object.Instantiate<Value>(instance.valuePreset); float value = DollarValueCurrentRef.Invoke(instance); int totalActivePlayerLevels = objectValueUpgradeInstance.GetTotalActivePlayerLevels(); val.valueMin = objectValueUpgradeInstance.Calculate(instance.valuePreset.valueMin, null, totalActivePlayerLevels); val.valueMax = objectValueUpgradeInstance.Calculate(instance.valuePreset.valueMax, null, totalActivePlayerLevels); if (FixedValueRef.Invoke(instance) != 0) { FixedValueRef.Invoke(instance) = (int)Math.Ceiling(objectValueUpgradeInstance.Calculate(FixedValueRef.Invoke(instance), null, totalActivePlayerLevels)); } value = objectValueUpgradeInstance.Calculate(value, null, totalActivePlayerLevels); instance.valuePreset = val; DollarValueCurrentRef.Invoke(instance) = value; UpdateExtractionGoalBonusFromCurrent(instance); SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with levels {0}: {1} - {2} ({3} / {4})", string.Join(",", from entry in objectValueUpgradeInstance.GetActivePlayerLevels() select (SemiFunc.PlayerGetName(entry.Player), Level: entry.Level)), instance.valuePreset.valueMin, instance.valuePreset.valueMax, DollarValueCurrentRef.Invoke(instance), FixedValueRef.Invoke(instance))); } } internal static void EnsureBaseExtractionGoalValue(ValuableObject instance, float value) { if (Object.op_Implicit((Object)(object)instance)) { ExtractionGoalValueData value2 = ExtractionGoalValues.GetValue(instance, (ValuableObject _) => new ExtractionGoalValueData()); if (!value2.HasBaseValue) { value2.BaseValue = value; value2.HasBaseValue = true; } } } internal static void UpdateExtractionGoalBonusFromCurrent(ValuableObject instance) { if (Object.op_Implicit((Object)(object)instance) && ExtractionGoalValues.TryGetValue(instance, out ExtractionGoalValueData value) && value.HasBaseValue) { value.UpgradeBonus = DollarValueCurrentRef.Invoke(instance) - value.BaseValue; } } internal static void MarkExcludedFromExtractionGoal(ValuableObject instance) { if (Object.op_Implicit((Object)(object)instance)) { ExtractionGoalValues.GetValue(instance, (ValuableObject _) => new ExtractionGoalValueData()).Excluded = true; } } internal static float GetExtractionGoalValue(ValuableObject instance) { if (!Object.op_Implicit((Object)(object)instance)) { return 0f; } if (!ExtractionGoalValues.TryGetValue(instance, out ExtractionGoalValueData value)) { return DollarValueCurrentRef.Invoke(instance); } if (value.Excluded) { return 0f; } float num = DollarValueCurrentRef.Invoke(instance); if (!value.HasBaseValue) { return num; } return Mathf.Max(0f, num - value.UpgradeBonus); } internal static IEnumerable<CodeInstruction> ReplaceSpawnBudgetValueLoad(IEnumerable<CodeInstruction> instructions) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown int num = 0; List<CodeInstruction> list = new List<CodeInstruction>(); foreach (CodeInstruction instruction in instructions) { CodeInstruction val = new CodeInstruction(instruction); if (CodeInstructionExtensions.LoadsField(val, DollarValueCurrentField, false)) { val.opcode = OpCodes.Call; val.operand = GetExtractionGoalValueMethod; num++; } list.Add(val); } if (num != 1) { SLRUpgradePack.Logger.LogWarning((object)$"Expected one valuable spawn-budget value read in ValuableDirector.SpawnValuable, replaced {num}."); } return list; } internal static IEnumerable<CodeInstruction> ReplaceExtractionGoalValueLoad(IEnumerable<CodeInstruction> instructions) { int num = 0; List<CodeInstruction> list = instructions.Select((Func<CodeInstruction, CodeInstruction>)((CodeInstruction instruction) => new CodeInstruction(instruction))).ToList(); for (int num2 = 0; num2 < list.Count - 3; num2++) { CodeInstruction val = list[num2]; if (CodeInstructionExtensions.LoadsField(val, DollarValueCurrentField, false) && !(list[num2 + 1].opcode != OpCodes.Conv_I4) && !(list[num2 + 2].opcode != OpCodes.Add) && CodeInstructionExtensions.StoresField(list[num2 + 3], RoundDirectorHaulGoalMaxField)) { val.opcode = OpCodes.Call; val.operand = GetExtractionGoalValueMethod; num++; } } if (num != 1) { SLRUpgradePack.Logger.LogWarning((object)$"Expected one value read when building RoundDirector.haulGoalMax, replaced {num}."); } return list; } } [HarmonyPatch] public static class ValuableObjectExtractionGoalValuePatch { private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.Inner(typeof(ValuableObject), "<DollarValueSet>d__38"), "MoveNext", (Type[])null, (Type[])null); } [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ValuableObjectValuePatch.ReplaceExtractionGoalValueLoad(instructions); } } [HarmonyPatch(typeof(ValuableDirector), "SpawnValuable")] public static class ValuableDirectorSpawnBudgetGoalValuePatch { [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ValuableObjectValuePatch.ReplaceSpawnBudgetValueLoad(instructions); } } [HarmonyPatch(typeof(LevelGenerator), "Start")] public class LevelGeneratorObjectValueStartPatch { internal static void Postfix() { if (!SemiFunc.RunIsLevel()) { return; } while (ValuableObjectValuePatch.DollarValueQueue.Count > 0) { ValuableObject val = ValuableObjectValuePatch.DollarValueQueue.Dequeue(); if (Object.op_Implicit((Object)(object)val)) { ValuableObjectValuePatch.Action(val); } } } } public class SpawnedValuableValuePatch<TSVT> where TSVT : MonoBehaviour { protected static void DoValuableStuff(TSVT spawnedValuable) { ValuableObject val = default(ValuableObject); if (((Component)(object)spawnedValuable).TryGetComponent<ValuableObject>(ref val) && SLRUpgradePack.ObjectValueUpgradeInstance.UpgradeEnabled.Value) { SLRUpgradePack.Logger.LogDebug((object)$"Valuable {((Object)(object)spawnedValuable).name} spawned with: {val.valuePreset.valueMin} {val.valuePreset.valueMax} {ValuableObjectValuePatch.FixedValueRef.Invoke(val)}"); ValuableObjectValuePatch.Action(val); } } } [HarmonyPatch(typeof(SurplusValuable), "Start")] public class SurplusValuableValuePatch : SpawnedValuableValuePatch<SurplusValuable> { internal static void Prefix(SurplusValuable __instance) { ObjectValueUpgrade objectValueUpgradeInstance = SLRUpgradePack.ObjectValueUpgradeInstance; ValuableObject val = default(ValuableObject); if (objectValueUpgradeInstance.UpgradeScalesSurplus.Value && objectValueUpgradeInstance.UpgradeEnabled.Value && ((Component)__instance).TryGetComponent<ValuableObject>(ref val)) { Value val2 = Object.Instantiate<Value>(val.valuePreset); float valueMin = val.valuePreset.valueMin; float valueMax = val.valuePreset.valueMax; int num = ValuableObjectValuePatch.FixedValueRef.Invoke(val); float num2 = ValuableObjectValuePatch.DollarValueCurrentRef.Invoke(val); ValuableObjectValuePatch.EnsureBaseExtractionGoalValue(val, num2); val2.valueMin = valueMin * objectValueUpgradeInstance.SurplusPercentScale.Value; val2.valueMax = valueMax * objectValueUpgradeInstance.SurplusPercentScale.Value; int num3 = (ValuableObjectValuePatch.FixedValueRef.Invoke(val) = (int)((float)num * objectValueUpgradeInstance.SurplusPercentScale.Value)); float num4 = (ValuableObjectValuePatch.DollarValueCurrentRef.Invoke(val) = num2 * objectValueUpgradeInstance.SurplusPercentScale.Value); val.valuePreset = val2; SpawnedValuableValuePatch<SurplusValuable>.DoValuableStuff(__instance); Value valuePreset = val.valuePreset; valuePreset.valueMin += valueMin - val2.valueMin; Value valuePreset2 = val.valuePreset; valuePreset2.valueMax += valueMax - val2.valueMax; ValuableObjectValuePatch.FixedValueRef.Invoke(val) += num - num3; ValuableObjectValuePatch.DollarValueCurrentRef.Invoke(val) += num2 - num4; ValuableObjectValuePatch.UpdateExtractionGoalBonusFromCurrent(val); SLRUpgradePack.Logger.LogInfo((object)$"Surplus bag worth {num2} scaling {num4} to a total of {ValuableObjectValuePatch.DollarValueCurrentRef.Invoke(val)}"); } } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector))] public static class ValuableObjectDynamicGoalValuePatch { private static readonly FieldRef<PhysGrabObjectImpactDetector, ValuableObject> ValuableObjectRef = AccessTools.FieldRefAccess<PhysGrabObjectImpactDetector, ValuableObject>("valuableObject"); [HarmonyPatch("HealLogic")] [HarmonyPostfix] private static void HealLogicPostfix(PhysGrabObjectImpactDetector __instance) { RefreshGoalValue(__instance); } [HarmonyPatch("ResetObject")] [HarmonyPostfix] private static void R