using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet; using FishNet.Broadcast; using FishNet.Connection; using FishNet.Object; using FishNet.Object.Synchronizing; using FishNet.Serializing; using FishNet.Transporting; using HarmonyLib; using Microsoft.CodeAnalysis; using SpongeMods.Core; using SpongeMods.ModMenu; using SpongeMods.UILib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("FishNet.Runtime")] [assembly: AssemblyCompany("SpongeMods")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Fish size variation and a personal catch record.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a149c533da6d929b7267867242f5011f9c2152dc")] [assembly: AssemblyProduct("SpongeMods.FishermansTally")] [assembly: AssemblyTitle("SpongeMods.FishermansTally")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SpongeMods.FishermansTally { internal sealed class Bench : Interactable { public override void Interact(Player player) { ((Interactable)this).Interact(player); if ((Object)(object)player == (Object)(object)Player.LocalPlayer) { Plugin.OpenBench(); } } } internal static class BenchBuilder { private static GameObject _bench; public static void Sync() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!Guest.BenchPlaced || !Plugin.BenchEnabled.Value) { Clear(); return; } Clear(); _bench = Build(Guest.BenchAt, Guest.BenchYaw); } public static void Clear() { if ((Object)(object)_bench != (Object)null) { Object.Destroy((Object)(object)_bench); } _bench = null; } public static bool AimPoint(out Vector3 point, out float yaw) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; yaw = 0f; Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.Transform == (Object)null) { return false; } Transform transform = localPlayer.Transform; Vector3 val = transform.position + transform.forward * Plugin.PlaceDistance.Value; Vector3 val2 = val + Vector3.up * 2f; RaycastHit val3 = default(RaycastHit); point = (Physics.Raycast(val2, Vector3.down, ref val3, 8f, LayerMask.op_Implicit(GameInfo.LevelLayer)) ? ((RaycastHit)(ref val3)).point : val); yaw = transform.eulerAngles.y; return true; } private static GameObject Build(Vector3 at, float yaw) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SpongeMods.RodBench"); val.SetActive(false); val.transform.SetPositionAndRotation(at, Quaternion.Euler(0f, yaw, 0f)); Material material = BorrowMaterial(); GameObject val2 = Slab(val.transform, new Vector3(0f, 0.92f, 0f), new Vector3(1.5f, 0.12f, 0.7f), material); GameObject val3 = Slab(val.transform, new Vector3(-0.62f, 0.43f, -0.25f), new Vector3(0.12f, 0.86f, 0.12f), material); GameObject val4 = Slab(val.transform, new Vector3(0.62f, 0.43f, -0.25f), new Vector3(0.12f, 0.86f, 0.12f), material); GameObject val5 = Slab(val.transform, new Vector3(-0.62f, 0.43f, 0.25f), new Vector3(0.12f, 0.86f, 0.12f), material); GameObject val6 = Slab(val.transform, new Vector3(0.62f, 0.43f, 0.25f), new Vector3(0.12f, 0.86f, 0.12f), material); BoxCollider val7 = val.AddComponent(); val7.center = new Vector3(0f, 0.5f, 0f); val7.size = new Vector3(1.6f, 1f, 0.8f); Bench bench = val.AddComponent(); ((Interactable)bench)._interactCol = (Collider)(object)val7; ((Interactable)bench)._modelsToOutline = (GameObject[])(object)new GameObject[5] { val2, val3, val4, val5, val6 }; GameObject val8 = new GameObject("TextTarget"); val8.transform.SetParent(val.transform, false); val8.transform.localPosition = new Vector3(0f, 1.25f, 0f); ((Interactable)bench)._textTarget = val8.transform; Tag(val, "Interactable"); int num = LayerMask.NameToLayer("Interactable"); if (num >= 0) { val.layer = num; } val.SetActive(true); return val; } private static GameObject Slab(Transform parent, Vector3 at, Vector3 size, Material material) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Piece"; Collider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } val.transform.SetParent(parent, false); val.transform.localPosition = at; val.transform.localScale = size; if ((Object)(object)material != (Object)null) { MeshRenderer component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).sharedMaterial = material; } } return val; } private static Material BorrowMaterial() { MeshRenderer[] array = Object.FindObjectsByType((FindObjectsInactive)0); foreach (MeshRenderer val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)val).sharedMaterial != (Object)null && (Object)(object)((Renderer)val).sharedMaterial.shader != (Object)null) { return ((Renderer)val).sharedMaterial; } } return null; } private static void Tag(GameObject target, string tag) { try { target.tag = tag; } catch (UnityException) { Plugin.Log.LogWarning((object)("The '" + tag + "' tag is missing, so the bench cannot be used.")); } } } internal enum BenchAsk : byte { Place, Remove, BuyLuck, BuyValue } internal struct CatchReport : IBroadcast { public string Species; public float Weight; public int Worth; } internal struct BoardEntry { public ulong SteamId; public string Angler; public string Species; public float Weight; public int Worth; } internal struct BoardUpdate : IBroadcast { public BoardEntry[] Entries; } internal struct BenchAskMessage : IBroadcast { public byte Ask; public float X; public float Y; public float Z; public float Yaw; } internal struct BenchStateMessage : IBroadcast { public bool Placed; public float X; public float Y; public float Z; public float Yaw; public byte LuckTier; public byte ValueTier; } internal sealed class Wire : Link { private const int MaxEntries = 64; private const int MaxText = 64; public static readonly Wire Instance = new Wire(); protected override void Describe() { Link.Describe((Action)delegate(Writer writer, CatchReport value) { writer.WriteString(value.Species); writer.WriteSingle(value.Weight); writer.WriteInt32(value.Worth); }, (Func)((Reader reader) => new CatchReport { Species = Link.Clip(reader.ReadStringAllocated(), 64), Weight = reader.ReadSingle(), Worth = reader.ReadInt32() })); Link.Describe((Action)delegate(Writer writer, BoardUpdate value) { BoardEntry[] array = value.Entries ?? Array.Empty(); int num = Link.Sane(array.Length, 64); writer.WriteInt32(num); for (int i = 0; i < num; i++) { writer.WriteUInt64(array[i].SteamId); writer.WriteString(array[i].Angler); writer.WriteString(array[i].Species); writer.WriteSingle(array[i].Weight); writer.WriteInt32(array[i].Worth); } }, (Func)delegate(Reader reader) { int num = Link.Sane(reader.ReadInt32(), 64); BoardEntry[] array = new BoardEntry[num]; for (int i = 0; i < num; i++) { array[i] = new BoardEntry { SteamId = reader.ReadUInt64(), Angler = Link.Clip(reader.ReadStringAllocated(), 64), Species = Link.Clip(reader.ReadStringAllocated(), 64), Weight = reader.ReadSingle(), Worth = reader.ReadInt32() }; } return new BoardUpdate { Entries = array }; }); Link.Describe((Action)delegate(Writer writer, BenchAskMessage value) { writer.WriteUInt8Unpacked(value.Ask); writer.WriteSingle(value.X); writer.WriteSingle(value.Y); writer.WriteSingle(value.Z); writer.WriteSingle(value.Yaw); }, (Func)((Reader reader) => new BenchAskMessage { Ask = reader.ReadUInt8Unpacked(), X = reader.ReadSingle(), Y = reader.ReadSingle(), Z = reader.ReadSingle(), Yaw = reader.ReadSingle() })); Link.Describe((Action)delegate(Writer writer, BenchStateMessage value) { writer.WriteBoolean(value.Placed); writer.WriteSingle(value.X); writer.WriteSingle(value.Y); writer.WriteSingle(value.Z); writer.WriteSingle(value.Yaw); writer.WriteUInt8Unpacked(value.LuckTier); writer.WriteUInt8Unpacked(value.ValueTier); }, (Func)((Reader reader) => new BenchStateMessage { Placed = reader.ReadBoolean(), X = reader.ReadSingle(), Y = reader.ReadSingle(), Z = reader.ReadSingle(), Yaw = reader.ReadSingle(), LuckTier = reader.ReadUInt8Unpacked(), ValueTier = reader.ReadUInt8Unpacked() })); } protected override void AttachServer() { InstanceFinder.ServerManager.RegisterBroadcast((Action)Host.OnCatch, true); InstanceFinder.ServerManager.RegisterBroadcast((Action)Host.OnAsk, true); } protected override void DetachServer() { if (!((Object)(object)InstanceFinder.ServerManager == (Object)null)) { InstanceFinder.ServerManager.UnregisterBroadcast((Action)Host.OnCatch); InstanceFinder.ServerManager.UnregisterBroadcast((Action)Host.OnAsk); } } protected override void AttachClient() { InstanceFinder.ClientManager.RegisterBroadcast((Action)Guest.OnBoard); InstanceFinder.ClientManager.RegisterBroadcast((Action)Guest.OnBench); } protected override void DetachClient() { if (!((Object)(object)InstanceFinder.ClientManager == (Object)null)) { InstanceFinder.ClientManager.UnregisterBroadcast((Action)Guest.OnBoard); InstanceFinder.ClientManager.UnregisterBroadcast((Action)Guest.OnBench); Guest.Forget(); } } } [BepInPlugin("SpongeMods.FishermansTally", "Sponge's Fisherman's Tally", "1.0.0")] [BepInDependency("SpongeMods.Core", "1.0.0")] [BepInDependency("SpongeMods.UILib", "1.0.0")] [BepInDependency("SpongeMods.ModMenu", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string Id = "SpongeMods.FishermansTally"; public const string Version = "1.0.0"; internal const float BoardWeightAllowance = 1.25f; internal static ConfigEntry BiggerRange; internal static ConfigEntry SizeSpread; internal static ConfigEntry SmallestSize; internal static ConfigEntry LargestSize; internal static ConfigEntry VisibleSize; internal static ConfigEntry SizeVisibility; internal static ConfigEntry SweepSeconds; internal static ConfigEntry SizeAffectsHealth; internal static ConfigEntry HealthFromSize; internal static ConfigEntry KeepTally; internal static ConfigEntry AnnounceRecords; internal static ConfigEntry ShareBoard; internal static ConfigEntry TallyKey; internal static ConfigEntry BenchEnabled; internal static ConfigEntry PlaceKey; internal static ConfigEntry PlaceDistance; internal static ConfigEntry MaxLuckTier; internal static ConfigEntry MaxValueTier; internal static ConfigEntry LuckBaseCost; internal static ConfigEntry ValueBaseCost; internal static ConfigEntry CostGrowth; internal static ConfigEntry LuckPerTier; internal static ConfigEntry ValuePerTier; private static TallyScreen _screen; private readonly Scaling _scaling = new Scaling(); internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; BindSettings(); try { new Harmony("SpongeMods.FishermansTally").PatchAll(); } catch (Exception ex) { Log.LogError((object)("Could not install size and tally patches: " + ex.Message)); } Guest.BenchChanged += BenchBuilder.Sync; Tabs.Register(); Log.LogInfo((object)"Fisherman's Tally ready."); } private void OnDestroy() { Guest.BenchChanged -= BenchBuilder.Sync; BenchBuilder.Clear(); ((Link)Wire.Instance).Drop(); Tally.Flush(force: true); Host.Flush(force: true); } private void BindSettings() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Expected O, but got Unknown //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Expected O, but got Unknown //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Expected O, but got Unknown //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Expected O, but got Unknown //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Expected O, but got Unknown //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Expected O, but got Unknown BiggerRange = ((BaseUnityPlugin)this).Config.Bind("Size", "Wider size range", true, "The game already varies fish weight, but narrowly. Widen it so genuinely huge and tiny fish turn up."); SizeSpread = ((BaseUnityPlugin)this).Config.Bind("Size", "Spread", 2.5f, new ConfigDescription("How much further from average fish may fall. 1 leaves the game's own range alone.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 8f), Array.Empty())); SmallestSize = ((BaseUnityPlugin)this).Config.Bind("Size", "Smallest", 0.2f, new ConfigDescription("Lightest a fish may be, as a fraction of average.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 1f), Array.Empty())); LargestSize = ((BaseUnityPlugin)this).Config.Bind("Size", "Largest", 4f, new ConfigDescription("Heaviest a fish may be, as a multiple of average.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 12f), Array.Empty())); VisibleSize = ((BaseUnityPlugin)this).Config.Bind("Appearance", "Show size", true, "Draw a heavy fish larger. The game tracks weight but always draws every fish the same size."); SizeVisibility = ((BaseUnityPlugin)this).Config.Bind("Appearance", "How obvious", 1f, new ConfigDescription("How strongly weight shows in the model. 0 is invisible, 1 is true to the weight, above 1 exaggerates.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); SweepSeconds = ((BaseUnityPlugin)this).Config.Bind("Appearance", "Update interval", 0.5f, new ConfigDescription("Seconds between size checks. Lower reacts faster and costs more.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); SizeAffectsHealth = ((BaseUnityPlugin)this).Config.Bind("Difficulty", "Bigger fish are tougher", false, "Let weight affect health as well as value. This is a real difficulty change, so it is off by default."); HealthFromSize = ((BaseUnityPlugin)this).Config.Bind("Difficulty", "Health from size", 0.5f, new ConfigDescription("How much of a fish's extra weight becomes extra health. 1 means twice the weight is twice the health.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); KeepTally = ((BaseUnityPlugin)this).Config.Bind("Tally", "Keep a record", true, "Remember your heaviest catch of each species."); AnnounceRecords = ((BaseUnityPlugin)this).Config.Bind("Tally", "Announce a personal best", true, "Show a banner when you beat your own record."); ShareBoard = ((BaseUnityPlugin)this).Config.Bind("Tally", "Shared board", true, "Report your catches to the host so everyone can see one board of biggest catches. Your own book is kept either way."); TallyKey = ((BaseUnityPlugin)this).Config.Bind("Tally", "Open the book", new KeyboardShortcut((KeyCode)289, Array.Empty()), "Opens your record book. Tab switches to everyone's board."); BenchEnabled = ((BaseUnityPlugin)this).Config.Bind("Bench", "Enabled", true, "Allow a rod bench to be placed, and apply what it sells."); PlaceKey = ((BaseUnityPlugin)this).Config.Bind("Bench", "Place or remove", new KeyboardShortcut((KeyCode)290, Array.Empty()), "Puts the bench in front of you, or takes it away if it is already out. There is one bench per world and everybody shares it."); PlaceDistance = ((BaseUnityPlugin)this).Config.Bind("Bench", "Placement distance", 2.2f, new ConfigDescription("How far in front of you the bench lands.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 6f), Array.Empty())); MaxLuckTier = ((BaseUnityPlugin)this).Config.Bind("Bench", "Luck tiers", 5, new ConfigDescription("How many times luck can be upgraded.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 20), Array.Empty())); MaxValueTier = ((BaseUnityPlugin)this).Config.Bind("Bench", "Value tiers", 5, new ConfigDescription("How many times sale value can be upgraded.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 20), Array.Empty())); LuckBaseCost = ((BaseUnityPlugin)this).Config.Bind("Bench", "Luck starting cost", 500, new ConfigDescription("Cost of the first luck tier.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100000), Array.Empty())); ValueBaseCost = ((BaseUnityPlugin)this).Config.Bind("Bench", "Value starting cost", 500, new ConfigDescription("Cost of the first value tier.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100000), Array.Empty())); CostGrowth = ((BaseUnityPlugin)this).Config.Bind("Bench", "Cost growth", 1.8f, new ConfigDescription("How much dearer each tier is than the last.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 4f), Array.Empty())); LuckPerTier = ((BaseUnityPlugin)this).Config.Bind("Bench", "Luck per tier", 0.25f, new ConfigDescription("How much each luck tier flattens the odds toward rarer fish.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 1f), Array.Empty())); ValuePerTier = ((BaseUnityPlugin)this).Config.Bind("Bench", "Value per tier", 0.1f, new ConfigDescription("Extra sale value per tier, as a fraction.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 1f), Array.Empty())); } internal static void NoteCatch(Player angler, string species, float weight, int worth, bool personalBest) { if (personalBest && AnnounceRecords.Value) { Screen().Celebrate(species); } if (ShareBoard.Value && !string.IsNullOrEmpty(species)) { if (InstanceFinder.IsServerStarted) { Host.NoteLocal(angler, species, weight, worth); return; } Link.Tell(new CatchReport { Species = species, Weight = weight, Worth = worth }); } } internal static void OpenBench() { Screen().Show(View.Bench); } internal static void OpenBook() { Screen().Show(View.Book); } private static TallyScreen Screen() { return _screen ?? (_screen = new TallyScreen(Palette.Default)); } private void Update() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) _scaling.Step(); ((Link)Wire.Instance).Step(); if (InstanceFinder.IsServerStarted) { Host.Step(); } KeyboardShortcut value = TallyKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { OpenBook(); } value = PlaceKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ToggleBench(); } _screen?.Step(); Tally.Flush(); } internal static void ToggleBench() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (BenchEnabled.Value) { Vector3 point; float yaw; if (Guest.BenchPlaced) { Link.Tell(new BenchAskMessage { Ask = 1 }); } else if (BenchBuilder.AimPoint(out point, out yaw)) { Link.Tell(new BenchAskMessage { Ask = 0, X = point.x, Y = point.y, Z = point.z, Yaw = yaw }); } } } } internal sealed class Scaling { private readonly Dictionary _applied = new Dictionary(); private readonly List _stale = new List(); private float _nextSweep; private const float Slack = 0.01f; public void Step() { if (Plugin.VisibleSize.Value && !(Time.unscaledTime < _nextSweep)) { _nextSweep = Time.unscaledTime + Mathf.Max(0.1f, Plugin.SweepSeconds.Value); Sweep(); } } private void Sweep() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (ItemManager.Items == null) { return; } foreach (KeyValuePair item in ItemManager.Items) { Item value = item.Value; if ((Object)(object)value == (Object)null || (Object)(object)value.Creature == (Object)null) { continue; } Creature creature = value.Creature; if (!((Object)(object)value.Holder != (Object)null) && !value.IsInInventory) { float num = ScaleFor(((Item)creature).RandomizedWeight); if (!_applied.TryGetValue(creature, out var value2) || !(Mathf.Abs(value2 - num) < 0.01f) || !(Mathf.Abs(((Component)creature).transform.localScale.x - num) < 0.01f)) { ((Component)creature).transform.localScale = Vector3.one * num; _applied[creature] = num; } } } Forget(); } private static float ScaleFor(float weight) { if (weight <= 0f) { return 1f; } float num = Mathf.Pow(weight, 1f / 3f); return 1f + (num - 1f) * Plugin.SizeVisibility.Value; } private void Forget() { foreach (KeyValuePair item in _applied) { if ((Object)(object)item.Key == (Object)null) { _stale.Add(item.Key); } } if (_stale.Count != 0) { for (int i = 0; i < _stale.Count; i++) { _applied.Remove(_stale[i]); } _stale.Clear(); } } } internal static class Host { private static readonly Dictionary _board = new Dictionary(); private static bool _benchPlaced; private static Vector3 _benchAt; private static float _benchYaw; private static byte _luckTier; private static byte _valueTier; private static string _loadedFor; private static bool _dirty; private static float _nextWrite; private static readonly HashSet _greeted = new HashSet(); private static readonly List _departed = new List(); public static int LuckTier => _luckTier; public static int ValueTier => _valueTier; public static void OnCatch(NetworkConnection from, CatchReport report, Channel channel) { if (!Plugin.ShareBoard.Value) { return; } Player val = Link.Who(from); if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(report.Species)) { float num = Mathf.Max(1f, Plugin.LargestSize.Value) * 1.25f; float num2 = Mathf.Clamp(report.Weight, 0f, num); if (!(num2 <= 0f)) { Remember(val.SteamID, val.SteamName, report.Species, num2, report.Worth); } } } public static void NoteLocal(Player player, string species, float weight, int worth) { if ((Object)(object)player != (Object)null) { Remember(player.SteamID, player.SteamName, species, weight, worth); } } private static void Remember(ulong steamId, string angler, string species, float weight, int worth) { Load(); if (!_board.TryGetValue(steamId, out var value) || !(weight <= value.Weight)) { _board[steamId] = new BoardEntry { SteamId = steamId, Angler = (string.IsNullOrEmpty(angler) ? "Angler" : angler), Species = species, Weight = weight, Worth = worth }; _dirty = true; PushBoard(); } } public static void OnAsk(NetworkConnection from, BenchAskMessage ask, Channel channel) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Load(); Player val = Link.Who(from); if ((Object)(object)val == (Object)null) { return; } switch ((BenchAsk)ask.Ask) { default: return; case BenchAsk.Place: if (!Plugin.BenchEnabled.Value) { return; } _benchPlaced = true; _benchAt = new Vector3(ask.X, ask.Y, ask.Z); _benchYaw = ask.Yaw; break; case BenchAsk.Remove: _benchPlaced = false; break; case BenchAsk.BuyLuck: if (!Buy(ref _luckTier, Plugin.MaxLuckTier.Value, LuckCost(_luckTier), val)) { return; } break; case BenchAsk.BuyValue: if (!Buy(ref _valueTier, Plugin.MaxValueTier.Value, ValueCost(_valueTier), val)) { return; } break; } _dirty = true; PushBench(); } private static bool Buy(ref byte tier, int ceiling, int cost, Player buyer) { if (tier >= ceiling) { return false; } if ((Object)(object)MoneyManager.Instance == (Object)null || !((NetworkBehaviour)MoneyManager.Instance).IsServerInitialized) { return false; } if (MoneyManager.Instance._money.Value < cost) { return false; } MoneyManager.RemoveMoney(cost, buyer); tier++; return true; } public static int LuckCost(int tier) { return Mathf.RoundToInt((float)Plugin.LuckBaseCost.Value * Mathf.Pow(Plugin.CostGrowth.Value, (float)tier)); } public static int ValueCost(int tier) { return Mathf.RoundToInt((float)Plugin.ValueBaseCost.Value * Mathf.Pow(Plugin.CostGrowth.Value, (float)tier)); } private static void Greet() { if ((Object)(object)InstanceFinder.ServerManager == (Object)null) { return; } Dictionary clients = InstanceFinder.ServerManager.Clients; foreach (KeyValuePair item in clients) { NetworkConnection value = item.Value; if (!(value == (NetworkConnection)null) && value.IsActive && value.IsAuthenticated && _greeted.Add(item.Key)) { Link.TellOne(value, BuildBoard()); Link.TellOne(value, BuildBench()); } } foreach (int item2 in _greeted) { if (!clients.ContainsKey(item2)) { _departed.Add(item2); } } if (_departed.Count != 0) { for (int i = 0; i < _departed.Count; i++) { _greeted.Remove(_departed[i]); } _departed.Clear(); } } public static void PushBoard() { Link.TellAll(BuildBoard()); } public static void PushBench() { Link.TellAll(BuildBench()); } private static BoardUpdate BuildBoard() { BoardEntry[] array = new BoardEntry[_board.Count]; _board.Values.CopyTo(array, 0); Array.Sort(array, (BoardEntry left, BoardEntry right) => right.Weight.CompareTo(left.Weight)); return new BoardUpdate { Entries = array }; } private static BenchStateMessage BuildBench() { return new BenchStateMessage { Placed = _benchPlaced, X = _benchAt.x, Y = _benchAt.y, Z = _benchAt.z, Yaw = _benchYaw, LuckTier = _luckTier, ValueTier = _valueTier }; } private static string FileFor(string save) { return SideCar.PathFor("sponge-tally", save); } private static void Load() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) string text = SaveManager.CurServerSave?.Name; if (string.IsNullOrEmpty(text) || text == _loadedFor) { return; } _loadedFor = text; _board.Clear(); _benchPlaced = false; _luckTier = 0; _valueTier = 0; try { SharedFile sharedFile = SideCar.Read(FileFor(text), (Action)Plugin.Log.LogWarning); _benchPlaced = sharedFile.BenchPlaced; _benchAt = new Vector3(sharedFile.BenchX, sharedFile.BenchY, sharedFile.BenchZ); _benchYaw = sharedFile.BenchYaw; _luckTier = (byte)Mathf.Clamp(sharedFile.LuckTier, 0, 255); _valueTier = (byte)Mathf.Clamp(sharedFile.ValueTier, 0, 255); if (sharedFile.Board == null) { return; } foreach (BoardRecord item in sharedFile.Board) { _board[item.SteamId] = item.ToEntry(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read the shared tally, starting fresh: " + ex.Message)); } } public static void Flush(bool force = false) { if (!_dirty || string.IsNullOrEmpty(_loadedFor) || (!force && Time.unscaledTime < _nextWrite)) { return; } _nextWrite = Time.unscaledTime + 20f; _dirty = false; try { SharedFile sharedFile = new SharedFile { BenchPlaced = _benchPlaced, BenchX = _benchAt.x, BenchY = _benchAt.y, BenchZ = _benchAt.z, BenchYaw = _benchYaw, LuckTier = _luckTier, ValueTier = _valueTier, Board = new List() }; foreach (BoardEntry value in _board.Values) { sharedFile.Board.Add(BoardRecord.From(value)); } SideCar.Write(FileFor(_loadedFor), (object)sharedFile, (Action)Plugin.Log.LogWarning); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not write the shared tally: " + ex.Message)); } } public static void Step() { Load(); Greet(); Flush(); } } internal static class Guest { public static BoardEntry[] Board { get; private set; } = Array.Empty(); public static bool BenchPlaced { get; private set; } public static Vector3 BenchAt { get; private set; } public static float BenchYaw { get; private set; } public static int LuckTier { get; private set; } public static int ValueTier { get; private set; } public static event Action BenchChanged; public static void OnBoard(BoardUpdate update, Channel channel) { Board = update.Entries ?? Array.Empty(); } public static void OnBench(BenchStateMessage state, Channel channel) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) bool num = BenchPlaced != state.Placed || !Mathf.Approximately(BenchYaw, state.Yaw) || BenchAt != new Vector3(state.X, state.Y, state.Z); BenchPlaced = state.Placed; BenchAt = new Vector3(state.X, state.Y, state.Z); BenchYaw = state.Yaw; LuckTier = state.LuckTier; ValueTier = state.ValueTier; if (num) { Guest.BenchChanged?.Invoke(); } } public static void Forget() { Board = Array.Empty(); BenchPlaced = false; LuckTier = 0; ValueTier = 0; Guest.BenchChanged?.Invoke(); } } [Serializable] internal class SharedFile { public int Version = 1; public bool BenchPlaced; public float BenchX; public float BenchY; public float BenchZ; public float BenchYaw; public int LuckTier; public int ValueTier; public List Board = new List(); } [Serializable] internal class BoardRecord { public string SteamIdText; public string Angler; public string Species; public float Weight; public int Worth; public ulong SteamId { get { if (!ulong.TryParse(SteamIdText, NumberStyles.None, CultureInfo.InvariantCulture, out var result)) { return 0uL; } return result; } } public static BoardRecord From(BoardEntry entry) { return new BoardRecord { SteamIdText = entry.SteamId.ToString(CultureInfo.InvariantCulture), Angler = entry.Angler, Species = entry.Species, Weight = entry.Weight, Worth = entry.Worth }; } public BoardEntry ToEntry() { return new BoardEntry { SteamId = SteamId, Angler = Angler, Species = Species, Weight = Weight, Worth = Worth }; } } [HarmonyPatch(typeof(CreatureUtils), "GetWeightWithStandardDeviation")] internal static class WeightSpreadPatch { private static void Postfix(ref float __result) { if (Plugin.BiggerRange.Value) { float num = 1f + (__result - 1f) * Plugin.SizeSpread.Value; __result = Mathf.Clamp(num, Plugin.SmallestSize.Value, Plugin.LargestSize.Value); } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class SizedHealthPatch { private static void Postfix(Creature __instance, ref int __result) { if (Plugin.SizeAffectsHealth.Value && !((Object)(object)__instance == (Object)null)) { float randomizedWeight = ((Item)__instance).RandomizedWeight; if (!(randomizedWeight <= 0f)) { float num = 1f + (randomizedWeight - 1f) * Plugin.HealthFromSize.Value; __result = Mathf.Max(1, Mathf.RoundToInt((float)__result * Mathf.Max(0.1f, num))); } } } } internal static class Tabs { public static void Register() { SpongeMenu.Tab("SpongeMods.FishermansTally", "Fisherman's Tally", 20).Heading("Fish size").Toggle("Wider range of sizes", Plugin.BiggerRange) .OnlyHost() .Number("Spread", Plugin.SizeSpread) .OnlyHost() .Number("Smallest", Plugin.SmallestSize) .OnlyHost() .Number("Largest", Plugin.LargestSize) .OnlyHost() .Note("Size comes from the game's own seeded calculation, so every player sees the same fish at the same weight with nothing sent over the network.") .Heading("How they look") .Toggle("Draw heavy fish larger", Plugin.VisibleSize) .Number("How strongly", Plugin.SizeVisibility) .Number("Update every (seconds)", Plugin.SweepSeconds) .Heading("How they fight") .Toggle("Weight affects health", Plugin.SizeAffectsHealth) .OnlyHost() .Number("How strongly", Plugin.HealthFromSize) .OnlyHost() .Heading("Your record book") .Toggle("Keep a record", Plugin.KeepTally) .Toggle("Announce personal bests", Plugin.AnnounceRecords) .Toggle("Share to everyone's board", Plugin.ShareBoard) .Press("Open the book", (Action)delegate { SpongeMenu.Close(); Plugin.OpenBook(); }); SpongeMenu.Tab("SpongeMods.FishermansTally", "Rod bench", 21).Heading("The bench").Toggle("Enabled", Plugin.BenchEnabled) .OnlyHost() .Number("Placement distance", Plugin.PlaceDistance) .Press("Put it down, or take it away", (Action)delegate { SpongeMenu.Close(); Plugin.ToggleBench(); }) .Note("One bench per world, shared by everyone, along with the tiers bought on it — the same way the game's money is one pot.") .Heading("Upgrades") .Number("Luck tiers", Plugin.MaxLuckTier) .OnlyHost() .Number("Luck per tier", Plugin.LuckPerTier) .OnlyHost() .Number("Value tiers", Plugin.MaxValueTier) .OnlyHost() .Number("Value per tier", Plugin.ValuePerTier) .OnlyHost() .Heading("Prices") .Number("First luck tier costs", Plugin.LuckBaseCost) .OnlyHost() .Number("First value tier costs", Plugin.ValueBaseCost) .OnlyHost() .Number("Each tier dearer by", Plugin.CostGrowth) .OnlyHost(); } } [Serializable] internal class Record { public string Species; public float Weight; public int Worth; public int Caught; public long WhenUtcTicks; public string When { get { if (WhenUtcTicks != 0L) { return new DateTime(WhenUtcTicks, DateTimeKind.Utc).ToLocalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); } return "-"; } } } [Serializable] internal class RecordBook { public int Version = 1; public List Records = new List(); } internal static class Tally { private const string FileName = "sponge-book"; private static readonly Dictionary _byName = new Dictionary(StringComparer.OrdinalIgnoreCase); private static bool _loaded; private static bool _dirty; private static float _nextWrite; private static string Path => SideCar.PathFor("sponge-book", (string)null); public static bool Note(string species, float weight, int worth) { if (string.IsNullOrEmpty(species)) { return false; } Load(); if (!_byName.TryGetValue(species, out var value)) { value = new Record { Species = species }; _byName[species] = value; } value.Caught++; _dirty = true; if (weight <= value.Weight) { return false; } value.Weight = weight; value.Worth = worth; value.WhenUtcTicks = DateTime.UtcNow.Ticks; return true; } public static List All() { Load(); List list = new List(_byName.Values); list.Sort((Record left, Record right) => right.Weight.CompareTo(left.Weight)); return list; } public static int TotalCaught() { Load(); int num = 0; foreach (Record value in _byName.Values) { num += value.Caught; } return num; } public static void Flush(bool force = false) { if (!_dirty || (!force && Time.unscaledTime < _nextWrite)) { return; } _nextWrite = Time.unscaledTime + 20f; _dirty = false; try { RecordBook recordBook = new RecordBook(); recordBook.Records.AddRange(_byName.Values); SideCar.Write(Path, (object)recordBook, (Action)Plugin.Log.LogWarning); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not write the tally: " + ex.Message)); } } private static void Load() { if (_loaded) { return; } _loaded = true; try { RecordBook recordBook = SideCar.Read(Path, (Action)Plugin.Log.LogWarning); if (recordBook.Records == null) { return; } foreach (Record record in recordBook.Records) { if (!string.IsNullOrEmpty(record.Species)) { _byName[record.Species] = record; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read the tally, starting a new one: " + ex.Message)); } } } [HarmonyPatch(typeof(Creature), "LocalHit")] internal static class CatchPatch { private static void Prefix(Creature __instance, out bool __state) { __state = (Object)(object)__instance != (Object)null && __instance._localIsDead; } private static void Postfix(Creature __instance, bool __state) { if (!((Object)(object)__instance == (Object)null || __state) && __instance._localIsDead) { string name = ((Item)__instance).GetName(); float weight = ((Item)__instance).RandomizedWeight * ((Item)__instance)._weight; int totalWorth = ((Item)__instance).TotalWorth; bool personalBest = Plugin.KeepTally.Value && Tally.Note(name, weight, totalWorth); Plugin.NoteCatch(Player.LocalPlayer, name, weight, totalWorth, personalBest); } } } internal enum View { Book, Board, Bench } internal sealed class TallyScreen { private const int Rows = 12; private readonly Menu _menu; private readonly Label _banner; private readonly Palette _palette; private float _bannerUntil; private string _notice = string.Empty; private float _noticeUntil; private List _records = new List(); public bool Open { get; private set; } public View Showing { get; private set; } public TallyScreen(Palette palette) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) _palette = palette; _menu = new Menu("Tally.Book", 700f, 12, palette, 25f, 17f); _menu.PlaceAt(new Placement((Anchor)4, 0f, 0f)); _banner = new Label("Tally.Banner", (RectTransform)null, 24f, palette.Accent, true) { Alignment = (TextAnchor)4 }; Placement val = new Placement((Anchor)1, 0f, 140f); ((Placement)(ref val)).ApplyTo(_banner.Rect); _banner.Rect.sizeDelta = new Vector2(700f, 40f); _banner.Visible(false); } public void Show(View view) { if (Open && Showing == view) { Close(); return; } Open = true; Showing = view; _menu.Visible(true); _menu.Rewind(); Refill(); } public void Close() { Open = false; _menu.Visible(false); } public void Celebrate(string species) { _banner.Text = "New personal best — " + species; _banner.Visible(true); _bannerUntil = Time.unscaledTime + 4f; } public void Step() { if (_bannerUntil > 0f && Time.unscaledTime > _bannerUntil) { _banner.Visible(false); _bannerUntil = 0f; } if (Open) { if (Input.GetKeyDown((KeyCode)274)) { _menu.Move(1); } else if (Input.GetKeyDown((KeyCode)273)) { _menu.Move(-1); } else if (Input.GetKeyDown((KeyCode)275) || Input.GetKeyDown((KeyCode)276)) { Swap(); } else if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)) { Choose(); } else if (Input.GetKeyDown((KeyCode)27)) { Close(); } if (Showing != View.Book) { Refill(); } Draw(); } } private void Swap() { if (Showing != View.Bench) { Showing = ((Showing == View.Book) ? View.Board : View.Book); _menu.Rewind(); Refill(); } } private void Choose() { if (Showing == View.Bench) { int cursor = _menu.Cursor; if (cursor >= 0 && Plugin.BenchEnabled.Value) { Link.Tell(new BenchAskMessage { Ask = (byte)((cursor == 0) ? 2 : 3) }); Notify("Asked the host to buy that."); } } } private void Notify(string text) { _notice = text; _noticeUntil = Time.unscaledTime + 4f; } private void Refill() { switch (Showing) { case View.Board: FillBoard(); break; case View.Bench: FillBench(); break; default: FillBook(); break; } } private void FillBook() { _records = Tally.All(); _menu.Selectable = false; CultureInfo invariantCulture = CultureInfo.InvariantCulture; List list = new List(_records.Count); foreach (Record record in _records) { list.Add(string.Format(invariantCulture, "{0,-26} {1,7:0.00} kg {2,8} {3,7} {4}", Trim(record.Species, 26), record.Weight, record.Worth, record.Caught, record.When)); } if (list.Count == 0) { list.Add("Nothing landed yet."); } _menu.SetItems((IEnumerable)list); } private void FillBoard() { _menu.Selectable = false; BoardEntry[] board = Guest.Board; CultureInfo invariantCulture = CultureInfo.InvariantCulture; List list = new List(board.Length); for (int i = 0; i < board.Length; i++) { BoardEntry boardEntry = board[i]; list.Add(string.Format(invariantCulture, "{0,2}. {1,-20} {2,-20} {3,7:0.00} kg {4,8}", i + 1, Trim(boardEntry.Angler, 20), Trim(boardEntry.Species, 20), boardEntry.Weight, boardEntry.Worth)); } if (list.Count == 0) { list.Add(Plugin.ShareBoard.Value ? "No catches recorded yet this world." : "The shared board is switched off in the settings."); } _menu.SetItems((IEnumerable)list); } private void FillBench() { _menu.Selectable = true; CultureInfo invariantCulture = CultureInfo.InvariantCulture; int luck = Upgrades.Luck; int value = Upgrades.Value; List items = new List(2) { Offer("Luck", luck, Plugin.MaxLuckTier.Value, Host.LuckCost(luck), "rare fish " + (Upgrades.LuckStrength * 100f).ToString("0", invariantCulture) + "% likelier"), Offer("Sale value", value, Plugin.MaxValueTier.Value, Host.ValueCost(value), "+" + (Upgrades.ValueBonus * 100f).ToString("0", invariantCulture) + "% when you sell") }; _menu.SetItems((IEnumerable)items); } private static string Offer(string name, int tier, int ceiling, int cost, string effect) { string arg = ((tier >= ceiling) ? "MAX" : $"tier {tier} of {ceiling} next {cost}"); return string.Format(CultureInfo.InvariantCulture, "{0,-12} {1,-26} {2}", name, arg, effect); } private void Draw() { switch (Showing) { case View.Board: _menu.Title = "Biggest catches — everyone"; _menu.Header = ((Guest.Board.Length != 0) ? " ANGLER SPECIES BEST VALUE" : string.Empty); _menu.Footer = "←→ your own book ↑↓ scroll Esc close"; break; case View.Bench: _menu.Title = "Rod bench — " + MoneyManager.Money.ToString(CultureInfo.InvariantCulture) + " in the pot"; _menu.Header = string.Empty; _menu.Footer = ((Time.unscaledTime < _noticeUntil) ? _notice : "↑↓ choose Enter buy Esc close"); break; default: _menu.Title = ((_records.Count == 0) ? "Your record book" : ($"Your record book — {_records.Count} species, " + Tally.TotalCaught().ToString(CultureInfo.InvariantCulture) + " landed")); _menu.Header = ((_records.Count > 0) ? "SPECIES BEST VALUE CAUGHT WHEN" : string.Empty); _menu.Footer = "←→ everyone's board ↑↓ scroll Esc close"; break; } _menu.Draw(); } private static string Trim(string text, int width) { if (!string.IsNullOrEmpty(text)) { if (text.Length > width) { return text.Substring(0, width - 1) + "…"; } return text; } return "?"; } } internal static class Upgrades { public static int Luck { get { if (!InstanceFinder.IsServerStarted) { return Guest.LuckTier; } return Host.LuckTier; } } public static int Value { get { if (!InstanceFinder.IsServerStarted) { return Guest.ValueTier; } return Host.ValueTier; } } public static float LuckStrength => (float)Luck * Plugin.LuckPerTier.Value; public static float ValueBonus => (float)Value * Plugin.ValuePerTier.Value; } [HarmonyPatch(typeof(CreatureManager), "GetRandomItem")] internal static class LuckPatch { private static void Prefix(ref List weights) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if (!Plugin.BenchEnabled.Value || weights == null || weights.Count < 2) { return; } float luckStrength = Upgrades.LuckStrength; if (luckStrength <= 0f) { return; } float num = 1f / (1f + luckStrength); List list = new List(weights.Count); for (int i = 0; i < weights.Count; i++) { ItemInfoWeight val = weights[i]; if (val != null) { list.Add(new ItemInfoWeight { fishable = val.Fishable, _weight = Mathf.Pow(Mathf.Max(0f, val.Weight), num) }); } } if (list.Count == weights.Count) { weights = list; } } } [HarmonyPatch(typeof(MoneyManager), "SellItem")] internal static class SaleBonusPatch { private static void Postfix(Item item) { if (!Plugin.BenchEnabled.Value || (Object)(object)item == (Object)null || (Object)(object)MoneyManager.Instance == (Object)null || !((NetworkBehaviour)MoneyManager.Instance).IsServerInitialized) { return; } float valueBonus = Upgrades.ValueBonus; if (!(valueBonus <= 0f)) { int num = Mathf.RoundToInt((float)item.TotalWorth * valueBonus); if (num > 0) { SyncVar money = MoneyManager.Instance._money; money.Value += num; } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }