using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Extensions;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using MoreMountains.Tools;
using MoreUpgrades.Menu;
using Steamworks;
using TMPro;
using TryConnect;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 MoreUpgrades
{
public class ExtraDailyTimeUpgrade : Upgrade
{
public const float SecondsPerUse = 30f;
private static readonly FieldRef<Upgrade, TextMeshPro> ValueTextField = AccessTools.FieldRefAccess<Upgrade, TextMeshPro>("valueText");
private bool _hasBeenUsed;
private void Start()
{
TextMeshPro val = ValueTextField.Invoke((Upgrade)(object)this);
if ((Object)(object)val != (Object)null)
{
((TMP_Text)val).text = $"+{30f:0.#}s";
}
}
protected override void OnUseItem(bool isPressed)
{
if (!_hasBeenUsed)
{
_hasBeenUsed = true;
if (((NetworkBehaviour)this).isServer)
{
((MonoBehaviour)this).StartCoroutine(UseRoutine());
}
}
}
private IEnumerator UseRoutine()
{
yield return (object)new WaitForSecondsRealtime(0.5f);
GameManager val = Object.FindFirstObjectByType<GameManager>();
if ((Object)(object)val != (Object)null)
{
GameUpgradeState.ShareAcrossLobby(GamePlayerUpgradeType.ExtraDailyTime, 30f);
GrantExtraTime(val, 30f);
PluginMain.Log.LogInfo((object)$"Extra Time granted +{30f}s of day duration (state={val.state}).");
}
else
{
PluginMain.Log.LogWarning((object)"Extra Time: no GameManager found — skipping.");
}
((ConsumableItem)this).DestroyItem();
}
internal static void GrantExtraTime(GameManager gameManager, float seconds)
{
if (NetworkServer.active && !((Object)(object)gameManager == (Object)null) && !(seconds <= 0f))
{
gameManager.Network_dayDuration += seconds;
}
}
public override bool Weaved()
{
return true;
}
}
public class GameFlavoredUpgrade : Upgrade
{
private static readonly FieldRef<Upgrade, Animator> AnimField = AccessTools.FieldRefAccess<Upgrade, Animator>("anim");
private static readonly FieldRef<Upgrade, SFXComponent> UpgradeSfxField = AccessTools.FieldRefAccess<Upgrade, SFXComponent>("upgradeSfx");
private static readonly FieldRef<Upgrade, TextMeshPro> ValueTextField = AccessTools.FieldRefAccess<Upgrade, TextMeshPro>("valueText");
[SerializeField]
private GamePlayerUpgradeType _upgradeType;
[SerializeField]
private float _amount;
[SerializeField]
private bool _configured;
private bool _hasBeenUsed;
protected GamePlayerUpgradeType UpgradeType => _upgradeType;
protected float Amount => _amount;
public void Configure(GamePlayerUpgradeType upgradeType, float amount)
{
_upgradeType = upgradeType;
_amount = amount;
_configured = true;
}
private void Start()
{
TextMeshPro val = ValueTextField.Invoke((Upgrade)(object)this);
if ((Object)(object)val != (Object)null)
{
((TMP_Text)val).text = (_amount * 100f).ToString("0.#") + "%";
}
}
protected override void OnUseItem(bool isPressed)
{
if (!_hasBeenUsed && _configured)
{
_hasBeenUsed = true;
Animator val = AnimField.Invoke((Upgrade)(object)this);
if ((Object)(object)val != (Object)null)
{
val.SetTrigger("Use");
}
if (((NetworkBehaviour)this).isServer)
{
((MonoBehaviour)this).StartCoroutine(UseRoutine());
}
}
}
private IEnumerator UseRoutine()
{
yield return (object)new WaitForSecondsRealtime(0.5f);
PlayerProfile[] array = Object.FindObjectsByType<PlayerProfile>((FindObjectsSortMode)0);
foreach (PlayerProfile val in array)
{
GameUpgradeState.Add(val.steamId, _upgradeType, _amount);
RpcUpgradeChanged(val.steamId, _upgradeType, GameUpgradeState.Get(val.steamId, _upgradeType));
}
PluginMain.Log.LogInfo((object)$"Granted {_upgradeType} +{_amount} to the lobby.");
SFXComponent val2 = UpgradeSfxField.Invoke((Upgrade)(object)this);
if ((Object)(object)val2 != (Object)null)
{
val2.RpcPlayOneShotWith3DPos();
}
((ConsumableItem)this).DestroyItem();
}
[ClientRpc]
private void RpcUpgradeChanged(ulong steamId, GamePlayerUpgradeType type, float newTotal)
{
UpgradeHudSync.OnUpgradeChanged(steamId, type, newTotal);
}
public override bool Weaved()
{
return true;
}
}
public enum GamePlayerUpgradeType
{
SlotsLuck,
RouletteLuck,
WheelLuck,
BlackjackLuck,
PokerLuck,
BaccaratLuck,
CrapsLuck,
MinesweeperLuck,
CrashLuck,
PlinkoLuck,
KenoLuck,
HiLoLuck,
DuckRaceLuck,
CrossyRoadLuck,
CoinFlipLuck,
ExtraShopItems,
ExtraDailyTime
}
internal static class GameTypeMap
{
private static readonly Dictionary<CasinoGameType, GamePlayerUpgradeType> Map = new Dictionary<CasinoGameType, GamePlayerUpgradeType>
{
[(CasinoGameType)12] = GamePlayerUpgradeType.SlotsLuck,
[(CasinoGameType)11] = GamePlayerUpgradeType.RouletteLuck,
[(CasinoGameType)9] = GamePlayerUpgradeType.WheelLuck,
[(CasinoGameType)13] = GamePlayerUpgradeType.WheelLuck,
[(CasinoGameType)0] = GamePlayerUpgradeType.BlackjackLuck,
[(CasinoGameType)14] = GamePlayerUpgradeType.PokerLuck,
[(CasinoGameType)16] = GamePlayerUpgradeType.BaccaratLuck,
[(CasinoGameType)1] = GamePlayerUpgradeType.CrapsLuck,
[(CasinoGameType)8] = GamePlayerUpgradeType.MinesweeperLuck,
[(CasinoGameType)5] = GamePlayerUpgradeType.MinesweeperLuck,
[(CasinoGameType)2] = GamePlayerUpgradeType.CrashLuck,
[(CasinoGameType)10] = GamePlayerUpgradeType.PlinkoLuck,
[(CasinoGameType)7] = GamePlayerUpgradeType.KenoLuck,
[(CasinoGameType)4] = GamePlayerUpgradeType.HiLoLuck,
[(CasinoGameType)6] = GamePlayerUpgradeType.DuckRaceLuck,
[(CasinoGameType)3] = GamePlayerUpgradeType.CrossyRoadLuck,
[(CasinoGameType)15] = GamePlayerUpgradeType.CoinFlipLuck
};
public static GamePlayerUpgradeType? ToUpgrade(CasinoGameType gameType)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (!Map.TryGetValue(gameType, out var value))
{
return null;
}
return value;
}
}
[Serializable]
public sealed class GameUpgradeSaveData
{
[Serializable]
public sealed class PlayerEntry
{
public string steamId = "";
public List<ValueEntry> upgrades = new List<ValueEntry>();
}
[Serializable]
public sealed class ValueEntry
{
public GamePlayerUpgradeType type;
public float value;
}
public List<PlayerEntry> players = new List<PlayerEntry>();
}
internal static class GameUpgradeState
{
private static readonly ConcurrentDictionary<ulong, ConcurrentDictionary<GamePlayerUpgradeType, float>> Values = new ConcurrentDictionary<ulong, ConcurrentDictionary<GamePlayerUpgradeType, float>>();
public static float Get(ulong steamId, GamePlayerUpgradeType type)
{
if (Values.TryGetValue(steamId, out ConcurrentDictionary<GamePlayerUpgradeType, float> value) && value.TryGetValue(type, out var value2))
{
return value2;
}
return 0f;
}
public static void Add(ulong steamId, GamePlayerUpgradeType type, float amount)
{
Values.GetOrAdd(steamId, (ulong _) => new ConcurrentDictionary<GamePlayerUpgradeType, float>()).AddOrUpdate(type, amount, (GamePlayerUpgradeType _, float existing) => existing + amount);
}
public static void Set(ulong steamId, GamePlayerUpgradeType type, float value)
{
Values.GetOrAdd(steamId, (ulong _) => new ConcurrentDictionary<GamePlayerUpgradeType, float>())[type] = value;
}
public static void ShareAcrossLobby(GamePlayerUpgradeType type, float amount)
{
PlayerProfile[] array = Object.FindObjectsByType<PlayerProfile>((FindObjectsSortMode)0);
for (int i = 0; i < array.Length; i++)
{
Add(array[i].steamId, type, amount);
}
}
public static void ResetAll()
{
Values.Clear();
}
public static IEnumerable<(ulong SteamId, GamePlayerUpgradeType Type, float Value)> All()
{
foreach (KeyValuePair<ulong, ConcurrentDictionary<GamePlayerUpgradeType, float>> kvp in Values)
{
foreach (KeyValuePair<GamePlayerUpgradeType, float> item in kvp.Value)
{
yield return (SteamId: kvp.Key, Type: item.Key, Value: item.Value);
}
}
}
}
internal static class ItemDescriptionRegistry
{
private static readonly ConcurrentDictionary<int, string> DescriptionsBySpawnableId = new ConcurrentDictionary<int, string>();
private static readonly ConcurrentDictionary<int, string> NamesBySpawnableId = new ConcurrentDictionary<int, string>();
public static void Register(int spawnableId, string displayName, string description)
{
NamesBySpawnableId[spawnableId] = displayName;
DescriptionsBySpawnableId[spawnableId] = description;
}
public static bool TryGetDescription(int spawnableId, out string description)
{
return DescriptionsBySpawnableId.TryGetValue(spawnableId, out description);
}
public static bool TryGetName(int spawnableId, out string name)
{
return NamesBySpawnableId.TryGetValue(spawnableId, out name);
}
}
internal static class ItemRegistrar
{
private readonly struct OddsUpgradeDefinition
{
public readonly string Key;
public readonly string DisplayName;
public readonly string GameLabel;
public readonly GamePlayerUpgradeType UpgradeType;
public readonly Color Tint;
public OddsUpgradeDefinition(string key, string displayName, string gameLabel, GamePlayerUpgradeType upgradeType, Color tint)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
Key = key;
DisplayName = displayName;
GameLabel = gameLabel;
UpgradeType = upgradeType;
Tint = tint;
}
}
private const float DefaultOddsBoost = 0.15f;
private const string ScrollBundlePath = "Assets/moreupgrades.scroll";
private const string ScrollVisualPrefabName = "scroll";
private static readonly Vector3 ScrollVisualScale = new Vector3(0.8f, 0.8f, 1.15f);
private const string PillsBundlePath = "Assets/moreupgrades.pills";
private const string PillsVisualPrefabName = "pills";
private static readonly Vector3 PillsVisualScale = Vector3.one * 0.32f;
private static readonly Vector3 PillsVisualEulerAngles = new Vector3(0f, -180f, 0f);
private static readonly OddsUpgradeDefinition[] OddsUpgrades = new OddsUpgradeDefinition[15]
{
new OddsUpgradeDefinition("slots_luck", "Slots Luck", "Slots", GamePlayerUpgradeType.SlotsLuck, HsvColor(0f, 0.85f, 0.9f)),
new OddsUpgradeDefinition("roulette_reader", "Roulette Reader", "Roulette", GamePlayerUpgradeType.RouletteLuck, HsvColor(24f, 0.9f, 0.75f)),
new OddsUpgradeDefinition("wheel_whisperer", "Wheel Whisperer", "Money Wheel and Wheel of Fortune", GamePlayerUpgradeType.WheelLuck, HsvColor(48f, 0.9f, 0.95f)),
new OddsUpgradeDefinition("card_counter", "Card Counter", "Blackjack", GamePlayerUpgradeType.BlackjackLuck, HsvColor(72f, 0.75f, 0.75f)),
new OddsUpgradeDefinition("poker_face", "Poker Face", "Poker", GamePlayerUpgradeType.PokerLuck, HsvColor(96f, 0.8f, 0.65f)),
new OddsUpgradeDefinition("baccarat_instinct", "Baccarat Instinct", "Baccarat", GamePlayerUpgradeType.BaccaratLuck, HsvColor(120f, 0.75f, 0.6f)),
new OddsUpgradeDefinition("loaded_dice", "Loaded Dice", "Craps", GamePlayerUpgradeType.CrapsLuck, HsvColor(144f, 0.85f, 0.7f)),
new OddsUpgradeDefinition("steady_hands", "Steady Hands", "Minesweeper and Dragon Tower", GamePlayerUpgradeType.MinesweeperLuck, HsvColor(168f, 0.8f, 0.75f)),
new OddsUpgradeDefinition("crash_sense", "Crash Sense", "Crash", GamePlayerUpgradeType.CrashLuck, HsvColor(192f, 0.85f, 0.9f)),
new OddsUpgradeDefinition("plinko_precision", "Plinko Precision", "Plinko", GamePlayerUpgradeType.PlinkoLuck, HsvColor(216f, 0.85f, 0.9f)),
new OddsUpgradeDefinition("keno_clairvoyance", "Keno Clairvoyance", "Keno", GamePlayerUpgradeType.KenoLuck, HsvColor(240f, 0.75f, 0.85f)),
new OddsUpgradeDefinition("hilo_hunch", "Hi-Lo Hunch", "Hi-Lo", GamePlayerUpgradeType.HiLoLuck, HsvColor(264f, 0.8f, 0.8f)),
new OddsUpgradeDefinition("duck_whisperer", "Duck Whisperer", "Duck Race", GamePlayerUpgradeType.DuckRaceLuck, HsvColor(288f, 0.85f, 0.85f)),
new OddsUpgradeDefinition("crossy_confidence", "Crossy Confidence", "Crossy Road", GamePlayerUpgradeType.CrossyRoadLuck, HsvColor(312f, 0.85f, 0.85f)),
new OddsUpgradeDefinition("coin_sense", "Coin Sense", "Coin Flip", GamePlayerUpgradeType.CoinFlipLuck, HsvColor(336f, 0.9f, 0.8f))
};
private static string DurationWord
{
get
{
if (!PluginMain.PersistentUpgradesPresent)
{
return "Boosts (for the rest of today)";
}
return "Permanently boosts";
}
}
private static Color HsvColor(float hueDegrees, float saturation, float value)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
return Color.HSVToRGB(hueDegrees / 360f, saturation, value);
}
public static void RegisterAll(BaseUnityPlugin plugin)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
SpawnableSO val = TryConnectApi.FindVanillaSpawnable<Upgrade>();
if ((Object)(object)val == (Object)null)
{
PluginMain.Log.LogError((object)"Could not find the vanilla Upgrade spawnable — no items were registered.");
return;
}
OddsUpgradeDefinition[] oddsUpgrades = OddsUpgrades;
for (int i = 0; i < oddsUpgrades.Length; i++)
{
OddsUpgradeDefinition oddsUpgradeDefinition = oddsUpgrades[i];
string description = DurationWord + " your winnings at " + oddsUpgradeDefinition.GameLabel + ".";
RegisterGameFlavoredUpgrade(plugin, val, oddsUpgradeDefinition.Key, oddsUpgradeDefinition.DisplayName, description, oddsUpgradeDefinition.UpgradeType, 0.15f, oddsUpgradeDefinition.Tint);
}
RegisterGameFlavoredUpgrade(plugin, val, "shop_scout", "Shop Scout", DurationWord + " the shop by one extra random item each day.", GamePlayerUpgradeType.ExtraShopItems, 1f, new Color(0.4f, 0.75f, 0.9f));
RegisterExtraDailyTime(plugin, val);
RegisterSecondWind(plugin, val);
}
private static void RegisterGameFlavoredUpgrade(BaseUnityPlugin plugin, SpawnableSO baseSpawnable, string key, string displayName, string description, GamePlayerUpgradeType upgradeType, float amount, Color tint)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
GameObject val = CreateScrollPrefab(plugin, baseSpawnable, key, "CustomPrefab");
GameObject val2 = CreateScrollPrefab(plugin, baseSpawnable, key, "MarkerPrefab");
TryConnectApi.SwapPrefabComponent<Upgrade, GameFlavoredUpgrade>(val).Configure(upgradeType, amount);
TryConnectApi.SwapPrefabComponent<Upgrade, GameFlavoredUpgrade>(val2).Configure(upgradeType, amount);
Register(plugin, key, displayName, description, baseSpawnable, val, val2, tint);
}
private static void RegisterExtraDailyTime(BaseUnityPlugin plugin, SpawnableSO baseSpawnable)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
Color tint = default(Color);
((Color)(ref tint))..ctor(0.95f, 0.55f, 0.75f);
GameObject val = CreateScrollPrefab(plugin, baseSpawnable, "extra_time", "CustomPrefab");
GameObject val2 = CreateScrollPrefab(plugin, baseSpawnable, "extra_time", "MarkerPrefab");
TryConnectApi.SwapPrefabComponent<Upgrade, ExtraDailyTimeUpgrade>(val);
TryConnectApi.SwapPrefabComponent<Upgrade, ExtraDailyTimeUpgrade>(val2);
string description = "Adds 30 seconds to today's gambling timer." + (PluginMain.PersistentUpgradesPresent ? " Carries over to future days too." : "");
Register(plugin, "extra_time", "Extra Time", description, baseSpawnable, val, val2, tint);
}
private static GameObject CreateScrollPrefab(BaseUnityPlugin plugin, SpawnableSO baseSpawnable, string key, string suffix)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
return CreateBundledVisualPrefab(plugin, baseSpawnable, key, suffix, "Assets/moreupgrades.scroll", "scroll", ScrollVisualScale, Vector3.zero);
}
private static GameObject CreatePillsPrefab(BaseUnityPlugin plugin, SpawnableSO baseSpawnable, string key, string suffix)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
return CreateBundledVisualPrefab(plugin, baseSpawnable, key, suffix, "Assets/moreupgrades.pills", "pills", PillsVisualScale, PillsVisualEulerAngles);
}
private static GameObject CreateBundledVisualPrefab(BaseUnityPlugin plugin, SpawnableSO baseSpawnable, string key, string suffix, string bundlePath, string visualPrefabName, Vector3 visualScale, Vector3 visualEulerAngles)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
GameObject val = TryConnectApi.CreatePrefabTemplate(baseSpawnable, key + "_" + suffix);
AssetBundle val2 = TryConnectAssetBundles.LoadRelativeToPlugin(plugin, bundlePath);
try
{
GameObject val3 = TryConnectAssetBundles.LoadAsset<GameObject>(val2, visualPrefabName);
TryConnectApi.ReplaceVisualsWithPrefab(val, val3, visualScale, true, Vector3.zero, visualEulerAngles);
return val;
}
finally
{
val2.Unload(false);
}
}
private static void RegisterSecondWind(BaseUnityPlugin plugin, SpawnableSO baseSpawnable)
{
GameObject val = CreatePillsPrefab(plugin, baseSpawnable, "second_wind", "CustomPrefab");
GameObject val2 = CreatePillsPrefab(plugin, baseSpawnable, "second_wind", "MarkerPrefab");
TryConnectApi.SwapPrefabComponent<Upgrade, SecondWindItem>(val);
TryConnectApi.SwapPrefabComponent<Upgrade, SecondWindItem>(val2);
Register(plugin, "second_wind", "Second Wind", "Regenerates one random missing body part. Single use.", baseSpawnable, val, val2, null, 4);
}
private static void Register(BaseUnityPlugin plugin, string key, string displayName, string description, SpawnableSO baseSpawnable, GameObject customPrefab, GameObject markerPrefab, Color tint)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Register(plugin, key, displayName, description, baseSpawnable, customPrefab, markerPrefab, tint, 4);
}
private static void Register(BaseUnityPlugin plugin, string key, string displayName, string description, SpawnableSO baseSpawnable, GameObject customPrefab, GameObject markerPrefab, Color? tint, int replacementChancePercent)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: 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_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_008e: 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_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
int num = TryConnectApi.GenerateSpawnableId(plugin.Info.Metadata.GUID, key);
ItemDescriptionRegistry.Register(num, displayName, description);
ApplyInteractableName(customPrefab, displayName);
ApplyInteractableName(markerPrefab, displayName);
TryConnectRegistrationResult val = TryConnectApi.RegisterCustomItem(new TryConnectItemRegistration
{
OwnerGuid = plugin.Info.Metadata.GUID,
Key = key,
SpawnableId = num,
DisplayName = displayName,
Description = description,
BaseSpawnable = baseSpawnable,
BaseItemComponentType = typeof(Upgrade),
CustomPrefab = customPrefab,
MarkerPrefab = markerPrefab,
ApplyTint = tint.HasValue,
Tint = tint.GetValueOrDefault(),
ReplacementChancePercent = replacementChancePercent,
ExtraBasePrice = 0,
ExtraFloorPrice = 0
});
PluginMain.Log.LogInfo((object)$"Registered '{key}': {val}");
TryConnectRegisteredItemInfo val2 = default(TryConnectRegisteredItemInfo);
if (TryConnectApi.TryGetRegisteredItem(num, ref val2) && (Object)(object)val2.Spawnable != (Object)null)
{
ApplySpawnableSo(customPrefab, val2.Spawnable);
ApplySpawnableSo(markerPrefab, val2.Spawnable);
}
else
{
PluginMain.Log.LogWarning((object)("'" + key + "': could not resolve the registered SpawnableSO — spawnableSo may still point at the wrong item."));
}
}
private static void ApplySpawnableSo(GameObject prefab, SpawnableSO spawnable)
{
Item component = prefab.GetComponent<Item>();
if (!((Object)(object)component == (Object)null))
{
component.spawnableSo = spawnable;
}
}
private static void ApplyInteractableName(GameObject prefab, string displayName)
{
Item component = prefab.GetComponent<Item>();
if ((Object)(object)component == (Object)null)
{
PluginMain.Log.LogWarning((object)("ApplyInteractableName: '" + ((Object)prefab).name + "' has no Item component — could not set InteractableName."));
return;
}
string interactableName = ((InteractableBase)component).InteractableName;
((InteractableBase)component).InteractableName = displayName;
PluginMain.Log.LogInfo((object)("ApplyInteractableName: '" + ((Object)prefab).name + "'.InteractableName '" + interactableName + "' -> '" + displayName + "'."));
}
}
[BepInPlugin("com.cristokos.moreupgrades", "MoreUpgrades", "1.0.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class PluginMain : BaseUnityPlugin
{
public const string PluginGuid = "com.cristokos.moreupgrades";
public const string PluginName = "MoreUpgrades";
public const string PluginVersion = "1.0.2";
private const string TryConnectGuid = "com.Try-4646.TryConnect";
internal const string PersistentUpgradesGuid = "com.cristokos.persistentupgrades";
private Harmony? _harmony;
internal static ManualLogSource Log { get; private set; }
internal static bool PersistentUpgradesPresent { get; private set; }
internal static ConfigEntry<bool> UnlockDevConsole { get; private set; }
internal static ConfigFile ConfigFile { get; private set; }
private void Awake()
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
ConfigFile = ((BaseUnityPlugin)this).Config;
UnlockDevConsole = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "UnlockDevConsole", false, "Unlocks the game's built-in dev console (spawn any item on demand) for testing. Leave off for normal play.");
PersistentUpgradesPresent = Chainloader.PluginInfos.ContainsKey("com.cristokos.persistentupgrades");
Log.LogInfo((object)(PersistentUpgradesPresent ? "PersistentUpgrades detected — MoreUpgrades upgrades will be permanent and lobby-shared." : "PersistentUpgrades not detected — MoreUpgrades upgrades will reset daily, like vanilla upgrades."));
_harmony = new Harmony("com.cristokos.moreupgrades");
PatchAllSafely(_harmony);
try
{
ItemRegistrar.RegisterAll((BaseUnityPlugin)(object)this);
}
catch (Exception arg)
{
Log.LogError((object)$"ItemRegistrar.RegisterAll threw — some or all items may not have registered: {arg}");
}
Log.LogInfo((object)"MoreUpgrades 1.0.2 initialized.");
}
private static void PatchAllSafely(Harmony harmony)
{
Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(PluginMain).Assembly);
foreach (Type type in typesFromAssembly)
{
try
{
harmony.CreateClassProcessor(type).Patch();
}
catch (Exception arg)
{
Log.LogError((object)$"Failed to patch '{type.FullName}' — that patch is disabled, everything else continues: {arg}");
}
}
}
private void OnDestroy()
{
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
public class SecondWindItem : Upgrade
{
private static readonly Random Random = new Random();
private bool _hasBeenUsed;
protected override void OnUseItem(bool isPressed)
{
if (!_hasBeenUsed)
{
_hasBeenUsed = true;
if (((NetworkBehaviour)this).isServer)
{
((MonoBehaviour)this).StartCoroutine(UseRoutine());
}
}
}
private IEnumerator UseRoutine()
{
yield return (object)new WaitForSecondsRealtime(0.5f);
GameManager val = Object.FindFirstObjectByType<GameManager>();
if ((Object)(object)val == (Object)null)
{
PluginMain.Log.LogWarning((object)"Second Wind: no GameManager found — skipping.");
}
else if ((int)val.state != 1)
{
PluginMain.Log.LogWarning((object)$"Second Wind: GameManager.state is '{val.state}', not Game — skipping.");
}
else
{
PlayerInventory networkHolder = ((Item)this).NetworkHolder;
if ((Object)(object)networkHolder == (Object)null)
{
PluginMain.Log.LogWarning((object)"Second Wind: NetworkHolder is null — skipping.");
}
else
{
PlayerOrgans component = ((Component)networkHolder).GetComponent<PlayerOrgans>();
if ((Object)(object)component == (Object)null)
{
PluginMain.Log.LogWarning((object)"Second Wind: holder has no PlayerOrgans component — skipping.");
}
else
{
RegenerateRandomMissingOrgan(component);
}
}
}
((ConsumableItem)this).DestroyItem();
}
private static void RegenerateRandomMissingOrgan(PlayerOrgans organs)
{
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
OrganManager val = Object.FindFirstObjectByType<OrganManager>();
if ((Object)(object)val == (Object)null)
{
PluginMain.Log.LogWarning((object)"Second Wind: no OrganManager found — skipping.");
return;
}
if (((NetworkBehaviour)organs).connectionToClient == null)
{
PluginMain.Log.LogWarning((object)"Second Wind: organs.connectionToClient is null — skipping.");
return;
}
if (!val.OrganData.TryGetValue(((NetworkBehaviour)organs).connectionToClient.connectionId, out var value))
{
PluginMain.Log.LogWarning((object)$"Second Wind: no OrganData entry for connectionId {((NetworkBehaviour)organs).connectionToClient.connectionId} — skipping.");
return;
}
PluginMain.Log.LogInfo((object)$"Second Wind: current organ state — leftEye={value.leftEye}, rightEye={value.rightEye}, body={value.body}, mouth={value.mouth}.");
List<OrganType> list = new List<OrganType>();
if (!value.leftEye)
{
list.Add((OrganType)0);
}
if (!value.rightEye)
{
list.Add((OrganType)1);
}
if (!value.body)
{
list.Add((OrganType)2);
}
if (!value.mouth)
{
list.Add((OrganType)3);
}
if (list.Count == 0)
{
PluginMain.Log.LogInfo((object)"Second Wind: no missing organs — nothing to regenerate.");
return;
}
OrganType val2 = list[Random.Next(list.Count)];
val.ServerToggleOrgan(organs, val2, true);
PluginMain.Log.LogInfo((object)$"Second Wind regenerated {val2}.");
}
public override bool Weaved()
{
return true;
}
}
}
namespace MoreUpgrades.Patches
{
[HarmonyPatch(typeof(SettingsLayoutRuntimeUI), "ShowTab")]
internal static class BulkToggleButtonsPatch
{
private static readonly FieldInfo? ResetEntryPrefabField = AccessTools.Field(typeof(SettingsLayoutRuntimeUI), "resetEntryPrefab");
private static readonly FieldInfo? LayoutField = AccessTools.Field(typeof(SettingsLayoutRuntimeUI), "layout");
private static readonly FieldInfo? TabContentsField = AccessTools.Field(typeof(SettingsLayoutRuntimeUI), "tabContents");
private static readonly Random Random = new Random();
private static void Postfix(SettingsLayoutRuntimeUI __instance, string tabName)
{
object? obj = LayoutField?.GetValue(__instance);
SettingsLayout val = (SettingsLayout)((obj is SettingsLayout) ? obj : null);
if (val == null || val.tabs == null)
{
return;
}
List<ToggleSettingItem> toggleEntries = (from e in val.tabs.Find((Tab t) => string.Equals(t.tabName, tabName, StringComparison.OrdinalIgnoreCase))?.entries?.OfType<ToggleSettingItem>()
where ItemToggleMenu.IsShopToggleKey(((SettingItemBase)e).key)
select e).ToList();
if (toggleEntries == null || toggleEntries.Count == 0)
{
return;
}
Transform val2 = FindContentRoot(__instance, tabName);
object? obj2 = ResetEntryPrefabField?.GetValue(__instance);
GameObject val3 = (GameObject)((obj2 is GameObject) ? obj2 : null);
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null))
{
CreateBulkButton(val3, val2, "\"MoreUpgrades\" — All On", delegate
{
SetAll(__instance, tabName, toggleEntries, enabled: true);
});
CreateBulkButton(val3, val2, "\"MoreUpgrades\" — All Off", delegate
{
SetAll(__instance, tabName, toggleEntries, enabled: false);
});
CreateBulkButton(val3, val2, "\"MoreUpgrades\" — Randomize", delegate
{
Randomize(__instance, tabName, toggleEntries);
});
}
}
private static Transform? FindContentRoot(SettingsLayoutRuntimeUI runtimeUi, string tabName)
{
if (!(TabContentsField?.GetValue(runtimeUi) is IEnumerable enumerable))
{
return null;
}
foreach (object item in enumerable)
{
FieldInfo? field = item.GetType().GetField("tabName");
FieldInfo field2 = item.GetType().GetField("contentRoot");
if (string.Equals(field?.GetValue(item) as string, tabName, StringComparison.OrdinalIgnoreCase))
{
object? obj = field2?.GetValue(item);
object? obj2 = ((obj is RectTransform) ? obj : null);
return (obj2 != null) ? ((Component)obj2).transform : null;
}
}
return null;
}
private static void CreateBulkButton(GameObject resetPrefab, Transform parent, string label, Action onClick)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
GameObject obj = Object.Instantiate<GameObject>(resetPrefab, parent);
((Object)obj).name = "MoreUpgrades_" + label;
TMP_Text componentInChildren = obj.GetComponentInChildren<TMP_Text>(true);
if ((Object)(object)componentInChildren != (Object)null)
{
componentInChildren.text = label;
}
Button componentInChildren2 = obj.GetComponentInChildren<Button>(true);
if ((Object)(object)componentInChildren2 != (Object)null)
{
((UnityEvent)componentInChildren2.onClick).AddListener((UnityAction)delegate
{
onClick();
});
}
}
private static void SetAll(SettingsLayoutRuntimeUI runtimeUi, string tabName, List<ToggleSettingItem> entries, bool enabled)
{
foreach (ToggleSettingItem entry in entries)
{
entry.value = enabled;
((SettingItemBase)entry).NotifyChanged();
}
PluginMain.Log.LogInfo((object)string.Format("MoreUpgrades: bulk-set {0} shop item(s) to {1}.", entries.Count, enabled ? "enabled" : "disabled"));
runtimeUi.ShowTab(tabName);
}
private static void Randomize(SettingsLayoutRuntimeUI runtimeUi, string tabName, List<ToggleSettingItem> entries)
{
foreach (ToggleSettingItem entry in entries)
{
entry.value = Random.Next(2) == 0;
((SettingItemBase)entry).NotifyChanged();
}
PluginMain.Log.LogInfo((object)$"MoreUpgrades: randomized {entries.Count} shop item(s)' enabled state.");
runtimeUi.ShowTab(tabName);
}
}
[HarmonyPatch(typeof(UpgradeManager), "ServerResetAllUpgradesToDefaults")]
internal static class DefaultDailyResetPatch
{
private static void Postfix()
{
if (NetworkServer.active && !PluginMain.PersistentUpgradesPresent)
{
GameUpgradeState.ResetAll();
PluginMain.Log.LogInfo((object)"Reset MoreUpgrades upgrade values for the new day (PersistentUpgrades not installed).");
}
}
}
[HarmonyPatch(typeof(NewConsole), "Start")]
internal static class DevConsoleUnlockPatch
{
private static void Postfix(NewConsole __instance)
{
if (PluginMain.UnlockDevConsole.Value && (Object)(object)__instance._devConsoleSetting != (Object)null && !__instance._devConsoleSetting.value)
{
__instance._devConsoleSetting.value = true;
PluginMain.Log.LogInfo((object)"Dev console unlocked for testing (MoreUpgrades Debug.UnlockDevConsole is enabled).");
}
}
}
[HarmonyPatch(typeof(UpgradeManager), "ServerResetAllUpgradesToDefaults")]
internal static class ExtraDailyTimeDayResetPatch
{
private static void Postfix()
{
if (!NetworkServer.active)
{
return;
}
GameManager val = Object.FindFirstObjectByType<GameManager>();
if ((Object)(object)val == (Object)null)
{
return;
}
GameSettings val2 = Resources.Load<GameSettings>("GameSettings");
float num = (val.Network_dayDuration = (((Object)(object)val2 != (Object)null) ? val2.dayDuration : 300f));
if (!PluginMain.PersistentUpgradesPresent)
{
PluginMain.Log.LogInfo((object)$"Extra Time: day duration reset to base {num}s (PersistentUpgrades not installed).");
return;
}
float num3 = 0f;
PlayerProfile[] array = Object.FindObjectsByType<PlayerProfile>((FindObjectsSortMode)0);
for (int i = 0; i < array.Length; i++)
{
float num4 = GameUpgradeState.Get(array[i].steamId, GamePlayerUpgradeType.ExtraDailyTime);
if (num4 > num3)
{
num3 = num4;
}
}
if (num3 > 0f)
{
ExtraDailyTimeUpgrade.GrantExtraTime(val, num3);
}
PluginMain.Log.LogInfo((object)$"Extra Time: day duration reset to base {num}s, then restored +{num3}s (PersistentUpgrades installed).");
}
}
internal static class ExtraShopItemSpawner
{
private static readonly Random Random = new Random();
private static readonly List<GameObject> SpawnedInstances = new List<GameObject>();
private static readonly HashSet<string> ExcludedLootTableNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Cosmetics", "MysteryBox" };
private static readonly FieldInfo? LootTableField = AccessTools.Field(typeof(ItemStamp), "lootTable");
public static void SpawnForNewDay(MonoBehaviour coroutineHost)
{
SpawnedInstances.RemoveAll((GameObject x) => (Object)(object)x == (Object)null);
Spawn(coroutineHost, "for the new day");
}
public static void RespawnForReroll(MonoBehaviour coroutineHost)
{
foreach (GameObject spawnedInstance in SpawnedInstances)
{
if ((Object)(object)spawnedInstance != (Object)null)
{
NetworkServer.Destroy(spawnedInstance);
}
}
SpawnedInstances.Clear();
Spawn(coroutineHost, "for the reroll");
}
private static void Spawn(MonoBehaviour coroutineHost, string logContext)
{
int num = Mathf.RoundToInt(HighestStackedExtraShopItems());
if (num <= 0)
{
return;
}
List<ItemStamp> list = FindShopStamps();
if (list.Count == 0)
{
PluginMain.Log.LogWarning((object)("Shop Scout: no shop ItemStamp pedestals found to spawn extra items near (" + logContext + ") — skipping."));
return;
}
List<GameObject> eligiblePrefabs = GetEligiblePrefabs(list);
if (eligiblePrefabs.Count == 0)
{
PluginMain.Log.LogWarning((object)("Shop Scout: found shop pedestals but no eligible items in their loot tables (" + logContext + ") — skipping."));
return;
}
List<Vector3> stampPositions = list.Select((ItemStamp s) => ((Component)s).transform.position).ToList();
coroutineHost.StartCoroutine(SpawnExtraItems(stampPositions, eligiblePrefabs, num, logContext));
}
private static List<ItemStamp> FindShopStamps()
{
ItemStamp[] array = Object.FindObjectsByType<ItemStamp>((FindObjectsSortMode)0);
List<ItemStamp> list = new List<ItemStamp>();
ItemStamp[] array2 = array;
foreach (ItemStamp val in array2)
{
if (!((Object)(object)val == (Object)null))
{
object? obj = LootTableField?.GetValue(val);
MMLootTableGameObjectSO val2 = (MMLootTableGameObjectSO)((obj is MMLootTableGameObjectSO) ? obj : null);
string text = (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : null);
if (text == null || !ExcludedLootTableNames.Contains(text))
{
list.Add(val);
}
}
}
return list;
}
private static List<GameObject> GetEligiblePrefabs(List<ItemStamp> shopStamps)
{
HashSet<GameObject> hashSet = new HashSet<GameObject>();
foreach (ItemStamp shopStamp in shopStamps)
{
object? obj = LootTableField?.GetValue(shopStamp);
List<MMLootGameObject> list = ((MMLootTable<MMLootGameObject, GameObject>)(object)((MMLootTableGameObjectSO)(((obj is MMLootTableGameObjectSO) ? obj : null)?)).LootTable)?.ObjectsToLoot;
if (list == null)
{
continue;
}
foreach (MMLootGameObject item in list)
{
if ((Object)(object)((MMLoot<GameObject>)(object)item)?.Loot != (Object)null)
{
hashSet.Add(((MMLoot<GameObject>)(object)item).Loot);
}
}
}
return hashSet.ToList();
}
private static IEnumerator SpawnExtraItems(List<Vector3> stampPositions, List<GameObject> eligible, int count, string logContext)
{
for (int i = 0; i < count; i++)
{
GameObject obj = eligible[Random.Next(eligible.Count)];
Vector3 val = stampPositions[Random.Next(stampPositions.Count)];
Vector3 val2 = new Vector3((float)(Random.NextDouble() * 2.0 - 1.0), 0f, (float)(Random.NextDouble() * 2.0 - 1.0)) * 0.75f;
Vector3 val3 = val + val2 + Vector3.up * 0.5f;
GameObject val4 = Object.Instantiate<GameObject>(obj, val3, Quaternion.identity);
NetworkServer.Spawn(val4, (NetworkConnectionToClient)null);
SpawnedInstances.Add(val4);
yield return (object)new WaitForSeconds(0.1f);
}
PluginMain.Log.LogInfo((object)$"Shop Scout spawned {count} extra item(s) near the shop pedestals ({logContext}).");
}
private static float HighestStackedExtraShopItems()
{
float num = 0f;
PlayerProfile[] array = Object.FindObjectsByType<PlayerProfile>((FindObjectsSortMode)0);
for (int i = 0; i < array.Length; i++)
{
float num2 = GameUpgradeState.Get(array[i].steamId, GamePlayerUpgradeType.ExtraShopItems);
if (num2 > num)
{
num = num2;
}
}
return num;
}
}
[HarmonyPatch(typeof(ItemManager), "ServerResetItems")]
internal static class ExtraShopItemDayResetPatch
{
private static void Postfix(ItemManager __instance)
{
if (NetworkServer.active)
{
ExtraShopItemSpawner.SpawnForNewDay((MonoBehaviour)(object)__instance);
}
}
}
[HarmonyPatch(typeof(ItemStampManager), "RerollAllItemStamps")]
internal static class ExtraShopItemRerollPatch
{
private static void Postfix(ItemStampManager __instance)
{
if (NetworkServer.active)
{
ExtraShopItemSpawner.RespawnForReroll((MonoBehaviour)(object)__instance);
}
}
}
[HarmonyPatch(typeof(ItemStampManager), "RetrieveAndRespawnAllItemStamps")]
internal static class ExtraShopItemRetrievePatch
{
private static void Postfix(ItemStampManager __instance)
{
if (NetworkServer.active)
{
ExtraShopItemSpawner.RespawnForReroll((MonoBehaviour)(object)__instance);
}
}
}
[HarmonyPatch(typeof(GameBase), "Payout")]
internal static class GameOddsUpgradePatch
{
private static readonly FieldRef<GameBase, PlayerProfile> InteractingPlayerRef = AccessTools.FieldRefAccess<GameBase, PlayerProfile>("interactingPlayer");
private static void Prefix(GameBase __instance, ref double multiplier)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active)
{
return;
}
GamePlayerUpgradeType? gamePlayerUpgradeType = GameTypeMap.ToUpgrade(__instance.GameType);
if (!gamePlayerUpgradeType.HasValue)
{
return;
}
PlayerProfile val = InteractingPlayerRef.Invoke(__instance);
if (!((Object)(object)val == (Object)null))
{
float num = GameUpgradeState.Get(val.steamId, gamePlayerUpgradeType.Value);
if (num != 0f)
{
multiplier *= 1.0 + (double)num;
}
}
}
}
[HarmonyPatch]
internal static class GameUpgradeSaveLoadPatch
{
private static string SaveDirectoryPath => Path.Combine(Application.persistentDataPath, "Saves");
internal static string SidecarPathFor(string saveName)
{
return Path.Combine(SaveDirectoryPath, saveName + ".moreupgrades.json");
}
[HarmonyPatch(typeof(SaveManager), "SaveGame")]
[HarmonyPostfix]
private static void AfterSaveGame(SaveManager __instance)
{
if (!NetworkServer.active || string.IsNullOrEmpty(__instance.CurrentSaveName))
{
return;
}
GameUpgradeSaveData gameUpgradeSaveData = new GameUpgradeSaveData();
Dictionary<ulong, GameUpgradeSaveData.PlayerEntry> dictionary = new Dictionary<ulong, GameUpgradeSaveData.PlayerEntry>();
foreach (var (key, type, value) in GameUpgradeState.All())
{
if (!dictionary.TryGetValue(key, out var value2))
{
GameUpgradeSaveData.PlayerEntry obj = new GameUpgradeSaveData.PlayerEntry
{
steamId = key.ToString()
};
value2 = (dictionary[key] = obj);
gameUpgradeSaveData.players.Add(value2);
}
value2.upgrades.Add(new GameUpgradeSaveData.ValueEntry
{
type = type,
value = value
});
}
try
{
if (!Directory.Exists(SaveDirectoryPath))
{
Directory.CreateDirectory(SaveDirectoryPath);
}
File.WriteAllText(SidecarPathFor(__instance.CurrentSaveName), JsonUtility.ToJson((object)gameUpgradeSaveData, true));
PluginMain.Log.LogInfo((object)$"Saved {gameUpgradeSaveData.players.Count} player(s) worth of MoreUpgrades values.");
}
catch (Exception ex)
{
PluginMain.Log.LogError((object)("Failed to save MoreUpgrades values: " + ex.Message));
}
}
[HarmonyPatch(typeof(SaveManager), "LoadGame")]
[HarmonyPostfix]
private static void AfterLoadGame(SaveManager __instance)
{
if (!NetworkServer.active || string.IsNullOrEmpty(__instance.CurrentSaveName))
{
return;
}
string path = SidecarPathFor(__instance.CurrentSaveName);
if (!File.Exists(path))
{
return;
}
try
{
GameUpgradeSaveData gameUpgradeSaveData = JsonUtility.FromJson<GameUpgradeSaveData>(File.ReadAllText(path));
if (gameUpgradeSaveData?.players == null)
{
return;
}
int num = 0;
foreach (GameUpgradeSaveData.PlayerEntry player in gameUpgradeSaveData.players)
{
if (string.IsNullOrEmpty(player.steamId) || !ulong.TryParse(player.steamId, out var result))
{
continue;
}
foreach (GameUpgradeSaveData.ValueEntry upgrade in player.upgrades)
{
GameUpgradeState.Set(result, upgrade.type, upgrade.value);
num++;
}
}
if (num > 0)
{
PluginMain.Log.LogInfo((object)$"Restored {num} MoreUpgrades value(s) from the loaded save.");
}
}
catch (Exception ex)
{
PluginMain.Log.LogError((object)("Failed to load MoreUpgrades values: " + ex.Message));
}
}
}
[HarmonyPatch(typeof(ItemDescriptionLocalization), "FetchDescription")]
internal static class ItemDescriptionLocalizationPatch
{
private static bool Prefix(int spawnableId, Action<string> onComplete, ref IEnumerator __result)
{
if (!ItemDescriptionRegistry.TryGetDescription(spawnableId, out string description))
{
return true;
}
onComplete?.Invoke(description);
__result = NoOp();
return false;
}
private static IEnumerator NoOp()
{
yield break;
}
}
[HarmonyPatch(typeof(ItemInteractLocalization), "FetchName")]
internal static class ItemNameLocalizationPatch
{
private static bool Prefix(int spawnableId, Action<string> onComplete, ref IEnumerator __result)
{
if (!ItemDescriptionRegistry.TryGetName(spawnableId, out string name))
{
return true;
}
PluginMain.Log.LogInfo((object)$"ItemNameLocalizationPatch: serving '{name}' for spawnableId {spawnableId}.");
onComplete?.Invoke(name);
__result = NoOp();
return false;
}
private static IEnumerator NoOp()
{
yield break;
}
}
[HarmonyPatch(typeof(MysteryBox), "GetRandomSpawnableByWeight")]
internal static class MysteryBoxEnforcementPatch
{
private static readonly Random Random = new Random();
private static readonly FieldInfo? SpawnableListField = AccessTools.Field(typeof(MysteryBox), "spawnableList");
private static readonly FieldInfo? SpawnableField = ResolveSpawnableEntryField();
private static void Postfix(MysteryBox __instance, ref SpawnableSO __result)
{
if ((Object)(object)__result == (Object)null || ItemEnabledState.IsEnabled(ShopCatalog.KeyForVanilla(__result.spawnableID)) || !(SpawnableListField?.GetValue(__instance) is IEnumerable enumerable))
{
return;
}
List<SpawnableSO> list = new List<SpawnableSO>();
foreach (object item in enumerable)
{
object? obj = SpawnableField?.GetValue(item);
SpawnableSO val = (SpawnableSO)((obj is SpawnableSO) ? obj : null);
if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)__result && ItemEnabledState.IsEnabled(ShopCatalog.KeyForVanilla(val.spawnableID)))
{
list.Add(val);
}
}
if (list.Count == 0)
{
PluginMain.Log.LogWarning((object)("MysteryBox: no enabled alternative to disabled item '" + __result.spawnableName + "' — spawning it anyway."));
return;
}
SpawnableSO val2 = __result;
__result = list[Random.Next(list.Count)];
PluginMain.Log.LogInfo((object)("MysteryBox: replaced disabled item '" + val2.spawnableName + "' with '" + __result.spawnableName + "'."));
}
private static FieldInfo? ResolveSpawnableEntryField()
{
FieldInfo fieldInfo = AccessTools.Field(typeof(MysteryBox), "spawnableList");
Type type = (((object)fieldInfo != null && fieldInfo.FieldType.IsGenericType) ? fieldInfo.FieldType.GetGenericArguments().FirstOrDefault() : null);
if (!(type != null))
{
return null;
}
return AccessTools.Field(type, "spawnable");
}
}
[HarmonyPatch(typeof(UpgradeManager), "ServerResetAllUpgradesToDefaults")]
internal static class PersistentModeRestorePatch
{
private static void Postfix()
{
if (NetworkServer.active && PluginMain.PersistentUpgradesPresent)
{
PluginMain.Log.LogInfo((object)"PersistentUpgrades active — MoreUpgrades values carried over the new day unchanged.");
}
}
}
[HarmonyPatch(typeof(SaveManager), "ResetCurrentSaveToDefaults")]
internal static class GameUpgradeStateResetPatch
{
private static void Prefix(SaveManager __instance)
{
if (!NetworkServer.active)
{
return;
}
GameUpgradeState.ResetAll();
if (!string.IsNullOrEmpty(__instance.CurrentSaveName))
{
try
{
string path = GameUpgradeSaveLoadPatch.SidecarPathFor(__instance.CurrentSaveName);
if (File.Exists(path))
{
File.Delete(path);
}
}
catch (Exception ex)
{
PluginMain.Log.LogError((object)("Failed to delete stale MoreUpgrades save file: " + ex.Message));
}
}
PluginMain.Log.LogInfo((object)"Cleared MoreUpgrades upgrade values for new save.");
}
}
[HarmonyPatch(typeof(SettingItemBase), "NotifyChanged")]
internal static class SettingsChangePatch
{
private static void Postfix(SettingItemBase __instance)
{
ToggleSettingItem val = (ToggleSettingItem)(object)((__instance is ToggleSettingItem) ? __instance : null);
if (val != null && ItemToggleMenu.IsShopToggleKey(((SettingItemBase)val).key))
{
string text = ItemToggleMenu.CatalogKeyFromSettingKey(((SettingItemBase)val).key);
ItemEnabledState.SetEnabled(text, val.value);
PluginMain.Log.LogInfo((object)("Shop item '" + text + "' " + (val.value ? "enabled" : "disabled") + "."));
}
}
}
[HarmonyPatch]
internal static class SettingsInjectionPatch
{
private static readonly FieldRef<LobbyModeDropdownButton, SettingsLayout> ButtonLayoutRef = AccessTools.FieldRefAccess<LobbyModeDropdownButton, SettingsLayout>("settingsLayout");
private static readonly FieldRef<SettingsLayoutRuntimeUI, SettingsLayout> RuntimeUiLayoutRef = AccessTools.FieldRefAccess<SettingsLayoutRuntimeUI, SettingsLayout>("layout");
[HarmonyPostfix]
[HarmonyPatch(typeof(LobbyModeDropdownButton), "Awake")]
private static void LobbyModeDropdownButton_Awake_Postfix(LobbyModeDropdownButton __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
SettingsLayout val = ButtonLayoutRef.Invoke(__instance);
if ((Object)(object)val != (Object)null)
{
ItemToggleMenu.EnsureInjected(val, "LobbyModeDropdownButton.Awake");
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(SettingsLayoutRuntimeUI), "Awake")]
private static void SettingsLayoutRuntimeUI_Awake_Prefix(SettingsLayoutRuntimeUI __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
SettingsLayout val = RuntimeUiLayoutRef.Invoke(__instance);
if ((Object)(object)val != (Object)null)
{
ItemToggleMenu.EnsureInjected(val, "SettingsLayoutRuntimeUI.Awake");
}
}
}
}
[HarmonyPatch(typeof(SettingsLocalization), "ApplyString")]
internal static class SettingsLabelLocalizationPatch
{
private const string KeyPrefix = "settings.label.moreupgrades.";
private static bool Prefix(TMP_Text label, string key, string fallback, ref IEnumerator __result)
{
if ((Object)(object)label == (Object)null || key == null || !key.StartsWith("settings.label.moreupgrades."))
{
return true;
}
label.text = fallback;
__result = NoOp();
return false;
}
private static IEnumerator NoOp()
{
yield break;
}
}
[HarmonyPatch(typeof(SettingsLayoutRuntimeUI), "CreateDropdownEntry")]
internal static class SettingsTooltipPatch
{
private static void Postfix(RectTransform parent, SettingItemBase entry)
{
if (entry is ToggleSettingItem && ItemToggleMenu.IsShopToggleKey(entry.key) && ((Transform)parent).childCount != 0)
{
((Component)((Transform)parent).GetChild(((Transform)parent).childCount - 1)).gameObject.AddComponent<SettingsTooltipTrigger>().Description = ItemToggleMenu.DescriptionForSettingKey(entry.key);
}
}
}
[HarmonyPatch]
internal static class ShopSpawnEnforcementPatch
{
private unsafe static void Postfix(MMLootTableGameObjectSO lootTable, Vector3 stampPosition, GameObject fallbackPrefab, ref GameObject __result)
{
if ((Object)(object)fallbackPrefab == (Object)null)
{
return;
}
PluginMain.Log.LogInfo((object)("ShopSpawnEnforcementPatch.Postfix: fallback='" + ((Object)fallbackPrefab).name + "' result='" + (((Object)(object)__result != (Object)null) ? ((Object)__result).name : "null") + "'."));
if ((Object)(object)__result != (Object)null && (Object)(object)__result != (Object)(object)fallbackPrefab)
{
GameObject rolledPrefab = __result;
TryConnectRegisteredItemInfo val = ((IEnumerable<TryConnectRegisteredItemInfo>)TryConnectApi.GetRegisteredItems()).FirstOrDefault((Func<TryConnectRegisteredItemInfo, bool>)((TryConnectRegisteredItemInfo i) => i.IsRegistered && (Object)(object)i.Spawnable != (Object)null && (Object)(object)i.Spawnable.prefab == (Object)(object)rolledPrefab));
if (val != null && !ItemEnabledState.IsEnabled(ShopCatalog.KeyForMod(val.OwnerGuid, val.Key)))
{
__result = fallbackPrefab;
}
}
else if (IsDisabledVanillaItem(fallbackPrefab))
{
List<(string, string, GameObject, bool)> list = (from r in TryConnectInternals.GetReplacements(fallbackPrefab)
where r.IsEnabled
select r).ToList();
if (list.Count != 0)
{
string text = (((Object)(object)lootTable != (Object)null) ? ((Object)lootTable).name : "ItemStamp");
Random random = new Random((((object)(*(Vector3*)(&stampPosition))/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ (text.GetHashCode() * 31 + ((Object)fallbackPrefab).name.GetHashCode()));
(string, string, GameObject, bool) tuple = list[random.Next(list.Count)];
__result = tuple.Item3;
PluginMain.Log.LogInfo((object)("GetShopReplacement's roll missed every registered item for '" + ((Object)fallbackPrefab).name + "' — forced enabled replacement '" + tuple.Item2 + "' instead of the disabled vanilla fallback."));
}
}
}
private static bool IsDisabledVanillaItem(GameObject prefab)
{
SpawnableSettings val = Resources.Load<SpawnableSettings>("SpawnableSettings");
if (val?.spawnables == null)
{
return false;
}
foreach (SpawnableSO spawnable in val.spawnables)
{
if ((Object)(object)spawnable != (Object)null && (Object)(object)spawnable.prefab == (Object)(object)prefab)
{
return !ItemEnabledState.IsEnabled(ShopCatalog.KeyForVanilla(spawnable.spawnableID));
}
}
return false;
}
private static MethodBase? TargetMethod()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
if (assembly.GetName().Name.Contains("TryConnect"))
{
Type type = assembly.GetType("TryConnect.RuntimeItemRegistry");
if (type != null)
{
return AccessTools.Method(type, "GetShopReplacement", (Type[])null, (Type[])null);
}
}
}
PluginMain.Log.LogWarning((object)"ShopSpawnEnforcementPatch: could not find TryConnect.RuntimeItemRegistry.GetShopReplacement — the shop item toggle menu will no longer be able to block disabled mod items from spawning. This usually means an incompatible TryConnect update; everything else in this mod is unaffected.");
return null;
}
}
[HarmonyPatch(typeof(UpgradeManager), "UserCode_RpcClearUpgradeUI")]
internal static class UpgradeHudClearPatch
{
private static void Postfix()
{
if (!PluginMain.PersistentUpgradesPresent)
{
UpgradeHudSync.Clear();
}
}
}
[HarmonyPatch(typeof(ItemStampManager), "GetUniqueLoot", new Type[]
{
typeof(MMLootTableGameObjectSO),
typeof(Vector3)
})]
internal static class VanillaShopEnforcementPatch
{
[HarmonyPriority(0)]
private static void Postfix(ItemStampManager __instance, MMLootTableGameObjectSO lootTable, Vector3 stampPosition, ref GameObject __result)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active || (Object)(object)__result == (Object)null || ((MMLootTable<MMLootGameObject, GameObject>)(object)lootTable?.LootTable)?.ObjectsToLoot == null)
{
return;
}
if (!TryDescribeFinalResult(__result, out string description, out bool isEnabled))
{
PluginMain.Log.LogInfo((object)("VanillaShopEnforcementPatch: '" + ((Object)__result).name + "' is not a recognized vanilla or mod catalog entry — skipping enforcement."));
return;
}
PluginMain.Log.LogInfo((object)$"VanillaShopEnforcementPatch: final pick '{description}' isEnabled={isEnabled}.");
if (!isEnabled)
{
GameObject val = PickEnabledAlternative(lootTable, stampPosition, __result);
if ((Object)(object)val != (Object)null)
{
__result = val;
PluginMain.Log.LogInfo((object)("Replaced disabled item '" + description + "' with '" + ((Object)val).name + "' in the shop."));
}
else
{
PluginMain.Log.LogWarning((object)("Loot table '" + ((Object)lootTable).name + "' has no enabled alternative to '" + description + "' — spawning it anyway."));
}
}
}
private static bool TryDescribeFinalResult(GameObject result, out string description, out bool isEnabled)
{
if (BuildVanillaLookup().TryGetValue(result, out SpawnableSO value))
{
description = $"{value.spawnableName} (id={value.spawnableID})";
isEnabled = ItemEnabledState.IsEnabled(ShopCatalog.KeyForVanilla(value.spawnableID));
return true;
}
TryConnectRegisteredItemInfo[] registeredItems = TryConnectApi.GetRegisteredItems();
foreach (TryConnectRegisteredItemInfo val in registeredItems)
{
if (val.IsRegistered && (Object)(object)val.Spawnable != (Object)null && (Object)(object)val.Spawnable.prefab == (Object)(object)result)
{
description = val.DisplayName;
isEnabled = ItemEnabledState.IsEnabled(ShopCatalog.KeyForMod(val.OwnerGuid, val.Key));
return true;
}
}
description = string.Empty;
isEnabled = false;
return false;
}
private static Dictionary<GameObject, SpawnableSO> BuildVanillaLookup()
{
Dictionary<GameObject, SpawnableSO> dictionary = new Dictionary<GameObject, SpawnableSO>();
SpawnableSettings val = Resources.Load<SpawnableSettings>("SpawnableSettings");
if (val?.spawnables == null)
{
return dictionary;
}
foreach (SpawnableSO spawnable in val.spawnables)
{
if ((Object)(object)spawnable != (Object)null && (Object)(object)spawnable.prefab != (Object)null && !dictionary.ContainsKey(spawnable.prefab))
{
dictionary[spawnable.prefab] = spawnable;
}
}
return dictionary;
}
private unsafe static GameObject? PickEnabledAlternative(MMLootTableGameObjectSO lootTable, Vector3 stampPosition, GameObject excluded)
{
Dictionary<GameObject, SpawnableSO> dictionary = BuildVanillaLookup();
List<GameObject> list = new List<GameObject>();
foreach (MMLootGameObject item in ((MMLootTable<MMLootGameObject, GameObject>)(object)lootTable.LootTable).ObjectsToLoot)
{
if ((Object)(object)((MMLoot<GameObject>)(object)item)?.Loot == (Object)null || (Object)(object)((MMLoot<GameObject>)(object)item).Loot == (Object)(object)excluded)
{
continue;
}
if (!dictionary.TryGetValue(((MMLoot<GameObject>)(object)item).Loot, out var value))
{
list.Add(((MMLoot<GameObject>)(object)item).Loot);
continue;
}
if (ItemEnabledState.IsEnabled(ShopCatalog.KeyForVanilla(value.spawnableID)))
{
list.Add(((MMLoot<GameObject>)(object)item).Loot);
continue;
}
(string, string, GameObject, bool) tuple = TryConnectInternals.GetReplacements(((MMLoot<GameObject>)(object)item).Loot).FirstOrDefault<(string, string, GameObject, bool)>(((string OwnerGuid, string Key, GameObject MarkerPrefab, bool IsEnabled) r) => r.IsEnabled);
if ((Object)(object)tuple.Item3 != (Object)null)
{
list.Add(tuple.Item3);
}
}
if (list.Count == 0)
{
return null;
}
SeededRandomManager val = Object.FindFirstObjectByType<SeededRandomManager>();
GameManager val2 = Object.FindFirstObjectByType<GameManager>();
int num = (((Object)(object)val != (Object)null) ? val.CurrentSeed : 0);
int num2 = (((Object)(object)val2 != (Object)null) ? val2.successfulQuota : 0);
Random random = new Random((((object)(*(Vector3*)(&stampPosition))/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ (num * 31 + num2));
return list[random.Next(list.Count)];
}
}
}
namespace MoreUpgrades.Menu
{
internal static class ItemEnabledState
{
private const string ConfigSection = "ShopItems";
private const string ConfigDescription = "Whether this shop item can appear in the shop. Set via the in-game settings menu.";
private static readonly ConcurrentDictionary<string, ConfigEntry<bool>> Entries = new ConcurrentDictionary<string, ConfigEntry<bool>>();
public static bool IsEnabled(string catalogToggleKey)
{
return GetEntry(catalogToggleKey).Value;
}
public static void SetEnabled(string catalogToggleKey, bool isEnabled)
{
GetEntry(catalogToggleKey).Value = isEnabled;
}
public static bool HasSavedValue(string catalogToggleKey)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if (Entries.ContainsKey(catalogToggleKey))
{
return true;
}
return PluginMain.ConfigFile.ContainsKey(new ConfigDefinition("ShopItems", SanitizeConfigKey(catalogToggleKey)));
}
private static ConfigEntry<bool> GetEntry(string catalogToggleKey)
{
return Entries.GetOrAdd(catalogToggleKey, (Func<string, ConfigEntry<bool>>)((string key) => PluginMain.ConfigFile.Bind<bool>("ShopItems", SanitizeConfigKey(key), true, "Whether this shop item can appear in the shop. Set via the in-game settings menu.")));
}
private static string SanitizeConfigKey(string key)
{
return key.Replace('=', '_');
}
}
internal static class ItemToggleMenu
{
private const string HeaderKey = "moreupgrades.section";
private const string StatusKey = "moreupgrades.status";
private const string ToggleKeyPrefix = "moreupgrades.toggle.";
private const string NoDescriptionFallback = "No description available.";
private static readonly HashSet<string> DefaultDisabledCatalogKeys = new HashSet<string> { ShopCatalog.KeyForMod("com.Try-4646.TryConnect", "ticket_fizz") };
private static readonly Dictionary<string, string> DescriptionsBySettingKey = new Dictionary<string, string>();
private static string StatusLabel
{
get
{
if (!PluginMain.PersistentUpgradesPresent)
{
return "\"PersistentUpgrades\" not installed — upgrades from \"MoreUpgrades\" reset each day.";
}
return "\"PersistentUpgrades\" detected — upgrades from \"MoreUpgrades\" are permanent and lobby-shared.";
}
}
public static string SettingKeyFor(string catalogToggleKey)
{
return "moreupgrades.toggle." + catalogToggleKey;
}
public static bool IsShopToggleKey(string? key)
{
return key?.StartsWith("moreupgrades.toggle.") ?? false;
}
public static string CatalogKeyFromSettingKey(string settingKey)
{
return settingKey.Substring("moreupgrades.toggle.".Length);
}
public static string DescriptionForSettingKey(string settingKey)
{
if (!DescriptionsBySettingKey.TryGetValue(settingKey, out string value))
{
return "No description available.";
}
return value;
}
public static bool EnsureInjected(SettingsLayout layout, string source)
{
if ((Object)(object)layout == (Object)null || layout.tabs == null || layout.tabs.Count == 0)
{
return false;
}
Tab val = FindTargetTab(layout);
if (val == null)
{
return false;
}
Tab val2 = val;
if (val2.entries == null)
{
val2.entries = new List<SettingItemBase>();
}
int num = 0;
num += EnsureTitleEntry(val.entries, "moreupgrades.section", "\"MoreUpgrades\" — Shop Items");
num += EnsureTitleEntry(val.entries, "moreupgrades.status", StatusLabel);
RefreshStatusLabel(val.entries);
foreach (ShopCatalogEntry item in ShopCatalog.GetAll())
{
string key = SettingKeyFor(item.ToggleKey);
DescriptionsBySettingKey[key] = (string.IsNullOrWhiteSpace(item.Description) ? "No description available." : item.Description);
if (!ItemEnabledState.HasSavedValue(item.ToggleKey) && DefaultDisabledCatalogKeys.Contains(item.ToggleKey))
{
ItemEnabledState.SetEnabled(item.ToggleKey, isEnabled: false);
}
bool defaultEnabled = ItemEnabledState.IsEnabled(item.ToggleKey);
bool flag = EnsureToggleEntry(val.entries, key, item.DisplayName, defaultEnabled) > 0;
num += (flag ? 1 : 0);
}
if (num > 0)
{
PluginMain.Log.LogInfo((object)$"Injected {num} MoreUpgrades settings entries from {source}. Tab='{val.tabName}'.");
}
return true;
}
private static Tab? FindTargetTab(SettingsLayout layout)
{
foreach (Tab tab in layout.tabs)
{
if (tab.entries != null && tab.entries.Any(IsLobbyModeEntry))
{
return tab;
}
}
foreach (Tab tab2 in layout.tabs)
{
if (tab2.entries != null && tab2.entries.Count != 0 && !string.IsNullOrWhiteSpace(tab2.tabName) && string.Equals(tab2.tabName.Trim(), "Settings", StringComparison.OrdinalIgnoreCase))
{
return tab2;
}
}
return null;
}
private static bool IsLobbyModeEntry(SettingItemBase entry)
{
if (!(entry is DropdownSettingItem) || entry.key == "moreupgrades.section")
{
return false;
}
return string.Equals(entry.label?.Trim(), "Lobby Mode", StringComparison.OrdinalIgnoreCase);
}
private static void RefreshStatusLabel(ICollection<SettingItemBase> entries)
{
TitleSettingItem val = entries.OfType<TitleSettingItem>().FirstOrDefault((Func<TitleSettingItem, bool>)((TitleSettingItem entry) => ((SettingItemBase)entry).key == "moreupgrades.status"));
if ((Object)(object)val != (Object)null)
{
((SettingItemBase)val).label = StatusLabel;
}
}
private static int EnsureTitleEntry(ICollection<SettingItemBase> entries, string key, string label)
{
if (entries.Any((SettingItemBase entry) => entry.key == key))
{
return 0;
}
TitleSettingItem val = ScriptableObject.CreateInstance<TitleSettingItem>();
((Object)val).hideFlags = (HideFlags)61;
((SettingItemBase)val).key = key;
((SettingItemBase)val).label = label;
entries.Add((SettingItemBase)(object)val);
return 1;
}
private static int EnsureToggleEntry(ICollection<SettingItemBase> entries, string key, string label, bool defaultEnabled)
{
if (entries.Any((SettingItemBase entry) => entry.key == key))
{
return 0;
}
ToggleSettingItem val = ScriptableObject.CreateInstance<ToggleSettingItem>();
((Object)val).hideFlags = (HideFlags)61;
((SettingItemBase)val).key = key;
((SettingItemBase)val).label = label;
val.value = defaultEnabled;
val.defaultValue = defaultEnabled;
val.loadOnSceneStart = false;
entries.Add((SettingItemBase)(object)val);
return 1;
}
}
internal static class SettingsTooltip
{
private const float MaxWidth = 420f;
private const float Padding = 10f;
private const float CursorOffset = 36f;
private static Canvas? _canvas;
private static RectTransform? _root;
private static TextMeshProUGUI? _text;
public static void Show(string message, TMP_FontAsset? fontToMatch, Vector2 screenPosition)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
EnsureBuilt(fontToMatch);
if (!((Object)(object)_text == (Object)null) && !((Object)(object)_root == (Object)null))
{
((TMP_Text)_text).text = message;
((Component)_root).gameObject.SetActive(true);
SetPosition(screenPosition);
}
}
public static void Hide()
{
if ((Object)(object)_root != (Object)null)
{
((Component)_root).gameObject.SetActive(false);
}
}
public static void SetPosition(Vector2 screenPosition)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_root == (Object)null) && ((Component)_root).gameObject.activeSelf)
{
((Transform)_root).position = new Vector3(screenPosition.x + 36f, screenPosition.y + 36f, 0f);
}
}
private static void EnsureBuilt(TMP_FontAsset? fontToMatch)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00d4: 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_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: 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_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_root != (Object)null)
{
if ((Object)(object)fontToMatch != (Object)null && (Object)(object)_text != (Object)null)
{
((TMP_Text)_text).font = fontToMatch;
}
return;
}
GameObject val = new GameObject("MoreUpgrades_TooltipCanvas");
Object.DontDestroyOnLoad((Object)(object)val);
_canvas = val.AddComponent<Canvas>();
_canvas.renderMode = (RenderMode)0;
_canvas.sortingOrder = 32767;
val.AddComponent<CanvasScaler>();
((Behaviour)val.AddComponent<GraphicRaycaster>()).enabled = false;
GameObject val2 = new GameObject("MoreUpgrades_Tooltip", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
val2.transform.SetParent(val.transform, false);
_root = (RectTransform)val2.transform;
_root.pivot = new Vector2(0f, 1f);
_root.sizeDelta = new Vector2(420f, 40f);
Image component = val2.GetComponent<Image>();
((Graphic)component).color = new Color(0.05f, 0.05f, 0.06f, 0.95f);
((Graphic)component).raycastTarget = false;
GameObject val3 = new GameObject("Text", new Type[2]
{
typeof(RectTransform),
typeof(TextMeshProUGUI)
});
val3.transform.SetParent(val2.transform, false);
RectTransform val4 = (RectTransform)val3.transform;
val4.anchorMin = Vector2.zero;
val4.anchorMax = Vector2.one;
val4.offsetMin = new Vector2(10f, 10f);
val4.offsetMax = new Vector2(-10f, -10f);
_text = val3.GetComponent<TextMeshProUGUI>();
((TMP_Text)_text).fontSize = 22f;
((Graphic)_text).color = Color.white;
((TMP_Text)_text).textWrappingMode = (TextWrappingModes)1;
((Graphic)_text).raycastTarget = false;
if ((Object)(object)fontToMatch != (Object)null)
{
((TMP_Text)_text).font = fontToMatch;
}
ContentSizeFitter obj = val2.AddComponent<ContentSizeFitter>();
obj.horizontalFit = (FitMode)0;
obj.verticalFit = (FitMode)2;
((Component)_text).GetComponent<RectTransform>().sizeDelta = new Vector2(400f, 0f);
val2.SetActive(false);
}
}
internal sealed class SettingsTooltipTrigger : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerMoveHandler, IPointerExitHandler
{
public string? Description { get; set; }
private void Awake()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
Graphic componentInChildren = ((Component)this).GetComponentInChildren<Graphic>(true);
if (componentInChildren == null || !componentInChildren.raycastTarget)
{
((Graphic)((Component)this).gameObject.AddComponent<Image>()).color = Color.clear;
}
}
public void OnPointerEnter(PointerEventData eventData)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (!string.IsNullOrWhiteSpace(Description))
{
TMP_Text componentInChildren = ((Component)this).GetComponentInChildren<TMP_Text>(true);
TMP_FontAsset fontToMatch = ((componentInChildren != null) ? componentInChildren.font : null);
SettingsTooltip.Show(Description, fontToMatch, eventData.position);
}
}
public void OnPointerMove(PointerEventData eventData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
SettingsTooltip.SetPosition(eventData.position);
}
public void OnPointerExit(PointerEventData eventData)
{
SettingsTooltip.Hide();
}
private void OnDisable()
{
SettingsTooltip.Hide();
}
}
internal readonly struct ShopCatalogEntry
{
public readonly string ToggleKey;
public readonly string DisplayName;
public readonly string Description;
public readonly SpawnableSO Spawnable;
public readonly bool IsVanilla;
public ShopCatalogEntry(string toggleKey, string displayName, string description, SpawnableSO spawnable, bool isVanilla)
{
ToggleKey = toggleKey;
DisplayName = displayName;
Description = description;
Spawnable = spawnable;
IsVanilla = isVanilla;
}
}
internal static class ShopCatalog
{
private const string VanillaKeyPrefix = "vanilla.";
private const string ModKeyPrefix = "mod.";
public static string KeyForVanilla(int spawnableId)
{
return "vanilla." + spawnableId;
}
public static string KeyForMod(string ownerGuid, string itemKey)
{
return "mod." + ownerGuid + ":" + itemKey;
}
public static bool IsVanillaKey(string toggleKey)
{
return toggleKey.StartsWith("vanilla.");
}
public static bool TryParseVanillaSpawnableId(string toggleKey, out int spawnableId)
{
if (IsVanillaKey(toggleKey) && int.TryParse(toggleKey.Substring("vanilla.".Length), out spawnableId))
{
return true;
}
spawnableId = 0;
return false;
}
public static IReadOnlyList<ShopCatalogEntry> GetAll()
{
List<ShopCatalogEntry> list = new List<ShopCatalogEntry>();
HashSet<int> hashSet = new HashSet<int>();
ItemDescriptionSettings descriptionSettings = Resources.Load<ItemDescriptionSettings>("ItemDescriptionSettings");
TryConnectRegisteredItemInfo[] registeredItems = TryConnectApi.GetRegisteredItems();
foreach (TryConnectRegisteredItemInfo val in registeredItems)
{
if (val.IsRegistered && !((Object)(object)val.Spawnable == (Object)null))
{
hashSet.Add(val.SpawnableId);
string description = ResolveDescription(descriptionSettings, val.Spawnable, val.Description);
list.Add(new ShopCatalogEntry(KeyForMod(val.OwnerGuid, val.Key), val.DisplayName, description, val.Spawnable, isVanilla: false));
}
}
SpawnableSettings val2 = Resources.Load<SpawnableSettings>("SpawnableSettings");
if (val2?.spawnables != null)
{
foreach (SpawnableSO spawnable in val2.spawnables)
{
if (!((Object)(object)spawnable == (Object)null) && !((Object)(object)spawnable.prefab == (Object)null) && !hashSet.Contains(spawnable.spawnableID) && !((Object)(object)spawnable.prefab.GetComponent<Item>() == (Object)null))
{
hashSet.Add(spawnable.spawnableID);
string displayName = (string.IsNullOrWhiteSpace(spawnable.spawnableName) ? ((Object)spawnable.prefab).name : spawnable.spawnableName);
string description2 = ResolveDescription(descriptionSettings, spawnable, spawnable.spawnableDescription);
list.Add(new ShopCatalogEntry(KeyForVanilla(spawnable.spawnableID), displayName, description2, spawnable, isVanilla: true));
}
}
}
return list.OrderBy((ShopCatalogEntry e) => e.DisplayName).ToList();
}
private static string ResolveDescription(ItemDescriptionSettings? descriptionSettings, SpawnableSO spawnable, string fallback)
{
string text = (((Object)(object)descriptionSettings != (Object)null) ? descriptionSettings.GetDescription(spawnable) : null);
if (!string.IsNullOrWhiteSpace(text))
{
return text;
}
return fallback;
}
}
internal static class TryConnectInternals
{
private static readonly Type? RuntimeItemRegistryType = FindType("TryConnect.RuntimeItemRegistry");
private static readonly FieldInfo? DefinitionsByBasePrefabField = RuntimeItemRegistryType?.GetField("DefinitionsByBasePrefab", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly Type? CustomItemDefinitionType = RuntimeItemRegistryType?.GetNestedType("CustomItemDefinition", BindingFlags.NonPublic);
private static readonly FieldInfo? OwnerGuidField = CustomItemDefinitionType?.GetField("OwnerGuid", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly FieldInfo? KeyField = CustomItemDefinitionType?.GetField("Key", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly FieldInfo? MarkerPrefabField = CustomItemDefinitionType?.GetField("MarkerPrefab", BindingFlags.Instance | BindingFlags.NonPublic);
private static Type? FindType(string fullName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type type = assemblies[i].GetType(fullName);
if (type != null)
{
return type;
}
}
return null;
}
public static IReadOnlyList<(string OwnerGuid, string Key, GameObject MarkerPrefab, bool IsEnabled)> GetReplacements(GameObject basePrefab)
{
try
{
if (DefinitionsByBasePrefabField == null || OwnerGuidField == null || KeyField == null || MarkerPrefabField == null)
{
return Array.Empty<(string, string, GameObject, bool)>();
}
if (!(DefinitionsByBasePrefabField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(basePrefab) || !(dictionary[basePrefab] is IEnumerable enumerable))
{
return Array.Empty<(string, string, GameObject, bool)>();
}
List<(string, string, GameObject, bool)> list = new List<(string, string, GameObject, bool)>();
foreach (object item2 in enumerable)
{
string text = OwnerGuidField.GetValue(item2) as string;
string text2 = KeyField.GetValue(item2) as string;
object? value = MarkerPrefabField.GetValue(item2);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if (text != null && text2 != null && !((Object)(object)val == (Object)null))
{
bool item = ItemEnabledState.IsEnabled(ShopCatalog.KeyForMod(text, text2));
list.Add((text, text2, val, item));
}
}
return list;
}
catch (Exception ex)
{
PluginMain.Log.LogWarning((object)("TryConnectInternals.GetReplacements: reflection into TryConnect internals failed: " + ex.Message));
return Array.Empty<(string, string, GameObject, bool)>();
}
}
public static bool HasEnabledReplacement(GameObject basePrefab)
{
return GetReplacements(basePrefab).Any<(string, string, GameObject, bool)>(((string OwnerGuid, string Key, GameObject MarkerPrefab, bool IsEnabled) r) => r.IsEnabled);
}
}
internal static class UpgradeHudSync
{
private static readonly Dictionary<GamePlayerUpgradeType, UpgradeEntryUI> Entries = new Dictionary<GamePlayerUpgradeType, UpgradeEntryUI>();
private static readonly Dictionary<GamePlayerUpgradeType, float> LastKnownTotals = new Dictionary<GamePlayerUpgradeType, float>();
private static Transform? _lastEntryParent;
private static readonly Dictionary<GamePlayerUpgradeType, (string Label, string Description)> Display = new Dictionary<GamePlayerUpgradeType, (string, string)>
{
[GamePlayerUpgradeType.SlotsLuck] = ("Slots Luck", "Boosts winnings at Slots"),
[GamePlayerUpgradeType.RouletteLuck] = ("Roulette Reader", "Boosts winnings at Roulette"),
[GamePlayerUpgradeType.WheelLuck] = ("Wheel Whisperer", "Boosts winnings at Money Wheel and Wheel of Fortune"),
[GamePlayerUpgradeType.BlackjackLuck] = ("Card Counter", "Boosts winnings at Blackjack"),
[GamePlayerUpgradeType.PokerLuck] = ("Poker Face", "Boosts winnings at Poker"),
[GamePlayerUpgradeType.BaccaratLuck] = ("Baccarat Instinct", "Boosts winnings at Baccarat"),
[GamePlayerUpgradeType.CrapsLuck] = ("Loaded Dice", "Boosts winnings at Craps"),
[GamePlayerUpgradeType.MinesweeperLuck] = ("Steady Hands", "Boosts winnings at Minesweeper and Dragon Tower"),
[GamePlayerUpgradeType.CrashLuck] = ("Crash Sense", "Boosts winnings at Crash"),
[GamePlayerUpgradeType.PlinkoLuck] = ("Plinko Precision", "Boosts winnings at Plinko"),
[GamePlayerUpgradeType.KenoLuck] = ("Keno Clairvoyance", "Boosts winnings at Keno"),
[GamePlayerUpgradeType.HiLoLuck] = ("Hi-Lo Hunch", "Boosts winnings at Hi-Lo"),
[GamePlayerUpgradeType.DuckRaceLuck] = ("Duck Whisperer", "Boosts winnings at Duck Race"),
[GamePlayerUpgradeType.CrossyRoadLuck] = ("Crossy Confidence", "Boosts winnings at Crossy Road"),
[GamePlayerUpgradeType.CoinFlipLuck] = ("Coin Sense", "Boosts winnings at Coin Flip"),
[GamePlayerUpgradeType.ExtraShopItems] = ("Shop Scout", "Adds extra items to the shop")
};
public static void OnUpgradeChanged(ulong steamId, GamePlayerUpgradeType type, float newTotal)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (SteamUser.GetSteamID().m_SteamID != steamId)
{
return;
}
if (newTotal <= 0f)
{
LastKnownTotals.Remove(type);
}
else
{
LastKnownTotals[type] = newTotal;
}
UpgradeUI instance = MonoSingleton<UpgradeUI>.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
Transform val = UpgradeUiAccess.EntryParent(instance);
UpgradeEntryUI val2 = UpgradeUiAccess.EntryTemplate(instance);
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
return;
}
if (_lastEntryParent != val)
{
Entries.Clear();
_lastEntryParent = val;
foreach (var (gamePlayerUpgradeType2, newTotal2) in LastKnownTotals)
{
if (gamePlayerUpgradeType2 != type)
{
Draw(val, val2, gamePlayerUpgradeType2, newTotal2);
}
}
}
if (newTotal <= 0f)
{
if (Entries.TryGetValue(type, out UpgradeEntryUI value) && (Object)(object)value != (Object)null)
{
Object.Destroy((Object)(object)((Component)value).gameObject);
}
Entries.Remove(type);
}
else
{
Draw(val, val2, type, newTotal);
}
}
private static void Draw(Transform parent, UpgradeEntryUI template, GamePlayerUpgradeType type, float newTotal)
{
if (Display.TryGetValue(type, out (string, string) value))
{
if (!Entries.TryGetValue(type, out UpgradeEntryUI value2) || (Object)(object)value2 == (Object)null)
{
value2 = Object.Instantiate<UpgradeEntryUI>(template, parent);
Entries[type] = value2;
}
string formattedValue = ((type == GamePlayerUpgradeType.ExtraShopItems) ? $"+{newTotal:0.#}" : ((newTotal * 100f).ToString("0.#") + "%"));
UpgradeEntryUiText.Set(value2, value.Item1, value.Item2, formattedValue);
}
}
public static void Clear()
{
foreach (UpgradeEntryUI value in Entries.Values)
{
if ((Object)(object)value != (Object)null)
{
Object.Destroy((Object)(object)((Component)value).gameObject);
}
}
Entries.Clear();
LastKnownTotals.Clear();
}
}
internal static class UpgradeUiAccess
{
private static readonly FieldRef<UpgradeUI, Transform> EntryParentField = AccessTools.FieldRefAccess<UpgradeUI, Transform>("entryParent");
private static readonly FieldRef<UpgradeUI, UpgradeEntryUI> EntryTemplateField = AccessTools.FieldRefAccess<UpgradeUI, UpgradeEntryUI>("upgradeEntryUI");
public static Transform EntryParent(UpgradeUI ui)
{
return UpgradeHudScroll.EnsureScrollable(EntryParentField.Invoke(ui));
}
public static UpgradeEntryUI EntryTemplate(UpgradeUI ui)
{
return EntryTemplateField.Invoke(ui);
}
}
internal static class UpgradeHudScroll
{
private const float VisibleHeight = 548.4f;
private const float ScrollbarWidth = 12f;
private static Transform? _wrappedSource;
private static Transform? _scrollableParent;
public static Transform EnsureScrollable(Transform entryParent)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Expected O, but got Unknown
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_024d: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Expected O, but got Unknown
//IL_025b: Unknown result type (might be due to invalid IL or missing references)
//IL_0262: Expected O, but got Unknown
//IL_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_028e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
//IL_031a: Unknown result type (might be due to invalid IL or missing references)
//IL_031f: Unknown result type (might be due to invalid IL or missing references)
//IL_0325: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Expected O, but got Unknown
//IL_0338: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_0350: Unknown result type (might be due to invalid IL or missing references)
//IL_0377: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_wrappedSource == (Object)(object)entryParent && (Object)(object)_scrollableParent != (Object)null)
{
return _scrollableParent;
}
Transform parent = entryParent.parent;
RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
Transform val2 = ((val != null) ? ((Transform)val).parent : null);
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
return entryParent;
}
int siblingIndex = ((Transform)val).GetSiblingIndex();
float x = val.sizeDelta.x;
GameObject val3 = new GameObject("MoreUpgrades_UpgradeScrollViewport", new Type[1] { typeof(RectTransform) });
RectTransform val4 = (RectTransform)val3.transform;
((Transform)val4).SetParent(val2, false);
((Transform)val4).SetSiblingIndex(siblingIndex);
val4.anchorMin = val.anchorMin;
val4.anchorMax = val.anchorMax;
val4.pivot = val.pivot;
val4.anchoredPosition = val.anchoredPosition;
val4.sizeDelta = new Vector2(x + 4f + 12f, 548.4f);
GameObject val5 = new GameObject("MoreUpgrades_UpgradeScrollMask", new Type[3]
{
typeof(RectTransform),
typeof(RectMask2D),
typeof(Image)
});
RectTransform val6 = (RectTransform)val5.transform;
((Transform)val6).SetParent((Transform)(object)val4, false);
val6.anchorMin = new Vector2(0f, 0f);
val6.anchorMax = new Vector2(0f, 1f);
val6.pivot = new Vector2(0f, 1f);
val6.anchoredPosition = Vector2.zero;
val6.sizeDelta = new Vector2(x, 0f);
Image component = val5.GetComponent<Image>();
((Graphic)component).color = new Color(0f, 0f, 0f, 0f);
((Graphic)component).raycastTarget = true;
((Transform)val).SetParent((Transform)(object)val6, false);
val.anchorMin = new Vector2(0f, 1f);
val.anchorMax = new Vector2(0f, 1f);
val.pivot = new Vector2(0f, 1f);
val.anchoredPosition = Vector2.zero;
GameObject val7 = new GameObject("MoreUpgrades_UpgradeScrollbar", new Type[3]
{
typeof(RectTransform),
typeof(Image),
typeof(Scrollbar)
});
RectTransform val8 = (RectTransform)val7.transform;
((Transform)val8).SetParent((Transform)(object)val4, false);
val8.anchorMin = new Vector2(1f, 0f);
val8.anchorMax = new Vector2(1f, 1f);
val8.pivot = new Vector2(1f, 1f);
val8.sizeDelta = new Vector2(12f, 0f);
val8.anchoredPosition = Vector2.zero;
((Graphic)val7.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.15f);
GameObject val9 = new GameObject("Handle", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
RectTransform val10 = (RectTransform)val9.transform;
((Transform)val10).SetParent((Transform)(object)val8, false);
val10.anchorMin = Vector2.zero;
val10.anchorMax = Vector2.one;
val10.sizeDelta = Vector2.zero;
Image component2 = val9.GetComponent<Image>();
((Graphic)component2).color = new Color(1f, 1f, 1f, 0.6f);
Scrollbar component3 = val7.GetComponent<Scrollbar>();
component3.direction = (Direction)2;
((Selectable)component3).targetGraphic = (Graphic)(object)component2;
component3.handleRect = val10;
ScrollRect val11 = val3.AddComponent<ScrollRect>();
val11.content = val;
val11.viewport = val6;
val11.horizontal = false;
val11.vertical = true;
val11.verticalScrollbar = component3;
val11.verticalScrollbarVisibility = (ScrollbarVisibility)1;
val11.movementType = (MovementType)2;
val11.scrollSensitivity = 20f;
val3.AddComponent<UpgradeHudWheelScroll>().Target = val11;
_wrappedSource = entryParent;
_scrollableParent = entryParent;
return entryParent;
}
}
internal sealed class UpgradeHudWheelScroll : MonoBehaviour
{
private const float PixelsPerRawUnit = 64.05f;
public ScrollRect? Target;
private void Update()
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Target == (Object)null || !((Component)Target.content).gameObject.activeInHierarchy)
{
return;
}
Mouse current = Mouse.current;
float num = ((current != null) ? ((InputControl<float>)(object)((Vector2Control)current.scroll).y).ReadValue() : 0f);
if (num != 0f)
{
Rect rect = Target.content.rect;
float height = ((Rect)(ref rect)).height;
rect = Target.viewport.rect;
float num2 = height - ((Rect)(ref rect)).height;
if (!(num2 <= 0f))
{
float num3 = num * 64.05f;
Target.verticalNormalizedPosition = Mathf.Clamp01(Target.verticalNormalizedPosition + num3 / num2);
}
}
}
}
internal static class UpgradeEntryUiText
{
private static readonly FieldRef<UpgradeEntryUI, TextMeshProUGUI> LabelField = AccessTools.FieldRefAccess<UpgradeEntryUI, TextMeshProUGUI>("labelText");
private static readonly FieldRef<UpgradeEntryUI, TextMeshProUGUI> DescriptionField = AccessTools.FieldRefAccess<UpgradeEntryUI, TextMeshProUGUI>("descriptionText");
private static readonly FieldRef<UpgradeEntryUI, TextMeshProUGUI> ValueField = AccessTools.FieldRefAccess<UpgradeEntryUI, TextMeshProUGUI>("valueText");
public static void Set(UpgradeEntryUI entry, string label, string description, string formattedValue)
{
TextMeshProUGUI val = LabelField.Invoke(entry);
if ((Object)(object)val != (Object)null)
{
((TMP_Text)val).text = label;
}
TextMeshProUGUI val2 = DescriptionField.Invoke(entry);
if ((Object)(object)val2 != (Object)null)
{
((TMP_Text)val2).text = description;
}
TextMeshProUGUI val3 = ValueField.Invoke(entry);
if ((Object)(object)val3 != (Object)null)
{
((TMP_Text)val3).text = formattedValue;
}
}
}
}