Please disclose if your mod was created primarily 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.3.8
plugins/SLRUpgradePack.dll
Decompiled 3 weeks agousing 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.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 REPOLib.Modules; using REPOLib.Objects.Sdk; using SLRUpgradePack.Properties; using SLRUpgradePack.UpgradeManagers; 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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("SolarAaron")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+3d28979a6e4b82ec617f718b0f407f8779ff5360")] [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] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SLRUpgradePack { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("SolarAaron.SLRUpgradePack", "SLRUpgradePack", "0.3.8")] public class SLRUpgradePack : BaseUnityPlugin { internal static readonly Dictionary<string, int> LimitedUse = new Dictionary<string, int>(); 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() || !LevelGenerator.Instance.Generated) { return; } List<Action> list = new List<Action>(); if (PhysGrabberPatch.Prepare() && OverchargeUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair3 in OverchargeUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair3.Value < OverchargeUpgradeInstance.StartingAmount.Value) { list.Add(delegate { OverchargeUpgradeInstance.UpgradeRegister.SetLevel(pair3.Key, OverchargeUpgradeInstance.StartingAmount.Value); }); } } } if (ArmorUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair4 in ArmorUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair4.Value < ArmorUpgradeInstance.StartingAmount.Value) { list.Add(delegate { ArmorUpgradeInstance.UpgradeRegister.SetLevel(pair4.Key, ArmorUpgradeInstance.StartingAmount.Value); }); } } } if (ObjectValueUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair5 in ObjectValueUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair5.Value < ObjectValueUpgradeInstance.StartingAmount.Value) { list.Add(delegate { ObjectValueUpgradeInstance.UpgradeRegister.SetLevel(pair5.Key, ObjectValueUpgradeInstance.StartingAmount.Value); }); } } } if (ObjectDurabilityUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair6 in ObjectDurabilityUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair6.Value < ObjectDurabilityUpgradeInstance.StartingAmount.Value) { list.Add(delegate { ObjectDurabilityUpgradeInstance.UpgradeRegister.SetLevel(pair6.Key, ObjectDurabilityUpgradeInstance.StartingAmount.Value); }); } } } if (ValuableDensityUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair7 in ValuableDensityUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair7.Value < ValuableDensityUpgradeInstance.StartingAmount.Value) { list.Add(delegate { ValuableDensityUpgradeInstance.UpgradeRegister.SetLevel(pair7.Key, ValuableDensityUpgradeInstance.StartingAmount.Value); }); } } } if (HeartOfGoldUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair8 in HeartOfGoldUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair8.Value < HeartOfGoldUpgradeInstance.StartingAmount.Value) { list.Add(delegate { HeartOfGoldUpgradeInstance.UpgradeRegister.SetLevel(pair8.Key, HeartOfGoldUpgradeInstance.StartingAmount.Value); }); } } } if (RegenerationUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair9 in RegenerationUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair9.Value < RegenerationUpgradeInstance.StartingAmount.Value) { list.Add(delegate { RegenerationUpgradeInstance.UpgradeRegister.SetLevel(pair9.Key, RegenerationUpgradeInstance.StartingAmount.Value); }); } } } if (ExtraLifeUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair2 in ExtraLifeUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair2.Value < ExtraLifeUpgradeInstance.StartingAmount.Value) { list.Add(delegate { ExtraLifeUpgradeInstance.UpgradeRegister.SetLevel(pair2.Key, ExtraLifeUpgradeInstance.StartingAmount.Value); }); } } } if (InventorySlotUpgradeInstance.UpgradeEnabled.Value) { foreach (KeyValuePair<string, int> pair in InventorySlotUpgradeInstance.UpgradeRegister.PlayerDictionary) { if (pair.Value < InventorySlotUpgradeInstance.StartingAmount.Value) { list.Add(delegate { InventorySlotUpgradeInstance.UpgradeRegister.SetLevel(pair.Key, InventorySlotUpgradeInstance.StartingAmount.Value); }); } } } list.ForEach(delegate(Action action) { action(); }); } } } 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> { public static NetworkedEvent ExtraLifeEvent = new NetworkedEvent("Extra Life", (Action<EventData>)ExtraLifeAction); public ConfigEntry<int> RevivePercent { get; protected set; } internal Dictionary<string, ExtraLife> ExtraLives { get; set; } = new Dictionary<string, ExtraLife>(); private static void ExtraLifeAction(EventData e) { NetworkMessage networkMessage = NetworkMessage.FromByteArray((byte[])e.CustomData); ExtraLifeUpgrade extraLifeUpgradeInstance = SLRUpgradePack.ExtraLifeUpgradeInstance; if (!extraLifeUpgradeInstance.ExtraLives.ContainsKey(networkMessage.PlayerId)) { extraLifeUpgradeInstance.InitUpgrade(SemiFunc.PlayerAvatarGetFromSteamID(networkMessage.PlayerId), extraLifeUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarGetFromSteamID(networkMessage.PlayerId))); } extraLifeUpgradeInstance.ExtraLives[networkMessage.PlayerId].SetViewId(networkMessage.PhotonId.Value); } 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); } } public class ExtraLife : MonoBehaviour { private static readonly FieldRef<PlayerHealth, int>? MaxHealthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("maxHealth"); private Coroutine? reviving; private PhotonView photonView; private FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health"); private FieldRef<PlayerDeathHead, bool> _inExtractionPointRef = AccessTools.FieldRefAccess<PlayerDeathHead, bool>("inExtractionPoint"); private FieldRef<PlayerDeathHead, PhysGrabObject> _physGrabObjectRef = AccessTools.FieldRefAccess<PlayerDeathHead, PhysGrabObject>("physGrabObject"); public PlayerDeathHead playerHead { get; set; } public PlayerAvatar player { get; set; } private void Update() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)(object)SemiFunc.PlayerAvatarLocal() || !Traverse.Create((object)RoundDirector.instance).Field("extractionPointsFetched").GetValue<bool>()) { return; } if (SemiFunc.IsMultiplayer() && photonView.ViewID == 0) { PhotonNetwork.AllocateViewID(photonView); NetworkMessage msg = new NetworkMessage { PlayerId = SemiFunc.PlayerGetSteamID(player), PhotonId = photonView.ViewID }; ExtraLifeUpgrade.ExtraLifeEvent.RaiseEvent((object)NetworkMessage.ToByteArray(msg), NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } if (Object.op_Implicit((Object)(object)player.playerHealth)) { ExtraLifeUpgrade extraLifeUpgradeInstance = SLRUpgradePack.ExtraLifeUpgradeInstance; if (extraLifeUpgradeInstance.UpgradeEnabled.Value) { if (_healthRef.Invoke(player.playerHealth) == 0 && extraLifeUpgradeInstance.UpgradeRegister.GetLevel(player) > 0 && !_inExtractionPointRef.Invoke(playerHead) && reviving == null) { reviving = ((MonoBehaviour)this).StartCoroutine(BeginReviving()); } if (reviving != null && _healthRef.Invoke(player.playerHealth) > 0) { reviving = null; } } } else { SLRUpgradePack.Logger.LogInfo((object)("Extra Life: player " + ((Object)player).name + " has no health object (disconnected?), self-destructing!")); Object.Destroy((Object)(object)this); } } private IEnumerator BeginReviving() { yield return (object)new WaitForEndOfFrame(); SLRUpgradePack.Logger.LogInfo((object)("Preparing to revive " + SemiFunc.PlayerGetName(player))); if (_inExtractionPointRef.Invoke(playerHead)) { reviving = null; SLRUpgradePack.Logger.LogInfo((object)"Not reviving head in extraction point"); yield break; } if (!SemiFunc.IsMultiplayer()) { ReviveLogic(); } else { photonView.RPC("ReviveLogic", (RpcTarget)0, Array.Empty<object>()); } reviving = null; } [PunRPC] private void ReviveLogic() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) ExtraLifeUpgrade extraLifeUpgradeInstance = SLRUpgradePack.ExtraLifeUpgradeInstance; _physGrabObjectRef.Invoke(playerHead).centerPoint = Vector3.zero; try { player.Revive(false); } catch { } player.playerHealth.Heal(Mathf.FloorToInt((float)MaxHealthRef.Invoke(player.playerHealth) * ((float)extraLifeUpgradeInstance.RevivePercent.Value / 100f)), true); if (_healthRef.Invoke(player.playerHealth) > 0) { extraLifeUpgradeInstance.UpgradeRegister.RemoveLevel(player, 1); } } private void Start() { SLRUpgradePack.Logger.LogInfo((object)(SemiFunc.PlayerGetName(player) + " has obtained extra lives")); if (!((Component)this).TryGetComponent<PhotonView>(ref photonView)) { photonView = ((Component)this).gameObject.AddComponent<PhotonView>(); } } internal void SetViewId(int id) { photonView.ViewID = id; photonView.TransferOwnership(player.photonView.Owner); } } [HarmonyPatch(typeof(LevelGenerator))] public class LevelGeneratorExtraLifePatch { [HarmonyPatch("GenerateDone")] [HarmonyPostfix] private static void GenerateDonePostfix() { ExtraLifeUpgrade extraLifeUpgradeInstance = SLRUpgradePack.ExtraLifeUpgradeInstance; PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; if (!((Object)(object)playerAvatarScript == (Object)null)) { SLRUpgradePack.Logger.LogInfo((object)("Adding extra life component to " + SemiFunc.PlayerGetName(playerAvatarScript) + " (" + SemiFunc.PlayerGetSteamID(playerAvatarScript) + ")")); if (extraLifeUpgradeInstance.ExtraLives.TryGetValue(SemiFunc.PlayerGetSteamID(playerAvatarScript), out ExtraLife value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } value = ((Component)playerAvatarScript).gameObject.AddComponent<ExtraLife>(); value.player = playerAvatarScript; value.playerHead = playerAvatarScript.playerDeathHead; extraLifeUpgradeInstance.ExtraLives[SemiFunc.PlayerGetSteamID(playerAvatarScript)] = value; } } } public class HeartOfGoldUpgrade : UpgradeBase<float> { 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) { NetworkMessage networkMessage = NetworkMessage.FromByteArray((byte[])e.CustomData); HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!heartOfGoldUpgradeInstance.GoldenHearts.ContainsKey(networkMessage.PlayerId)) { heartOfGoldUpgradeInstance.InitUpgrade(SemiFunc.PlayerAvatarGetFromSteamID(networkMessage.PlayerId), heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(SemiFunc.PlayerAvatarGetFromSteamID(networkMessage.PlayerId))); } heartOfGoldUpgradeInstance.GoldenHearts[networkMessage.PlayerId].SetViewId(networkMessage.PhotonId.Value); } 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 PhotonView photonView; private readonly FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health"); 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 Start() { if (!((Component)this).TryGetComponent<PhotonView>(ref photonView)) { photonView = ((Component)this).gameObject.AddComponent<PhotonView>(); } Pause = false; } public void DestroyOnlyMe() { if (SemiFunc.IsMasterClientOrSingleplayer()) { DestroyOnlyMeRPC(); } else { photonView.RPC("DestroyOnlyMeRPC", (RpcTarget)0, Array.Empty<object>()); } } [PunRPC] private void DestroyOnlyMeRPC() { if (!((Object)(object)ValuableComponent == (Object)null)) { SLRUpgradePack.Logger.LogInfo((object)("Components in GoldenHeart: " + string.Join(',', from v in ((Component)this).GetComponents<Object>() select ((object)v).ToString()))); RoundDirector.instance.PhysGrabObjectRemove(((Component)ValuableComponent).GetComponent<PhysGrabObject>()); Object.Destroy((Object)(object)ValuableComponent); ValuableComponent = null; } } public void CreateOnlyMe() { if (SemiFunc.IsMasterClientOrSingleplayer()) { CreateOnlyMeRPC(); } else { photonView.RPC("CreateOnlyMeRPC", (RpcTarget)0, Array.Empty<object>()); } } [PunRPC] private void CreateOnlyMeRPC() { //IL_013f: 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_0214: 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_025c: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; SLRUpgradePack.Logger.LogInfo((object)("Adding valuable component to player " + SemiFunc.PlayerGetName(player))); ValuableComponent = ((Component)player.healthGrab).gameObject.AddComponent<ValuableObject>(); 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 num2 = (lastLevel = -1); lastHealth = num2; } private void Update() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)(object)player || !Traverse.Create((object)RoundDirector.instance).Field("extractionPointsFetched").GetValue<bool>()) { return; } HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!heartOfGoldUpgradeInstance.UpgradeEnabled.Value || Pause) { return; } if (!Object.op_Implicit((Object)(object)player.playerHealth)) { Object.Destroy((Object)(object)this); } if (heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player) != 0 && _healthRef.Invoke(player.playerHealth) != 0 && (lastLevel != heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player) || lastHealth != _healthRef.Invoke(player.playerHealth))) { if (SemiFunc.IsMultiplayer() && photonView.ViewID == 0) { PhotonNetwork.AllocateViewID(photonView); NetworkMessage msg = new NetworkMessage { PlayerId = SemiFunc.PlayerGetSteamID(player), PhotonId = photonView.ViewID }; HeartOfGoldUpgrade.HeartOfGoldEvent.RaiseEvent((object)NetworkMessage.ToByteArray(msg), NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } lastLevel = heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player); lastHealth = _healthRef.Invoke(player.playerHealth); if ((Object)(object)ValuableComponent == (Object)null || !Object.op_Implicit((Object)(object)ValuableComponent)) { CreateOnlyMe(); } if (!SemiFunc.IsMultiplayer()) { UpdateOnlyMeRPC(); } else { photonView.RPC("UpdateOnlyMeRPC", (RpcTarget)0, Array.Empty<object>()); } } } [PunRPC] private void UpdateOnlyMeRPC() { HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!_discoveredRef.Invoke(ValuableComponent)) { ValuableComponent.Discover((State)0); } _dollarValueCurrentRef.Invoke(ValuableComponent) = heartOfGoldUpgradeInstance.Calculate((float)_healthRef.Invoke(player.playerHealth) * heartOfGoldUpgradeInstance.BaseHeartValue.Value, player, heartOfGoldUpgradeInstance.UpgradeRegister.GetLevel(player)); ValuableObjectValuePatch.Action(ValuableComponent); } 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 void SetViewId(int id) { photonView.ViewID = id; photonView.TransferOwnership(player.photonView.Owner); } } [HarmonyPatch(typeof(ExtractionPoint))] public class ExtractionPointDestroyPatch { private static FieldRef<RoundDirector, int>? _totalHaulRef = AccessTools.FieldRefAccess<RoundDirector, int>("totalHaul"); [HarmonyPatch("DestroyAllPhysObjectsInHaulList")] [HarmonyPrefix] private static bool DestroyAllPrefix() { HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!SemiFunc.IsMasterClientOrSingleplayer() || !heartOfGoldUpgradeInstance.UpgradeEnabled.Value) { return true; } ValuableObject val = default(ValuableObject); foreach (GameObject dollarHaul in RoundDirector.instance.dollarHaulList) { if (!Object.op_Implicit((Object)(object)dollarHaul) || !Object.op_Implicit((Object)(object)dollarHaul.GetComponent<PhysGrabObject>())) { continue; } _totalHaulRef.Invoke(RoundDirector.instance) += (int)Traverse.Create((object)dollarHaul.GetComponent<ValuableObject>()).Field("dollarValueCurrent").GetValue<float>(); if (dollarHaul.TryGetComponent<ValuableObject>(ref val) && ((Object)val).name.Equals("Health Grab")) { foreach (KeyValuePair<string, GoldenHeart> goldenHeart in heartOfGoldUpgradeInstance.GoldenHearts) { if ((Object)(object)goldenHeart.Value.ValuableComponent == (Object)(object)val) { SLRUpgradePack.Logger.LogInfo((object)("Player " + SemiFunc.PlayerGetName(goldenHeart.Value.player) + " in extraction zone counts as valuable")); goldenHeart.Value.PauseLogic(pause: true); goldenHeart.Value.DestroyOnlyMe(); } } } else { dollarHaul.GetComponent<PhysGrabObject>().DestroyPhysGrabObject(); } } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { player.playerDeathHead.Revive(); } foreach (KeyValuePair<string, GoldenHeart> goldenHeart2 in heartOfGoldUpgradeInstance.GoldenHearts) { goldenHeart2.Value.PauseLogic(pause: false); } return false; } [HarmonyPatch("DestroyTheFirstPhysObjectsInHaulList")] [HarmonyPrefix] private static bool DestroyFirstPrefix() { HeartOfGoldUpgrade heartOfGoldUpgradeInstance = SLRUpgradePack.HeartOfGoldUpgradeInstance; if (!SemiFunc.IsMasterClientOrSingleplayer() || RoundDirector.instance.dollarHaulList.Count == 0 || !Object.op_Implicit((Object)(object)RoundDirector.instance.dollarHaulList[0]) || !Object.op_Implicit((Object)(object)RoundDirector.instance.dollarHaulList[0].GetComponent<PhysGrabObject>()) || !heartOfGoldUpgradeInstance.UpgradeEnabled.Value) { return true; } _totalHaulRef.Invoke(RoundDirector.instance) += (int)Traverse.Create((object)RoundDirector.instance.dollarHaulList[0].GetComponent<ValuableObject>()).Field("dollarValueCurrent").GetValue<float>(); ValuableObject val = default(ValuableObject); if (RoundDirector.instance.dollarHaulList[0].TryGetComponent<ValuableObject>(ref val) && ((Object)val).name.Equals("Health Grab")) { foreach (KeyValuePair<string, GoldenHeart> goldenHeart in heartOfGoldUpgradeInstance.GoldenHearts) { if ((Object)(object)goldenHeart.Value.ValuableComponent == (Object)(object)val) { SLRUpgradePack.Logger.LogInfo((object)("Player " + SemiFunc.PlayerGetName(goldenHeart.Value.player) + " in extraction zone counts as valuable")); goldenHeart.Value.PauseLogic(pause: true); goldenHeart.Value.DestroyOnlyMe(); } } } else { RoundDirector.instance.dollarHaulList[0].GetComponent<PhysGrabObject>().DestroyPhysGrabObject(); } RoundDirector.instance.dollarHaulList.RemoveAt(0); 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>>(); 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); } } internal override void UseUpgrade(PlayerAvatar player, int level) { base.UseUpgrade(player, level); InventoryStartPatch.Postfix(InventoryRef); InventoryUIStartPatch.Postfix(UIRef); } } [HarmonyPatch(typeof(InventoryUI), "Start")] public class InventoryUIStartPatch { private static FieldRef<InventoryUI, List<GameObject>> allChildren = AccessTools.FieldRefAccess<InventoryUI, List<GameObject>>("allChildren"); internal static void Postfix(InventoryUI __instance) { //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) 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; Transform child = ((Component)__instance).transform.GetChild(0); for (int i = 0; i < num; i++) { Transform val = ((Component)__instance).transform.Find($"Inventory Spot {i + 1}"); if ((Object)(object)val != (Object)null) { val.localPosition = Vector2.op_Implicit(new Vector2(num2 + (float)i * 40f, -175.3f)); continue; } Transform val2 = Object.Instantiate<Transform>(child, child.parent); ((Object)val2).name = $"Inventory Spot {i + 1}"; InventorySpot component = ((Component)val2).GetComponent<InventorySpot>(); component.inventorySpotIndex = i; TextMeshProUGUI component2 = ((Component)val2.Find("Numbers")).GetComponent<TextMeshProUGUI>(); string text2 = (((TMP_Text)component.noItem).text = (i + 1).ToString()); string text3 = text2; ((TMP_Text)component2).text = text3; val2.localPosition = Vector2.op_Implicit(new Vector2(num2 + (float)i * 40f, -175.3f)); allChildren.Invoke(__instance).Add(((Component)val2).gameObject); } } } [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(); } } [HarmonyPatch(typeof(Inventory), "Start")] public class InventoryStartPatch { private static 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); } } } } [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_00ce: Unknown result type (might be due to invalid IL or missing references) InventorySlotUpgrade inventorySlotUpgradeInstance = SLRUpgradePack.InventorySlotUpgradeInstance; if (inventorySlotUpgradeInstance.UpgradeEnabled.Value && inventorySlotUpgradeInstance.BoundPlayer != null) { 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 && InputManager.instance.KeyDown(list.GetRange(0, num)[__instance.inventorySpotIndex].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()) { val = ((Component)PhotonView.Find(photonViewID)).GetComponent<ItemAttributes>(); } if ((Object)(object)_itemAttributes == (Object)null && !SemiFunc.IsMultiplayer()) { 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.itemStatBattery[name]); } ItemEquippable component2 = ((Component)val).GetComponent<ItemEquippable>(); if (!Object.op_Implicit((Object)(object)component2)) { return true; } int hashCode = name.GetHashCode(); if (!Object.op_Implicit((Object)(object)component2)) { return true; } 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 value, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "ObjectDurability", value, player, level); } } [HarmonyPatch(typeof(ValuableObject), "Start")] public class ValuableObjectDurabilityPatch { [HarmonyPriority(0)] internal static void Prefix(ValuableObject __instance) { ObjectDurabilityUpgrade objectDurabilityUpgradeInstance = SLRUpgradePack.ObjectDurabilityUpgradeInstance; if (SemiFunc.IsMasterClientOrSingleplayer() && objectDurabilityUpgradeInstance.UpgradeEnabled.Value) { SLRUpgradePack.Logger.LogDebug((object)$"Original durability: {__instance.durabilityPreset.durability}"); Durability val = Object.Instantiate<Durability>(__instance.durabilityPreset); int level = (from kvp in objectDurabilityUpgradeInstance.UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select kvp.Value).Sum(); val.durability = objectDurabilityUpgradeInstance.Calculate(__instance.durabilityPreset.durability, null, level); val.fragility = UpgradeBase<float>.DefaultCalculateFloatReduce(objectDurabilityUpgradeInstance, "ObjectDurability", __instance.durabilityPreset.fragility, null, level); __instance.durabilityPreset = val; SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with levels {0}: {1}", string.Join(",", from kvp in objectDurabilityUpgradeInstance.UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value)), __instance.durabilityPreset.durability)); } } } public class SpawnedValuableDurabilityPatch<TSVT> where TSVT : MonoBehaviour { protected static void DoValuableStuff(TSVT spawnedValuable) { ValuableObject val = default(ValuableObject); if (((Component)(object)spawnedValuable).TryGetComponent<ValuableObject>(ref val)) { SLRUpgradePack.Logger.LogDebug((object)$"Valuable spawned with: {val.durabilityPreset.durability} / {val.durabilityPreset.fragility}"); ValuableObjectDurabilityPatch.Prefix(val); } } } [HarmonyPatch(typeof(SurplusValuable), "Start")] public class SurplusValuableDurabilityValuePatch : SpawnedValuableDurabilityPatch<SurplusValuable> { internal static void Prefix(SurplusValuable __instance) { SpawnedValuableDurabilityPatch<SurplusValuable>.DoValuableStuff(__instance); } } [HarmonyPatch(typeof(EnemyValuable), "Start")] public class EnemyValuableDurabilityValuePatch : SpawnedValuableDurabilityPatch<EnemyValuable> { internal static void Prefix(EnemyValuable __instance) { SpawnedValuableDurabilityPatch<EnemyValuable>.DoValuableStuff(__instance); } } 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 { internal static readonly FieldRef<ValuableObject, int> FixedValueRef = AccessTools.FieldRefAccess<ValuableObject, int>("dollarValueOverride"); internal static readonly FieldRef<ValuableObject, float> DollarValueCurrentRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent"); internal static readonly Queue<ValuableObject> DollarValueQueue = new Queue<ValuableObject>(); [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) { 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 level = (from kvp in objectValueUpgradeInstance.UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select kvp.Value).Sum(); val.valueMin = objectValueUpgradeInstance.Calculate(instance.valuePreset.valueMin, null, level); val.valueMax = objectValueUpgradeInstance.Calculate(instance.valuePreset.valueMax, null, level); if (FixedValueRef.Invoke(instance) != 0) { FixedValueRef.Invoke(instance) = (int)Math.Ceiling(objectValueUpgradeInstance.Calculate(FixedValueRef.Invoke(instance), null, level)); } value = objectValueUpgradeInstance.Calculate(value, null, level); instance.valuePreset = val; DollarValueCurrentRef.Invoke(instance) = value; SLRUpgradePack.Logger.LogDebug((object)string.Format("After calculation with levels {0}: {1} - {2} ({3} / {4})", string.Join(",", from kvp in objectValueUpgradeInstance.UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value)), instance.valuePreset.valueMin, instance.valuePreset.valueMax, DollarValueCurrentRef.Invoke(instance), FixedValueRef.Invoke(instance))); } } } [HarmonyPatch(typeof(LevelGenerator), "Start")] public class LevelGeneratorObjectValueStartPatch { internal static void Postfix(ValuableDirector __instance) { 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); 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; SLRUpgradePack.Logger.LogInfo((object)$"Surplus bag worth {num2} scaling {num4} to a total of {ValuableObjectValuePatch.DollarValueCurrentRef.Invoke(val)}"); } } } [HarmonyPatch(typeof(EnemyValuable), "Start")] public class EnemyValuableValuePatch : SpawnedValuableValuePatch<EnemyValuable> { internal static void Prefix(EnemyValuable __instance) { SpawnedValuableValuePatch<EnemyValuable>.DoValuableStuff(__instance); } } public class OverchargeUpgrade : UpgradeBase<float> { public OverchargeUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier) : base("Overcharge", "assets/repo/mods/resources/items/items/item upgrade overcharge 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, "Overcharge", value, player, level); } } [HarmonyPatch(typeof(PhysGrabber))] public class PhysGrabberPatch { public static bool Prepare() { return typeof(PhysGrabber).GetMethods().Any((MethodInfo method) => method.Name.Equals("PhysGrabOverCharge")); } [HarmonyPatch("PhysGrabOverCharge")] [HarmonyPrefix] private static void GrabOverchargePrefix(PhysGrabber __instance, ref float _amount) { OverchargeUpgrade overchargeUpgradeInstance = SLRUpgradePack.OverchargeUpgradeInstance; if (overchargeUpgradeInstance.UpgradeEnabled.Value) { SLRUpgradePack.Logger.LogDebug((object)$"Original overcharge amount: {_amount}"); _amount = overchargeUpgradeInstance.Calculate(_amount, __instance.playerAvatar, overchargeUpgradeInstance.UpgradeRegister.GetLevel(__instance.playerAvatar)); SLRUpgradePack.Logger.LogDebug((object)$"After calculation with level {overchargeUpgradeInstance.UpgradeRegister.GetLevel(__instance.playerAvatar)}: {_amount}"); } } [HarmonyPatch("PhysGrabOverChargeLogic")] [HarmonyPrefix] private static void LogicPrefix(PhysGrabber __instance, float ___physGrabBeamOverChargeFloat, out float __state) { _ = SLRUpgradePack.OverchargeUpgradeInstance; __state = ___physGrabBeamOverChargeFloat; } [HarmonyPatch("PhysGrabOverChargeLogic")] [HarmonyPostfix] private static void LogicPostfix(PhysGrabber __instance, ref float __state, ref float ___physGrabBeamOverChargeFloat, ref byte ___physGrabBeamOverCharge) { if (__state > 0f && __state > ___physGrabBeamOverChargeFloat) { OverchargeUpgrade overchargeUpgradeInstance = SLRUpgradePack.OverchargeUpgradeInstance; float num = 0.1f * Time.deltaTime; float num2 = UpgradeBase<float>.DefaultCalculateFloatIncrease(overchargeUpgradeInstance, "Overcharge", num, __instance.playerAvatar, overchargeUpgradeInstance.UpgradeRegister.GetLevel(__instance.playerAvatar)) - num; ___physGrabBeamOverChargeFloat = Math.Max(0f, ___physGrabBeamOverChargeFloat - num2); ___physGrabBeamOverCharge = (byte)((double)___physGrabBeamOverChargeFloat * 200.0); } } } public class RegenerationComponent : MonoBehaviour { internal PlayerAvatar player; private float pendingHealing; private readonly FieldRef<PlayerHealth, int> _healthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("health"); private void Start() { SLRUpgradePack.Logger.LogInfo((object)(SemiFunc.PlayerGetName(player) + " is regenerating")); } private void Update() { RegenerationUpgrade regenerationUpgradeInstance = SLRUpgradePack.RegenerationUpgradeInstance; if (ValuableDirector.instance.setupComplete && regenerationUpgradeInstance.UpgradeEnabled.Value && regenerationUpgradeInstance.UpgradeRegister.GetLevel(player) != 0 && _healthRef.Invoke(player.playerHealth) != 0) { pendingHealing += regenerationUpgradeInstance.Calculate(regenerationUpgradeInstance.BaseHealing.Value * Time.deltaTime, player, regenerationUpgradeInstance.UpgradeRegister.GetLevel(player)); if (pendingHealing >= 1f) { player.playerHealth.Heal((int)Math.Floor(pendingHealing), false); pendingHealing -= Mathf.Floor(pendingHealing); } } } } public class RegenerationUpgrade : UpgradeBase<float> { public ConfigEntry<float> BaseHealing { get; protected set; } internal Dictionary<string, RegenerationComponent> Regenerations { get; set; } = new Dictionary<string, RegenerationComponent>(); public RegenerationUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float baseHealing, float priceMultiplier) : base("Regeneration", "assets/repo/mods/resources/items/items/item upgrade regeneration lib.asset", enabled, upgradeAmount, exponential, exponentialAmount, config, assetBundle, priceMultiplier, configureAmount: true, canBeExponential: true, (int?)null) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown BaseHealing = config.Bind<float>("Regeneration Upgrade", "Base Healing", baseHealing, new ConfigDescription("Base Healing Amount", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); } public override float Calculate(float value, PlayerAvatar player, int level) { return UpgradeBase<float>.DefaultCalculateFloatIncrease(this, "Regeneration", value, player, level); } } [HarmonyPatch(typeof(LevelGenerator))] public class LevelGeneratorRegenerationPatch { [HarmonyPatch("GenerateDone")] [HarmonyPostfix] private static void GenerateDonePostfix() { RegenerationUpgrade regenerationUpgradeInstance = SLRUpgradePack.RegenerationUpgradeInstance; PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; if (!((Object)(object)playerAvatarScript == (Object)null)) { SLRUpgradePack.Logger.LogInfo((object)("Adding regeneration component to " + SemiFunc.PlayerGetName(playerAvatarScript) + " (" + SemiFunc.PlayerGetSteamID(playerAvatarScript) + ")")); if (regenerationUpgradeInstance.Regenerations.TryGetValue(SemiFunc.PlayerGetSteamID(playerAvatarScript), out RegenerationComponent value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } value = ((Component)playerAvatarScript).gameObject.AddComponent<RegenerationComponent>(); value.player = playerAvatarScript; regenerationUpgradeInstance.Regenerations[SemiFunc.PlayerGetSteamID(playerAvatarScript)] = value; } } } public abstract class UpgradeBase<T> { private string _name; private string _assetName; private AssetBundle _assetBundle; public ConfigEntry<bool> UpgradeEnabled { get; protected set; } public ConfigEntry<T> UpgradeAmount { get; protected set; } public ConfigEntry<bool> UpgradeExponential { get; protected set; } public ConfigEntry<T> UpgradeExpAmount { get; protected set; } public ConfigEntry<float> PriceMultiplier { get; protected set; } public ConfigEntry<int> StartingAmount { get; protected set; } public ConfigEntry<int> MaxLevel { get; protected set; } public PlayerUpgrade UpgradeRegister { get; protected set; } protected UpgradeBase(string name, string assetName, bool enabled, T upgradeAmount, bool exponential, T exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier, bool configureAmount, bool canBeExponential, int? maxLevel) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown _name = name; _assetName = assetName; _assetBundle = assetBundle; UpgradeEnabled = config.Bind<bool>(_name + " Upgrade", "Enabled", enabled, "Should the " + _name + " Upgrade be enabled?"); PriceMultiplier = config.Bind<float>(_name + " Upgrade", "Price multiplier", priceMultiplier, "Multiplier of upgrade base price"); StartingAmount = config.Bind<int>(_name + " Upgrade", "Starting Amount", 0, new ConfigDescription("How many levels of " + _name + " to start a game with", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, maxLevel.GetValueOrDefault(100)), Array.Empty<object>())); if (configureAmount) { UpgradeAmount = config.Bind<T>(_name + " Upgrade", _name + " Upgrade Power", upgradeAmount, "How much the " + _name + " Upgrade increments"); if (canBeExponential) { UpgradeExponential = config.Bind<bool>(_name + " Upgrade", "Exponential upgrade", exponential, "Should the " + _name + " Upgrade stack exponentially?"); UpgradeExpAmount = config.Bind<T>(_name + " Upgrade", _name + " Upgrade Exponential Power", exponentialAmount, "How much the Exponential " + _name + " upgrade increments"); } } if (maxLevel.HasValue) { MaxLevel = config.Bind<int>(_name + " Upgrade", "Maximum Level", maxLevel.Value, new ConfigDescription("Maximum level", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, maxLevel.Value), Array.Empty<object>())); } if (UpgradeEnabled.Value) { RegisterUpgrade(); } UpgradeEnabled.SettingChanged += UpgradeEnabledOnSettingChanged; } private void RegisterUpgrade() { ItemContent val = _assetBundle.LoadAsset<ItemContent>(_assetName); SLRUpgradePack.Logger.LogInfo((object)$"Upgrade price range (default) {val.Prefab.item.value.valueMin} - {val.Prefab.item.value.valueMax}"); Value val2 = ScriptableObject.CreateInstance<Value>(); val2.valueMin = val.Prefab.item.value.valueMin * PriceMultiplier.Value; val2.valueMax = val.Prefab.item.value.valueMax * PriceMultiplier.Value; val.Prefab.item.value = val2; PrefabRef val3 = Items.RegisterItem(val); SLRUpgradePack.Logger.LogInfo((object)JsonUtility.ToJson((object)val3)); UpgradeRegister = Upgrades.RegisterUpgrade(_name.Replace(" ", ""), val.Prefab.item, (Action<PlayerAvatar, int>)InitUpgrade, (Action<PlayerAvatar, int>)UseUpgrade); if (MaxLevel != null) { SLRUpgradePack.LimitedUse[_name + " Upgrade"] = MaxLevel.Value; SLRUpgradePack.Logger.LogInfo((object)string.Format("{0} is limited to {1}", val3.PrefabName, SLRUpgradePack.LimitedUse[_name + " Upgrade"])); } } private void UpgradeEnabledOnSettingChanged(object sender, EventArgs e) { if (UpgradeEnabled.Value) { if (UpgradeRegister == null) { RegisterUpgrade(); } UpgradeRegister.Item.disabled = false; } else if (UpgradeRegister != null) { UpgradeRegister.Item.disabled = true; } } internal virtual void InitUpgrade(PlayerAvatar player, int level) { GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, blocking: false); if (Traverse.Create((object)player).Field<bool>("isLocal").Value) { SLRUpgradePack.Logger.LogInfo((object)("Init " + _name + ": " + string.Join(",", from kvp in UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value)))); } } internal virtual void UseUpgrade(PlayerAvatar player, int level) { if (Traverse.Create((object)player).Field<bool>("isLocal").Value) { SLRUpgradePack.Logger.LogInfo((object)("Used " + _name + ": " + string.Join(",", from kvp in UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select (SemiFunc.PlayerGetName(SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key)), kvp.Value)))); } } public abstract T Calculate(T value, PlayerAvatar player, int level); public static float DefaultCalculateFloatReduce(UpgradeBase<float> instance, string name, float value, PlayerAvatar player, int level) { if (level > 0) { if (instance.UpgradeExponential.Value) { return (float)((double)value / Math.Pow(instance.UpgradeExpAmount.Value, level)); } return value / (1f + instance.UpgradeAmount.Value * (float)level); } return value; } public static float DefaultCalculateFloatIncrease(UpgradeBase<float> instance, string name, float value, PlayerAvatar player, int level) { if (level > 0) { if (instance.UpgradeExponential.Value) { return (float)((double)value * Math.Pow(instance.UpgradeExpAmount.Value, level)); } return value * (1f + instance.UpgradeAmount.Value * (float)level); } return value; } protected GameObject GetVisualsFromComponent(Component component) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown GameObject val = null; if (((object)component).GetType() == typeof(EnemyParent)) { EnemyParent val2 = (EnemyParent)(object)((component is EnemyParent) ? component : null); Enemy val3 = (Enemy)AccessTools.Field(typeof(EnemyParent), "Enemy").GetValue(component); try { val = ((Component)val2.EnableObject.gameObject.GetComponentInChildren<Animator>()).gameObject; } catch { } if ((Object)(object)val == (Object)null) { try { val = ((Component)((Component)val3).GetComponent<EnemyVision>().VisionTransform).gameObject; } catch { } } if ((Object)(object)val == (Object)null) { val = ((Component)val3).gameObject; } } else if (((object)component).GetType() == typeof(PlayerAvatar)) { val = ((Component)((PlayerAvatar)((component is PlayerAvatar) ? component : null)).playerAvatarVisuals).gameObject; } return val; } } [Serializable] public class NetworkMessage { public string? PlayerId { get; set; } public int? PhotonId { get; set; } public static byte[] ToByteArray(NetworkMessage msg) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); binaryFormatter.Serialize(memoryStream, msg); return memoryStream.ToArray(); } public static NetworkMessage FromByteArray(byte[] bytes) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(bytes); return (NetworkMessage)binaryFormatter.Deserialize(serializationStream); } } public class EnumeratorWrapper : IEnumerable { public IEnumerator enumerator; public Action? prefixAction; public Action? postfixAction; public Action<object>? preItemAction; public Action<object>? postItemAction; public Func<object, object>? itemAction; IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { prefixAction?.Invoke(); while (enumerator.MoveNext()) { object item = enumerator.Current; preItemAction?.Invoke(item); if (itemAction != null) { yield return itemAction(item); } else { yield return item; } postItemAction?.Invoke(item); } postfixAction?.Invoke(); } } [HarmonyPatch(typeof(StatsManager), "FetchPlayerUpgrades")] public class StatsManagerPatch { private static bool Prefix(StatsManager __instance, ref string _steamID, ref Dictionary<string, int> __result) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); Regex regex = new Regex("(?<!^)(?=[A-Z])"); foreach (KeyValuePair<string, Dictionary<string, int>> dictionaryOfDictionary in __instance.dictionaryOfDictionaries) { if (!dictionaryOfDictionary.Key.StartsWith("playerUpgrade") || !dictionaryOfDictionary.Value.ContainsKey(_steamID)) { continue; } string text = ""; string[] array = regex.Split(dictionaryOfDictionary.Key); bool flag = false; string[] array2 = array; foreach (string text2 in array2) { if (flag) { text = text + text2 + " "; } if (text2 == "Upgrade") { flag = true; } } text = text.Replace("Modded", "").Trim(); if (text.Length != 0) { int num = dictionaryOfDictionary.Value[_steamID]; if (dictionary.TryGetValue(text, out var value)) { SLRUpgradePack.Logger.LogWarning((object)$"Duplicate upgrade found [{text}: {value} => {num}]"); } dictionary[text] = num; } } __result = dictionary; return false; } } [HarmonyPatch(typeof(ItemUpgrade), "PlayerUpgrade")] [HarmonyPriority(800)] public class ItemUpgradePatch { private static FieldRef<ItemUpgrade, ItemToggle>? _itemToggleRef = AccessTools.FieldRefAccess<ItemUpgrade, ItemToggle>("itemToggle"); private static FieldRef<ItemToggle, int>? _playerTogglePhotonIdRef = AccessTools.FieldRefAccess<ItemToggle, int>("playerTogglePhotonID"); private static FieldRef<ItemUpgrade, ItemAttributes>? _itemAttributesRef = AccessTools.FieldRefAccess<ItemUpgrade, ItemAttributes>("itemAttributes"); private static bool Prefix(ItemUpgrade __instance) { PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(_playerTogglePhotonIdRef.Invoke(_itemToggleRef.Invoke(__instance))); string itemName = _itemAttributesRef.Invoke(__instance).item.itemName; SLRUpgradePack.Logger.LogInfo((object)("Looking for " + itemName + " in " + string.Join(",", SLRUpgradePack.LimitedUse))); if (SLRUpgradePack.LimitedUse.TryGetValue(itemName, out var value)) { int level = SLRUpgradePack.InventorySlotUpgradeInstance.UpgradeRegister.GetLevel(val); SLRUpgradePack.Logger.LogInfo((object)$"Checking for level limit for {SemiFunc.PlayerGetName(val)}:{itemName} => {level} < {value}"); return level < value; } return true; } } [HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")] public class ShopManagerSingleUsePatch { private static void Prefix(ShopManager __instance) { foreach (Item value2 in StatsManager.instance.itemDictionary.Values) { if (SLRUpgradePack.LimitedUse.TryGetValue(value2.itemName, out var value)) { value2.maxPurchaseAmount = GameDirector.instance.PlayerList.Count * value; } } } private static void Postfix(ShopManager __instance) { __instance.potentialItemUpgrades.RemoveAll((Item item) => item.disabled); } } public class ValuableDensityUpgrade : UpgradeBase<float> { public List<AnimationCurve> TotalMaxAmountCurves { get; set; } public List<AnimationCurve> TotalMaxValueCurves { get; set; } public List<AnimationCurve> TinyCurves { get; set; } public List<AnimationCurve> SmallCurves { get; set; } public List<AnimationCurve> MediumCurves { get; set; } public List<AnimationCurve> BigCurves { get; set; } public List<AnimationCurve> WideCurves { get; set; } public List<AnimationCurve> TallCurves { get; set; } public List<AnimationCurve> VeryTallCurves { get; set; } public ValuableDensityUpgrade(bool enabled, float upgradeAmount, bool exponential, float exponentialAmount, ConfigFile config, AssetBundle assetBundle, float priceMultiplier) : base("Valuable Density", "assets/repo/mods/resources/items/items/item upgrade valuable density 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>.DefaultCalculateFloatIncrease(this, "ValuableDensity", value, player, level); } } [HarmonyPatch(typeof(LevelGenerator), "Start")] public class LevelGeneratorPatch { private delegate float difficultyDelegate(); private static bool initialized; private static void Prefix(LevelGenerator __instance) { ValuableDensityUpgrade valuableDensityUpgrade = SLRUpgradePack.ValuableDensityUpgradeInstance; if (!SemiFunc.IsMasterClientOrSingleplayer() || !valuableDensityUpgrade.UpgradeEnabled.Value) { return; } SLRUpgradePack.Logger.LogInfo((object)"Valuable Density Upgrade runs HERE"); if (!initialized) { valuableDensityUpgrade.TinyCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tinyMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.SmallCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "smallMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.MediumCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "mediumMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.BigCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "bigMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.WideCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "wideMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.TallCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tallMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.VeryTallCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "veryTallMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.TotalMaxAmountCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxAmountCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); valuableDensityUpgrade.TotalMaxValueCurves = (from re in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxValueCurve", 10) select re.Invoke(ValuableDirector.instance)).ToList(); initialized = true; } List<difficultyDelegate> staticNumberedMethodDelegates = GetStaticNumberedMethodDelegates<difficultyDelegate>(typeof(SemiFunc), "RunGetDifficultyMultiplier", Array.Empty<Type>(), 10); foreach (string item in valuableDensityUpgrade.TotalMaxAmountCurves.Zip(staticNumberedMethodDelegates, (AnimationCurve curve, difficultyDelegate difficulty) => $"Probably applying valuable density upgrade to {curve.Evaluate(difficulty())}")) { SLRUpgradePack.Logger.LogInfo((object)item); } Traverse val = Traverse.Create((object)ValuableDirector.instance).Field("totalMaxAmount"); if (valuableDensityUpgrade.UpgradeRegister != null && valuableDensityUpgrade.UpgradeRegister.PlayerDictionary != null) { int totalLevels = (from kvp in valuableDensityUpgrade.UpgradeRegister.PlayerDictionary where (Object)(object)SemiFunc.PlayerAvatarGetFromSteamID(kvp.Key) != (Object)null select kvp.Value).Sum(); if (valuableDensityUpgrade.TotalMaxAmountCurves.Count != 0) { SLRUpgradePack.Logger.LogInfo((object)"Replacing Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item2 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item2.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TotalMaxAmountCurves[item2.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } } else { SLRUpgradePack.Logger.LogInfo((object)"Setting Max Amount"); val.SetValue((object)(int)Math.Ceiling(valuableDensityUpgrade.Calculate(val.GetValue<int>(), null, totalLevels))); } if (valuableDensityUpgrade.TotalMaxValueCurves.Count != 0) { SLRUpgradePack.Logger.LogInfo((object)"Replacing Max Value curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item3 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "totalMaxValueCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item3.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TotalMaxValueCurves[item3.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } } SLRUpgradePack.Logger.LogInfo((object)"Replacing Tiny Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item4 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tinyMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item4.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TinyCurves[item4.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } SLRUpgradePack.Logger.LogInfo((object)"Replacing Small Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item5 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "smallMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item5.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.SmallCurves[item5.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } SLRUpgradePack.Logger.LogInfo((object)"Replacing Medium Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item6 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "mediumMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item6.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.MediumCurves[item6.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } SLRUpgradePack.Logger.LogInfo((object)"Replacing Big Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item7 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "bigMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item7.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.BigCurves[item7.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } SLRUpgradePack.Logger.LogInfo((object)"Replacing Wide Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item8 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "wideMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item8.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.WideCurves[item8.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } SLRUpgradePack.Logger.LogInfo((object)"Replacing Tall Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item9 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "tallMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item9.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.TallCurves[item9.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } SLRUpgradePack.Logger.LogInfo((object)"Replacing Very Tall Max Amount curve"); foreach (Tuple<Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>, int> item10 in from value in GetNumberedFieldRefs<ValuableDirector, AnimationCurve>(ValuableDirector.instance, "veryTallMaxAmountCurve", 10).Zip(staticNumberedMethodDelegates, Tuple.Create<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate>).Select((Tuple<FieldRef<ValuableDirector, AnimationCurve>, difficultyDelegate> value, int index) => Tuple.Create(value, index)) where value.Item1.Item1 != null && value.Item1.Item2 != null select value) { item10.Item1.Item1.Invoke(ValuableDirector.instance) = ReplaceCurve(valuableDensityUpgrade.VeryTallCurves[item10.Item2], (float value) => valuableDensityUpgrade.Calculate(value, null, totalLevels)); } } SLRUpgradePack.Logger.LogDebug((object)$"Total max items: {val.GetValue<int>()}"); } private static AnimationCurve ReplaceCurve(AnimationCurve target, Func<float, float> calculate) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) AnimationCurve val = new AnimationCurve(); val.CopyFrom(target); val.ClearKeys(); Keyframe[] keys = target.GetKeys(); for (int i = 0; i < keys.Length; i++) { Keyframe val2 = keys[i]; Keyframe val3 = val2; ((Keyframe)(ref val3)).value = calculate(((Keyframe)(ref val2)).value); Keyframe val4 = val3; SLRUpgradePack.Logger.LogDebug((object)$"Increased step at {((Keyframe)(ref val4)).time} from {((Keyframe)(ref val2)).value} to {((Keyframe)(ref val4)).value}"); val.AddKey(val4); } return val; } private static List<FieldRef<S, T>> GetNumberedFieldRefs<S, T>(S source, string expectedBaseName, int checkMax, int checkMin = 0) { List<FieldRef<S, T>> list = new List<FieldRef<S, T>>(); if (Traverse.Create((object)source).Field(expectedBaseName).FieldExists()) { list.Add(AccessTools.FieldRefAccess<S, T>(expectedBaseName)); } for (int i = checkMin; i < checkMax; i++) { if (Traverse.Create((object)source).Field(expectedBaseName + i).FieldExists()) { list.Add(AccessTools.FieldRefAccess<S, T>(expectedBaseName + i)); } } return list; } private static List<T> GetNumberedMethodDelegates<S, T>(S source, string expectedBaseName, Type[] parameters, int checkMax, int checkMin = 0) where T : Delegate { List<T> list = new List<T>(); if (Traverse.Create((object)source).Method(expectedBaseName, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(typeof(S), expectedBaseName, parameters, (Type[])null), (object)source, true)); } for (int i = checkMin; i < checkMax; i++) { if (Traverse.Create((object)source).Method(expectedBaseName + i, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(typeof(S), expectedBaseName + i, parameters, (Type[])null), (object)source, true)); } } return list; } private static List<T> GetStaticNumberedMethodDelegates<T>(Type source, string expectedBaseName, Type[] parameters, int checkMax, int checkMin = 0) where T : Delegate { List<T> list = new List<T>(); if (Traverse.Create(source).Method(expectedBaseName, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(source, expectedBaseName, parameters, (Type[])null), (object)source, true)); } for (int i = checkMin; i < checkMax; i++) { if (Traverse.Create(source).Method(expectedBaseName + i, parameters, (object[])null).MethodExists()) { list.Add(AccessTools.MethodDelegate<T>(AccessTools.Method(source, expectedBaseName + i, parameters, (Type[])null), (object)source, true)); } } return list; } } } namespace SLRUpgradePack.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] public class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] public static ResourceManager ResourceManager { get { if (object.Equals(null, resourceMan)) { resourceMan = new ResourceManager("SLRUpgradePack.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] public static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } public static byte[] slr_assets => (byte[])ResourceManager.GetObject("slr_assets", resourceCulture); internal Resources() { } } }