using System; using System.Collections.Generic; using System.Diagnostics; 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 BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using SOD.Common; using SOD.Common.Helpers.SyncDiskObjects; 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: AssemblyCompany("SoDDiskPack")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.12.0.0")] [assembly: AssemblyInformationalVersion("0.12.0")] [assembly: AssemblyProduct("SoDDiskPack")] [assembly: AssemblyTitle("SoDDiskPack")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.12.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 SoDDiskPack { public class DiskDef { public string Key; public string DiskName; public string EffectName; public string EffectDesc; public Effect Effect; public float Value; public int Price; public Rarity Rarity; public Manufacturer Manufacturer; public string[] SaleLocations; public string[] TierDescs; public UpgradeEffect[] TierEffects; public float[] TierValues; public Effect SideEffect; public float SideValue; public string SideName; public string SideDesc; public bool Enabled = true; public bool TiersInCode; } public static class Disks { public static readonly DiskDef[] All = new DiskDef[19] { new DiskDef { Key = "Quickstep", DiskName = "Quickstep", EffectName = "Fleet Foot", EffectDesc = "You move faster on foot.", Effect = (Effect)57, Value = 0.15f, Price = 2500, Rarity = (Rarity)2, Manufacturer = (Manufacturer)0, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = new string[3] { "You move faster still.", "Your pace improves further.", "You move considerably faster." }, TiersInCode = true }, new DiskDef { Key = "LowProfile", DiskName = "Low Profile", Enabled = false, EffectName = "Unremarkable", EffectDesc = "Citizens are less easily alarmed by you.", Effect = (Effect)62, Value = -0.15f, Price = 1000, Rarity = (Rarity)2, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" }, TierDescs = new string[3] { "Citizens are calmer still.", "You draw less attention again.", "You are markedly harder to alarm." } }, new DiskDef { Key = "SquattersRights", DiskName = "Squatter's Rights", Enabled = false, EffectName = "Belong Here", EffectDesc = "You are given longer before trespassing is reported.", Effect = (Effect)63, Value = 0.5f, Price = 1000, Rarity = (Rarity)2, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" }, TierDescs = new string[3] { "You are given longer still.", "Further grace before you are reported.", "A considerable delay before you are reported." } }, new DiskDef { Key = "Homebound", DiskName = "Homebound", Enabled = false, EffectName = "Homebound", EffectDesc = "You may travel directly to your apartment.", Effect = (Effect)65, Value = 1f, Price = 1500, Rarity = (Rarity)3, Manufacturer = (Manufacturer)2, SaleLocations = new string[1] { "SyncClinic" } }, new DiskDef { Key = "Signpost", DiskName = "Signpost", Enabled = false, EffectName = "Signpost", EffectDesc = "You may travel using street signage.", Effect = (Effect)67, Value = 1f, Price = 1500, Rarity = (Rarity)3, Manufacturer = (Manufacturer)2, SaleLocations = new string[1] { "SyncClinic" } }, new DiskDef { Key = "PersonaNonGrata", DiskName = "Persona Non Grata", Enabled = false, EffectName = "Persona Non Grata", EffectDesc = "Loitering is no longer held against you.", Effect = (Effect)69, Value = 1f, Price = 1000, Rarity = (Rarity)2, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" } }, new DiskDef { Key = "FreeRein", DiskName = "Free Rein", Enabled = false, EffectName = "Free Rein", EffectDesc = "Your presence at crime scenes is permitted.", Effect = (Effect)61, Value = 1f, Price = 1500, Rarity = (Rarity)3, Manufacturer = (Manufacturer)2, SaleLocations = new string[1] { "SyncClinic" } }, new DiskDef { Key = "DeepPockets", DiskName = "Deep Pockets", EffectName = "Deep Pockets", EffectDesc = "Increase your inventory capacity.", Effect = (Effect)11, Value = 1f, Price = 3000, Rarity = (Rarity)3, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" }, TierDescs = null }, new DiskDef { Key = "SprintersCurse", DiskName = "Sprinter's Curse", EffectName = "Fast Twitch", EffectDesc = "You move considerably faster on foot.", Effect = (Effect)57, Value = 0.2f, SideEffect = (Effect)27, SideValue = 0.25f, SideName = "Brittle", SideDesc = "Your reworked frame takes damage badly. This cannot be removed.", Price = 2500, Rarity = (Rarity)2, Manufacturer = (Manufacturer)0, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = new string[3] { "You run faster, and tire sooner for it.", "You run faster again. Your skin splits more easily.", "You run faster still, and the ground meets you harder." }, TiersInCode = true }, new DiskDef { Key = "IronLung", DiskName = "Iron Lung", EffectName = "Dense Tissue", EffectDesc = "You take considerably less damage.", Effect = (Effect)27, Value = -0.25f, SideEffect = (Effect)57, SideValue = -0.2f, SideName = "Heavy Gait", SideDesc = "Your added mass slows you down.", Price = 2500, Rarity = (Rarity)2, Manufacturer = (Manufacturer)0, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = new string[3] { "You tire far more slowly.", "Your body knits itself back together faster.", "Your gait is corrected." }, TiersInCode = true }, new DiskDef { Key = "Leap", DiskName = "Leap", EffectName = "Leap", EffectDesc = "You jump considerably higher, but land harder.", Effect = (Effect)0, Value = 0f, Price = 3500, Rarity = (Rarity)2, Manufacturer = (Manufacturer)0, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = new string[3] { "You jump higher still.", "Your leap improves again.", "You clear considerable heights." }, TiersInCode = true }, new DiskDef { Key = "DeadAir", DiskName = "Dead Air", EffectName = "Slow Response", EffectDesc = "Security systems take longer to react to you.", Effect = (Effect)44, Value = 0.5f, Price = 1250, Rarity = (Rarity)1, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" }, TierDescs = new string[2] { "Tripped breakers stay down longer.", "Disabled security is slower to wake." }, TiersInCode = true }, new DiskDef { Key = "PlusOne", DiskName = "Plus One", EffectName = "On The List", EffectDesc = "You obtain guest passes more readily.", Effect = (Effect)64, Value = 0.25f, Price = 2000, Rarity = (Rarity)1, Manufacturer = (Manufacturer)2, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = null }, new DiskDef { Key = "Muckraker", DiskName = "Muckraker", EffectName = "Expose", EffectDesc = "Earn money photographing illegal operations.", Effect = (Effect)50, Value = 40f, Price = 500, Rarity = (Rarity)0, Manufacturer = (Manufacturer)4, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = null }, new DiskDef { Key = "BlankFace", DiskName = "Blank Face", Enabled = false, EffectName = "Unmemorable", EffectDesc = "Citizens are far less easily alarmed by you.", Effect = (Effect)62, Value = -0.3f, SideEffect = (Effect)14, SideValue = -0.3f, SideName = "Forgettable", SideDesc = "Citizens are less willing to talk to you.", Price = 2000, Rarity = (Rarity)2, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" }, TierDescs = null }, new DiskDef { Key = "CompanyMan", DiskName = "Company Man", EffectName = "Staff Discount", EffectDesc = "Everything you buy costs considerably less.", Effect = (Effect)13, Value = 0.2f, SideEffect = (Effect)14, SideValue = -0.2f, SideName = "Corporate Stink", SideDesc = "Citizens trust you less. This cannot be removed.", Price = 1500, Rarity = (Rarity)1, Manufacturer = (Manufacturer)2, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = null }, new DiskDef { Key = "SecondWind", DiskName = "Second Wind", EffectName = "Second Wind", EffectDesc = "You recover health more quickly.", Effect = (Effect)12, Value = 0.1f, Price = 2000, Rarity = (Rarity)2, Manufacturer = (Manufacturer)0, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = new string[3] { "Your wounds close faster still.", "Your reserves last longer.", "Your flesh bruises less readily." }, TiersInCode = true }, new DiskDef { Key = "LongArm", DiskName = "Long Arm", EffectName = "Long Arm", EffectDesc = "You can reach further.", Effect = (Effect)23, Value = 0.1f, Price = 1000, Rarity = (Rarity)0, Manufacturer = (Manufacturer)0, SaleLocations = new string[1] { "SyncClinic" }, TierDescs = new string[2] { "You can reach further still.", "You throw with considerably more force." }, TiersInCode = true }, new DiskDef { Key = "LightsOut", DiskName = "Lights Out", EffectName = "Lights Out", EffectDesc = "Citizens you knock out stay unconscious longer.", Effect = (Effect)42, Value = 0.5f, Price = 2000, Rarity = (Rarity)2, Manufacturer = (Manufacturer)5, SaleLocations = new string[1] { "BlackmarketSyncClinic" }, TierDescs = null } }; } [BepInPlugin("ta.sod.syncdiskpack", "SoD Disk Pack", "0.12.0")] public class Plugin : BasePlugin { public const string GUID = "ta.sod.syncdiskpack"; public const string VER = "0.12.0"; internal static ManualLogSource L; internal static ConfigEntry DisableList; internal static ConfigEntry RemoveList; internal static ConfigEntry QsTier1; internal static ConfigEntry QsTier2; internal static ConfigEntry QsTier3; internal static ConfigEntry LeapJump0; internal static ConfigEntry LeapJump1; internal static ConfigEntry LeapJump2; internal static ConfigEntry LeapJump3; internal static ConfigEntry LeapFall0; internal static ConfigEntry LeapFall1; internal static ConfigEntry LeapFall2; internal static ConfigEntry LeapFall3; internal static ConfigEntry IlTiredness; internal static ConfigEntry IlRecovery; internal static ConfigEntry IlHunger; internal static ConfigEntry IlThirst; internal static ConfigEntry IlGaitCure; internal static ConfigEntry ScSpeedPerTier; internal static ConfigEntry ScTiredness; internal static ConfigEntry ScBleeding; internal static ConfigEntry ScFallDamage; internal static ConfigEntry DaBreakerReset; internal static ConfigEntry DaSecurityReset; internal static ConfigEntry DaTamperGrace; internal static ConfigEntry LaInteractionRange; internal static ConfigEntry LaCarryDistance; internal static ConfigEntry LaThrowForce; internal static ConfigEntry SwRecovery; internal static ConfigEntry SwEnergy; internal static ConfigEntry SwBruised; internal static float? BaseRunSpeed; internal static float? BaseJumpHeight; internal static float? BaseFallDamage; internal static float? BaseTiredness; internal static float? BaseRecovery; internal static float? BaseHunger; internal static float? BaseThirst; internal static float? BaseBleeding; internal static float? BaseBreakerReset; internal static float? BaseSecurityReset; internal static int? BaseTamperGrace; internal static float? BaseInteractionRange; internal static float? BaseCarryDistance; internal static float? BaseThrowForce; internal static float? BaseEnergyRate; internal static float? BaseBruised; public override void Load() { L = ((BasePlugin)this).Log; L.LogInfo((object)"=== SoDDiskPack 0.12.0 starting ==="); DisableList = ((BasePlugin)this).Config.Bind("_Experimental", "DisableVanillaDisks", "", "TEST ONLY. Comma-separated vanilla preset names to set disabled=true. Leave empty to change nothing."); RemoveList = ((BasePlugin)this).Config.Bind("_Experimental", "RemoveVanillaDisks", "", "TEST ONLY. Comma-separated vanilla preset names to REMOVE from Toolbox.allSyncDisks and from every MenuPreset stock list. Suppresses VENDOR stock only; world loot in an existing city is unaffected. Throwaway saves only. Leave empty."); QsTier1 = ((BasePlugin)this).Config.Bind("Quickstep", "Tier1RunSpeedFraction", 0.05f, "Quickstep tier 1. Fraction added to base playerRunSpeed. Cumulative."); QsTier2 = ((BasePlugin)this).Config.Bind("Quickstep", "Tier2RunSpeedFraction", 0.05f, "Quickstep tier 2. Fraction added to base playerRunSpeed. Cumulative."); QsTier3 = ((BasePlugin)this).Config.Bind("Quickstep", "Tier3RunSpeedFraction", 0.1f, "Quickstep tier 3. Fraction added to base playerRunSpeed. Cumulative."); LeapJump0 = ((BasePlugin)this).Config.Bind("Leap", "JumpHeightInstalled", 6f, "GameplayControls.jumpHeight while Leap is installed, unupgraded. Game baseline is 4.5. Absolute value, not a fraction."); LeapJump1 = ((BasePlugin)this).Config.Bind("Leap", "JumpHeightTier1", 7f, "jumpHeight at tier 1. Absolute."); LeapJump2 = ((BasePlugin)this).Config.Bind("Leap", "JumpHeightTier2", 8f, "jumpHeight at tier 2. Absolute."); LeapJump3 = ((BasePlugin)this).Config.Bind("Leap", "JumpHeightTier3", 9f, "jumpHeight at tier 3. Absolute. 9.0 was play-tested as a good ceiling."); LeapFall0 = ((BasePlugin)this).Config.Bind("Leap", "FallDamageInstalled", 1f, "fallDamageMultiplier while Leap is installed. Game baseline is 0.85. This is Leap's cost. The cure is the Stability split disk, not a tier."); LeapFall1 = ((BasePlugin)this).Config.Bind("Leap", "FallDamageTier1", 1.1f, "fallDamageMultiplier at tier 1."); LeapFall2 = ((BasePlugin)this).Config.Bind("Leap", "FallDamageTier2", 1.2f, "fallDamageMultiplier at tier 2."); LeapFall3 = ((BasePlugin)this).Config.Bind("Leap", "FallDamageTier3", 1.3f, "fallDamageMultiplier at tier 3."); IlTiredness = ((BasePlugin)this).Config.Bind("IronLung", "Tier1TirednessFraction", -0.3f, "Iron Lung tier 1. Fraction applied to base playerTirednessRate (0.06). Negative tires you more slowly. Deliberately ASYMMETRIC against Sprinter's Curse tier 1 (+0.25): if the two were equal and opposite a player running both disks would see an upgrade do literally nothing."); IlRecovery = ((BasePlugin)this).Config.Bind("IronLung", "Tier2RecoveryFraction", 0.25f, "Iron Lung tier 2. Fraction applied to base playerRecoveryRate (0.225). Positive heals faster. SUMMED with Second Wind tier 1 if both installed."); IlHunger = ((BasePlugin)this).Config.Bind("IronLung", "Tier3HungerFraction", -0.2f, "Iron Lung tier 3. Fraction applied to base playerHungerRate (0.125)."); IlThirst = ((BasePlugin)this).Config.Bind("IronLung", "Tier3ThirstFraction", -0.2f, "Iron Lung tier 3. Fraction applied to base playerThirstRate (0.15)."); IlGaitCure = ((BasePlugin)this).Config.Bind("IronLung", "Tier3GaitCureFraction", 0.25f, "Iron Lung tier 3 compensates for the Heavy Gait side effect. The enum gives maxSpeedModifier -0.2 (x0.8); this writes playerRunSpeed +25% on top. The two compose multiplicatively, so in ISOLATION 0.8 x 1.25 returns you to normal exactly. NOTE: run-speed fractions from all disks are summed and applied once to the baseline, so the cure is DILUTED when Quickstep or Sprinter's Curse are also installed - roughly 5% short with both at tier 3. This is expected behaviour."); ScSpeedPerTier = ((BasePlugin)this).Config.Bind("SprintersCurse", "SpeedFractionPerTier", 0.08f, "Sprinter's Curse. Fraction added to base playerRunSpeed per tier. Cumulative."); ScTiredness = ((BasePlugin)this).Config.Bind("SprintersCurse", "Tier1TirednessFraction", 0.25f, "Sprinter's Curse tier 1 cost. Fraction applied to base playerTirednessRate. Positive tires you faster. See IronLung Tier1TirednessFraction for why these two are not equal and opposite."); ScBleeding = ((BasePlugin)this).Config.Bind("SprintersCurse", "Tier2BleedingFraction", 0.5f, "Sprinter's Curse tier 2 cost. Fraction applied to base combatHitChanceOfBleeding (0.1). combatHitChanceOfBrokenLeg was rejected for this: at a 0.01 base it is imperceptible even tripled."); ScFallDamage = ((BasePlugin)this).Config.Bind("SprintersCurse", "Tier3FallDamageFraction", 0.3f, "Sprinter's Curse tier 3 cost. Fraction applied to whatever fallDamageMultiplier already is, so it stacks on top of Leap."); DaBreakerReset = ((BasePlugin)this).Config.Bind("DeadAir", "Tier1BreakerResetFraction", 0.5f, "Dead Air tier 1. Fraction applied to base breakerResetTime (0.5). POSITIVE means tripped breakers stay down LONGER, which is the stealth benefit. The sign was inverted before 0.10.0 and shortened the outage instead."); DaSecurityReset = ((BasePlugin)this).Config.Bind("DeadAir", "Tier2SecurityResetFraction", 0.5f, "Dead Air tier 2. Fraction applied to base securityResetTime (3). POSITIVE means disabled security takes LONGER to come back online. Same sign inversion as tier 1, fixed in 0.10.0."); DaTamperGrace = ((BasePlugin)this).Config.Bind("DeadAir", "Tier3TamperGraceAbsolute", 5, "UNUSED as of 0.10.0. Dead Air ships as a two-tier chain. tamperGrace is unobservable by construction: the tampering action completes in under 3 seconds, so the grace window never expires at any value. The key is retained so existing configs are not disturbed."); LaInteractionRange = ((BasePlugin)this).Config.Bind("LongArm", "Tier1InteractionRangeFraction", 0.2f, "Long Arm tier 1. Fraction applied to base interactionRange (1.585). This is interaction reach, and it stacks with the disk's own reachModifier main effect and with Tenacity/Brawn tier 1. Confirmed read live and observed in play."); LaCarryDistance = ((BasePlugin)this).Config.Bind("LongArm", "Tier2CarryDistanceFraction", 0.4f, "UNUSED as of 0.10.0. carryDistance is owned by PlacementPlus while that mod is enabled, so writes to it do nothing. The key is retained so existing configs are not disturbed."); LaThrowForce = ((BasePlugin)this).Config.Bind("LongArm", "Tier3ThrowForceFraction", 0.4f, "Long Arm tier 2 as of 0.10.0, despite the key name, which is kept to avoid orphaning the value on existing installs. Fraction applied to base throwForce (6.4). Raised from 0.25 because 0.25 was too weak to feel in play."); SwRecovery = ((BasePlugin)this).Config.Bind("SecondWind", "Tier1RecoveryFraction", 0.2f, "Second Wind tier 1. Fraction applied to base playerRecoveryRate (0.225). SUMMED with Iron Lung tier 2, which writes the same field."); SwEnergy = ((BasePlugin)this).Config.Bind("SecondWind", "Tier2EnergyFraction", -0.2f, "Second Wind tier 2. Fraction applied to base playerEnergyRate (0.116). UNTESTED IN PLAY: this field has never been confirmed to be read live rather than consumed once at startup. It will log correctly either way."); SwBruised = ((BasePlugin)this).Config.Bind("SecondWind", "Tier3BruisedFraction", -0.4f, "Second Wind tier 3. Fraction applied to base combatHitChanceOfBruised (0.1). Negative means you bruise less often. A small effect by design; no vanilla disk claims this field."); int num = 0; int num2 = 0; DiskDef[] all = Disks.All; foreach (DiskDef diskDef in all) { if (!((BasePlugin)this).Config.Bind(diskDef.Key, "Enabled", diskDef.Enabled, "Register this disk.").Value) { L.LogInfo((object)("skipped: " + diskDef.DiskName)); continue; } int value = ((BasePlugin)this).Config.Bind(diskDef.Key, "Price", diskDef.Price, "Purchase price.").Value; float value2 = ((BasePlugin)this).Config.Bind(diskDef.Key, "Value", diskDef.Value, "Base effect value. Fractions are percentages (0.1 = 10%). Ignored on disks whose effect is applied in code.").Value; if (diskDef.TierDescs != null && diskDef.TierDescs.Length != 0 && !diskDef.TiersInCode) { num2++; L.LogWarning((object)("*** " + diskDef.DiskName + " has upgrade options but no code in RecomputeAll. Those upgrades will do NOTHING. ***")); } try { Register(diskDef, value, value2); num++; } catch (Exception ex) { L.LogError((object)("FAILED " + diskDef.DiskName + ": " + ex)); } } Harmony.CreateAndPatchAll(typeof(DisablePatch), (string)null); Harmony.CreateAndPatchAll(typeof(TierPatch), (string)null); L.LogInfo((object)("=== SoDDiskPack done: " + num + " registered, " + num2 + " with unimplemented tiers ===")); } private static void Register(DiskDef d, int price, float value) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Invalid comparison between Unknown and I4 //IL_0140: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) int num = default(int); SyncDiskBuilder val = Lib.SyncDisks.Builder(d.DiskName, "ta.sod.syncdiskpack", true).AddEffect(d.EffectName, d.EffectDesc, ref num, (string)null); if ((int)d.SideEffect != 0) { int num2 = default(int); val.AddSideEffect(d.SideName, d.SideDesc, ref num2); } if (d.SaleLocations != null && d.SaleLocations.Length != 0) { val.AddSaleLocation(d.SaleLocations); } if (d.TierDescs != null && d.TierDescs.Length != 0) { Options val2 = default(Options); if (d.TierDescs.Length == 1) { ((Options)(ref val2))..ctor(d.TierDescs[0]); } else if (d.TierDescs.Length == 2) { ((Options)(ref val2))..ctor(d.TierDescs[0], d.TierDescs[1]); } else { ((Options)(ref val2))..ctor(d.TierDescs[0], d.TierDescs[1], d.TierDescs[2]); } OptionIds val3 = default(OptionIds); val.AddUpgradeOption(val2, ref val3); } SyncDiskPreset preset = val.CreateAndRegister().Preset; bool flag = (int)d.Effect == 0; if (!flag) { preset.mainEffect1 = d.Effect; preset.mainEffect1Value = value; } preset.mainEffect2 = (Effect)0; preset.mainEffect2Value = 0f; preset.mainEffect3 = (Effect)0; preset.mainEffect3Value = 0f; preset.price = price; preset.rarity = d.Rarity; preset.manufacturer = d.Manufacturer; preset.canBeSideJobReward = true; preset.minimumWealthLevel = 0f; if ((int)d.SideEffect != 0) { preset.sideEffect = d.SideEffect; preset.sideEffectValue = d.SideValue; } int num3 = 0; try { num3 = preset.option1UpgradeEffects.Count; } catch { } L.LogInfo((object)("registered " + d.DiskName + " | effect=" + ((object)preset.mainEffect1/*cast due to .constrained prefix*/).ToString() + " value=" + preset.mainEffect1Value + " mfr=" + ((object)preset.manufacturer/*cast due to .constrained prefix*/).ToString() + " side=" + ((object)preset.sideEffect/*cast due to .constrained prefix*/).ToString() + " sideVal=" + preset.sideEffectValue + " price=" + preset.price + " optionSlots=" + num3 + " customId=" + num + (flag ? " CODE-DRIVEN" : "") + (d.TiersInCode ? " TIERS-IN-CODE" : ""))); } private static int LevelOf(string suffix) { try { UpgradesController instance = UpgradesController.Instance; if ((Object)(object)instance == (Object)null || instance.upgrades == null) { return -1; } Enumerator enumerator = instance.upgrades.GetEnumerator(); while (enumerator.MoveNext()) { Upgrades current = enumerator.Current; if (current != null && !((SoCustomComparison)(object)current.preset == (SoCustomComparison)null)) { string name = ((Object)current.preset).name; if (name != null && name.EndsWith(suffix)) { return current.level; } } } } catch { } return -1; } internal static void RecomputeAll() { try { GameplayControls instance = GameplayControls.Instance; if (!((Object)(object)instance == (Object)null)) { if (!BaseRunSpeed.HasValue) { BaseRunSpeed = instance.playerRunSpeed; BaseJumpHeight = instance.jumpHeight; BaseFallDamage = instance.fallDamageMultiplier; BaseTiredness = instance.playerTirednessRate; BaseRecovery = instance.playerRecoveryRate; BaseHunger = instance.playerHungerRate; BaseThirst = instance.playerThirstRate; BaseBleeding = instance.combatHitChanceOfBleeding; BaseBreakerReset = instance.breakerResetTime; BaseSecurityReset = instance.securityResetTime; BaseTamperGrace = instance.tamperGrace; BaseInteractionRange = instance.interactionRange; BaseCarryDistance = instance.carryDistance; BaseThrowForce = instance.throwForce; BaseEnergyRate = instance.playerEnergyRate; BaseBruised = instance.combatHitChanceOfBruised; ManualLogSource l = L; string[] array = new string[32]; array[0] = "[TIER] captured baselines runSpeed="; float? baseRunSpeed = BaseRunSpeed; array[1] = baseRunSpeed.ToString(); array[2] = " jump="; baseRunSpeed = BaseJumpHeight; array[3] = baseRunSpeed.ToString(); array[4] = " fall="; baseRunSpeed = BaseFallDamage; array[5] = baseRunSpeed.ToString(); array[6] = " tired="; baseRunSpeed = BaseTiredness; array[7] = baseRunSpeed.ToString(); array[8] = " recovery="; baseRunSpeed = BaseRecovery; array[9] = baseRunSpeed.ToString(); array[10] = " hunger="; baseRunSpeed = BaseHunger; array[11] = baseRunSpeed.ToString(); array[12] = " thirst="; baseRunSpeed = BaseThirst; array[13] = baseRunSpeed.ToString(); array[14] = " bleeding="; baseRunSpeed = BaseBleeding; array[15] = baseRunSpeed.ToString(); array[16] = " breakerReset="; baseRunSpeed = BaseBreakerReset; array[17] = baseRunSpeed.ToString(); array[18] = " securityReset="; baseRunSpeed = BaseSecurityReset; array[19] = baseRunSpeed.ToString(); array[20] = " tamperGrace="; int? baseTamperGrace = BaseTamperGrace; array[21] = baseTamperGrace.ToString(); array[22] = " interactionRange="; baseRunSpeed = BaseInteractionRange; array[23] = baseRunSpeed.ToString(); array[24] = " carryDistance="; baseRunSpeed = BaseCarryDistance; array[25] = baseRunSpeed.ToString(); array[26] = " throwForce="; baseRunSpeed = BaseThrowForce; array[27] = baseRunSpeed.ToString(); array[28] = " energy="; baseRunSpeed = BaseEnergyRate; array[29] = baseRunSpeed.ToString(); array[30] = " bruised="; baseRunSpeed = BaseBruised; array[31] = baseRunSpeed.ToString(); l.LogInfo((object)string.Concat(array)); } int num = LevelOf("_Quickstep"); int num2 = LevelOf("_Leap"); int num3 = LevelOf("_Iron Lung"); int num4 = LevelOf("_Sprinter's Curse"); int num5 = LevelOf("_Dead Air"); int num6 = LevelOf("_Long Arm"); int num7 = LevelOf("_Second Wind"); float num8 = 0f; if (num >= 1) { num8 += QsTier1.Value; } if (num >= 2) { num8 += QsTier2.Value; } if (num >= 3) { num8 += QsTier3.Value; } if (num4 >= 1) { num8 += ScSpeedPerTier.Value; } if (num4 >= 2) { num8 += ScSpeedPerTier.Value; } if (num4 >= 3) { num8 += ScSpeedPerTier.Value; } if (num3 >= 3) { num8 += IlGaitCure.Value; } instance.playerRunSpeed = BaseRunSpeed.Value * (1f + num8); float value = BaseJumpHeight.Value; float num9 = BaseFallDamage.Value; if (num2 == 0) { value = LeapJump0.Value; num9 = LeapFall0.Value; } else if (num2 == 1) { value = LeapJump1.Value; num9 = LeapFall1.Value; } else if (num2 == 2) { value = LeapJump2.Value; num9 = LeapFall2.Value; } else if (num2 >= 3) { value = LeapJump3.Value; num9 = LeapFall3.Value; } if (num4 >= 3) { num9 *= 1f + ScFallDamage.Value; } instance.jumpHeight = value; instance.fallDamageMultiplier = num9; float num10 = 0f; if (num3 >= 1) { num10 += IlTiredness.Value; } if (num4 >= 1) { num10 += ScTiredness.Value; } instance.playerTirednessRate = BaseTiredness.Value * (1f + num10); float num11 = 0f; if (num3 >= 2) { num11 += IlRecovery.Value; } if (num7 >= 1) { num11 += SwRecovery.Value; } instance.playerRecoveryRate = BaseRecovery.Value * (1f + num11); instance.playerHungerRate = BaseHunger.Value * (1f + ((num3 >= 3) ? IlHunger.Value : 0f)); instance.playerThirstRate = BaseThirst.Value * (1f + ((num3 >= 3) ? IlThirst.Value : 0f)); instance.combatHitChanceOfBleeding = BaseBleeding.Value * (1f + ((num4 >= 2) ? ScBleeding.Value : 0f)); instance.breakerResetTime = BaseBreakerReset.Value * (1f + ((num5 >= 1) ? DaBreakerReset.Value : 0f)); instance.securityResetTime = BaseSecurityReset.Value * (1f + ((num5 >= 2) ? DaSecurityReset.Value : 0f)); instance.tamperGrace = BaseTamperGrace.Value; instance.interactionRange = BaseInteractionRange.Value * (1f + ((num6 >= 1) ? LaInteractionRange.Value : 0f)); instance.carryDistance = BaseCarryDistance.Value; instance.throwForce = BaseThrowForce.Value * (1f + ((num6 >= 2) ? LaThrowForce.Value : 0f)); instance.playerEnergyRate = BaseEnergyRate.Value * (1f + ((num7 >= 2) ? SwEnergy.Value : 0f)); instance.combatHitChanceOfBruised = BaseBruised.Value * (1f + ((num7 >= 3) ? SwBruised.Value : 0f)); L.LogInfo((object)("[TIER] qs=" + num + " leap=" + num2 + " il=" + num3 + " sc=" + num4 + " da=" + num5 + " la=" + num6 + " sw=" + num7 + " | runSpeed=" + instance.playerRunSpeed + " jump=" + instance.jumpHeight + " fall=" + instance.fallDamageMultiplier + " tired=" + instance.playerTirednessRate + " recovery=" + instance.playerRecoveryRate + " hunger=" + instance.playerHungerRate + " thirst=" + instance.playerThirstRate + " bleeding=" + instance.combatHitChanceOfBleeding + " breakerReset=" + instance.breakerResetTime + " securityReset=" + instance.securityResetTime + " tamperGrace=" + instance.tamperGrace + " interactionRange=" + instance.interactionRange + " carryDistance=" + instance.carryDistance + " throwForce=" + instance.throwForce + " energy=" + instance.playerEnergyRate + " bruised=" + instance.combatHitChanceOfBruised)); } } catch (Exception ex) { L.LogError((object)("[TIER] RecomputeAll failed: " + ex)); } } } [HarmonyPatch(typeof(UpgradeEffectController), "OnSyncDiskChange")] public static class TierPatch { private static void Postfix() { Plugin.RecomputeAll(); } } [HarmonyPatch(typeof(Toolbox), "Start")] public static class DisablePatch { private static bool done; private static List ParseNames(string raw) { List list = new List(); if (string.IsNullOrWhiteSpace(raw)) { return list; } string[] array = raw.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { list.Add(text); } } return list; } private static void Postfix() { if (!done) { done = true; DoDisable(); DoRemove(); } } private static void DoDisable() { List list = ParseNames(Plugin.DisableList.Value); if (list.Count == 0) { Plugin.L.LogInfo((object)"=== DisableVanillaDisks empty, nothing flagged ==="); return; } int num = 0; Enumerator enumerator = Toolbox.Instance.allSyncDisks.GetEnumerator(); while (enumerator.MoveNext()) { SyncDiskPreset current = enumerator.Current; foreach (string item in list) { if (((Object)current).name == item) { current.disabled = true; num++; Plugin.L.LogInfo((object)("=== DISABLED vanilla preset: " + ((Object)current).name + " ===")); } } } Plugin.L.LogInfo((object)("=== disable pass complete, " + num + " of " + list.Count + " names matched ===")); } private static void DoRemove() { List list = ParseNames(Plugin.RemoveList.Value); if (list.Count == 0) { Plugin.L.LogInfo((object)"=== RemoveVanillaDisks empty, nothing removed ==="); return; } int num = 0; Toolbox instance = Toolbox.Instance; if ((Object)(object)instance != (Object)null && instance.allSyncDisks != null) { for (int num2 = instance.allSyncDisks.Count - 1; num2 >= 0; num2--) { SyncDiskPreset val = instance.allSyncDisks[num2]; if (!((SoCustomComparison)(object)val == (SoCustomComparison)null)) { foreach (string item in list) { if (((Object)val).name == item) { instance.allSyncDisks.RemoveAt(num2); num++; Plugin.L.LogInfo((object)("=== REMOVED from Toolbox.allSyncDisks: " + item + " ===")); break; } } } } } else { Plugin.L.LogWarning((object)"=== Toolbox.allSyncDisks null, toolbox removal skipped ==="); } int num3 = 0; int num4 = 0; Il2CppArrayBase val2 = Resources.FindObjectsOfTypeAll(); if (val2 != null) { foreach (MenuPreset item2 in val2) { if ((SoCustomComparison)(object)item2 == (SoCustomComparison)null || item2.syncDisks == null) { continue; } num4++; for (int num5 = item2.syncDisks.Count - 1; num5 >= 0; num5--) { SyncDiskPreset val3 = item2.syncDisks[num5]; if (!((SoCustomComparison)(object)val3 == (SoCustomComparison)null)) { foreach (string item3 in list) { if (((Object)val3).name == item3) { item2.syncDisks.RemoveAt(num5); num3++; break; } } } } } } Plugin.L.LogInfo((object)("=== remove pass complete: " + num + " from Toolbox, " + num3 + " across " + num4 + " menu presets ===")); } } }