using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using GameNetcodeStuff;
using HarmonyLib;
using InteractiveTerminalAPI.UI;
using InteractiveTerminalAPI.UI.Application;
using InteractiveTerminalAPI.UI.Cursor;
using InteractiveTerminalAPI.UI.Screen;
using LethalModDataLib.Enums;
using LethalModDataLib.Events;
using LethalModDataLib.Features;
using LethalNetworkAPI;
using LethalNetworkAPI.Utils;
using LobbyCompatibility.Attributes;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using tesinormed.FAndCDaveCo.Bank;
using tesinormed.FAndCDaveCo.Bank.UI;
using tesinormed.FAndCDaveCo.Extensions;
using tesinormed.FAndCDaveCo.Insurance;
using tesinormed.FAndCDaveCo.Insurance.UI;
using tesinormed.FAndCDaveCo.Network;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("tesinormed.FAndCDaveCo")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+14e4dc01ea4c406787181855f4e5b262b6c36517")]
[assembly: AssemblyProduct("FAndCDaveCo")]
[assembly: AssemblyTitle("tesinormed.FAndCDaveCo")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace tesinormed.FAndCDaveCo
{
public class Config : SyncedConfig2<Config>
{
[SyncedEntryField]
public readonly SyncedEntry<bool> GameDisableDeathCreditPenalty;
[SyncedEntryField]
public readonly SyncedEntry<double> EconomicBasePremium;
[SyncedEntryField]
public readonly SyncedEntry<double> EconomicDeductible;
[SyncedEntryField]
public readonly SyncedEntry<double> EconomicDeductibleMaximum;
[SyncedEntryField]
public readonly SyncedEntry<double> EconomicDeductibleMinimum;
[SyncedEntryField]
public readonly SyncedEntry<double> StandardBasePremium;
[SyncedEntryField]
public readonly SyncedEntry<double> StandardDeductible;
[SyncedEntryField]
public readonly SyncedEntry<double> StandardDeductibleMaximum;
[SyncedEntryField]
public readonly SyncedEntry<double> StandardDeductibleMinimum;
[SyncedEntryField]
public readonly SyncedEntry<double> BespokeBasePremium;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption00;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption01;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption02;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption03;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption04;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption05;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption06;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption07;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption08;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption09;
[SyncedEntryField]
public readonly SyncedEntry<int> CoverageOption10;
[SyncedEntryField]
public readonly SyncedEntry<int> ClaimRetentionDays;
[SyncedEntryField]
public readonly SyncedEntry<double> ClaimPremiumIncrease;
[SyncedEntryField]
public readonly SyncedEntry<int> PenaltyStartDaysFromIssuance;
[SyncedEntryField]
public readonly SyncedEntry<double> PenaltyAmount;
[SyncedEntryField]
public readonly SyncedEntry<double> InterestAmount;
public Config(ConfigFile configFile)
: base("tesinormed.FAndCDaveCo")
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_0032: Expected O, but got Unknown
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
//IL_0066: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_009a: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Expected O, but got Unknown
//IL_00ce: Expected O, but got Unknown
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Expected O, but got Unknown
//IL_0102: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
//IL_0136: Expected O, but got Unknown
//IL_0147: 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_016a: Expected O, but got Unknown
//IL_016a: Expected O, but got Unknown
//IL_017b: 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_019e: Expected O, but got Unknown
//IL_019e: Expected O, but got Unknown
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Expected O, but got Unknown
//IL_01d2: Expected O, but got Unknown
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Expected O, but got Unknown
//IL_0206: Expected O, but got Unknown
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Expected O, but got Unknown
//IL_0238: Unknown result type (might be due to invalid IL or missing references)
//IL_0248: Expected O, but got Unknown
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Expected O, but got Unknown
//IL_027a: Unknown result type (might be due to invalid IL or missing references)
//IL_028a: Expected O, but got Unknown
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Expected O, but got Unknown
//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Expected O, but got Unknown
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_02ed: Expected O, but got Unknown
//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
//IL_030e: Expected O, but got Unknown
//IL_031f: Unknown result type (might be due to invalid IL or missing references)
//IL_032f: Expected O, but got Unknown
//IL_0340: Unknown result type (might be due to invalid IL or missing references)
//IL_0350: Expected O, but got Unknown
//IL_0361: Unknown result type (might be due to invalid IL or missing references)
//IL_0371: Expected O, but got Unknown
//IL_0382: Unknown result type (might be due to invalid IL or missing references)
//IL_039b: Unknown result type (might be due to invalid IL or missing references)
//IL_03a5: Expected O, but got Unknown
//IL_03a5: Expected O, but got Unknown
//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
//IL_03d2: Expected O, but got Unknown
//IL_03d2: Expected O, but got Unknown
//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
//IL_03fe: Expected O, but got Unknown
//IL_03fe: Expected O, but got Unknown
//IL_040f: Unknown result type (might be due to invalid IL or missing references)
//IL_0428: Unknown result type (might be due to invalid IL or missing references)
//IL_0432: Expected O, but got Unknown
//IL_0432: Expected O, but got Unknown
//IL_0443: Unknown result type (might be due to invalid IL or missing references)
//IL_045c: Unknown result type (might be due to invalid IL or missing references)
//IL_0466: Expected O, but got Unknown
//IL_0466: Expected O, but got Unknown
GameDisableDeathCreditPenalty = SyncedBindingExtensions.BindSyncedEntry<bool>(configFile, new ConfigDefinition("Game", "DisableDeathCreditPenalty"), true, new ConfigDescription("Whether to disable the death credit penalty (only if there is a current insurance policy)", (AcceptableValueBase)null, Array.Empty<object>()));
EconomicBasePremium = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Economic", "BasePremium"), 0.07, new ConfigDescription("Initial premiums before any additional penalties due to submitted claims", (AcceptableValueBase)null, Array.Empty<object>()));
EconomicDeductible = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Economic", "Deductible"), 0.25, new ConfigDescription("Percent of claim amount that must be paid before a payout is made", (AcceptableValueBase)null, Array.Empty<object>()));
EconomicDeductibleMinimum = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Economic", "DeductibleMinimum"), 0.15, new ConfigDescription("Percent of coverage that sets the deductible minimum amount", (AcceptableValueBase)null, Array.Empty<object>()));
EconomicDeductibleMaximum = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Economic", "DeductibleMaximum"), 0.6, new ConfigDescription("Percent of coverage that sets the deductible maximum amount", (AcceptableValueBase)null, Array.Empty<object>()));
StandardBasePremium = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Standard", "BasePremium"), 0.15, new ConfigDescription("Initial premiums before any additional penalties due to submitted claims", (AcceptableValueBase)null, Array.Empty<object>()));
StandardDeductible = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Standard", "Deductible"), 0.1, new ConfigDescription("Percent of claim amount that must be paid before a payout is made", (AcceptableValueBase)null, Array.Empty<object>()));
StandardDeductibleMinimum = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Standard", "DeductibleMinimum"), 0.1, new ConfigDescription("Percent of coverage that sets the deductible minimum amount", (AcceptableValueBase)null, Array.Empty<object>()));
StandardDeductibleMaximum = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Standard", "DeductibleMaximum"), 0.3, new ConfigDescription("Percent of coverage that sets the deductible maximum amount", (AcceptableValueBase)null, Array.Empty<object>()));
BespokeBasePremium = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Policies.Bespoke", "BasePremium"), 0.35, new ConfigDescription("Initial premiums before any additional penalties due to submitted claims", (AcceptableValueBase)null, Array.Empty<object>()));
CoverageOption00 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option00"), 150, (ConfigDescription)null);
CoverageOption01 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option01"), 400, (ConfigDescription)null);
CoverageOption02 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option02"), 800, (ConfigDescription)null);
CoverageOption03 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option03"), 1500, (ConfigDescription)null);
CoverageOption04 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option04"), 2250, (ConfigDescription)null);
CoverageOption05 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option05"), 3600, (ConfigDescription)null);
CoverageOption06 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option06"), 5500, (ConfigDescription)null);
CoverageOption07 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option07"), 8000, (ConfigDescription)null);
CoverageOption08 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option08"), 11125, (ConfigDescription)null);
CoverageOption09 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option09"), 15250, (ConfigDescription)null);
CoverageOption10 = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Coverage", "Option10"), 18000, (ConfigDescription)null);
ClaimPremiumIncrease = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Insurance.Claims", "PremiumIncrease"), 0.25, new ConfigDescription("Percent of the cumulative premium increase for each submitted claim", (AcceptableValueBase)null, Array.Empty<object>()));
ClaimRetentionDays = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Insurance.Claims", "RetentionDays"), 10, new ConfigDescription("Days that claims are retained in the save (sets the maximum increase for premiums)", (AcceptableValueBase)null, Array.Empty<object>()));
PenaltyStartDaysFromIssuance = SyncedBindingExtensions.BindSyncedEntry<int>(configFile, new ConfigDefinition("Bank.Loan.Penalty", "StartDaysFromIssuance"), 4, new ConfigDescription("Start of the late penalty in days from the issuance date", (AcceptableValueBase)null, Array.Empty<object>()));
PenaltyAmount = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Bank.Loan.Penalty", "Amount"), 0.1, new ConfigDescription("Percent of the credits garnished each day", (AcceptableValueBase)null, Array.Empty<object>()));
InterestAmount = SyncedBindingExtensions.BindSyncedEntry<double>(configFile, new ConfigDefinition("Bank.Loan", "InterestAmount"), 0.05, new ConfigDescription("Percent of the principal added on for interest (only added once)", (AcceptableValueBase)null, Array.Empty<object>()));
ConfigManager.Register<Config>((SyncedConfig2<Config>)(object)this);
}
}
[BepInPlugin("tesinormed.FAndCDaveCo", "FAndCDaveCo", "2.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency("LethalNetworkAPI", "3.0.0")]
[BepInDependency("com.sigurd.csync", "5.0.0")]
[LobbyCompatibility(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance { get; private set; }
internal static ManualLogSource Logger { get; private set; }
internal static Terminal Terminal { get; set; }
internal Config Config { get; private set; }
public State State { get; private set; }
private void Awake()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
Config = new Config(((BaseUnityPlugin)this).Config);
State = new State();
SaveLoadEvents.PostSaveGameEvent += (PostSaveGameEventHandler)delegate
{
State.Save();
};
SaveLoadEvents.PostLoadGameEvent += (PostLoadGameEventHandler)delegate
{
State.Load();
};
SaveLoadEvents.PostDeleteSaveEvent += (PostDeleteSaveEventHandler)delegate
{
State.Reset();
HUDManagerEvents.QueuedHudTips.Clear();
};
SaveLoadEvents.PostResetSavedGameValuesEvent += (PostResetSavedGameValuesEventHandler)delegate
{
State.Reset();
HUDManagerEvents.QueuedHudTips.Clear();
State.Save();
};
CreditEvents.Init();
HUDManagerEvents.Init();
InteractiveTerminalManager.RegisterApplication<PolicyInformationTerminal>(new string[3] { "insurance info", "insurance information", "insurance policy" });
InteractiveTerminalManager.RegisterApplication<PolicySelectTerminal>(new string[2] { "insurance select", "insurance get" });
InteractiveTerminalManager.RegisterApplication<PolicyClaimTerminal>(new string[3] { "insurance claim", "insurance claims", "insurance make claim" });
InteractiveTerminalManager.RegisterApplication<BankLoanInformationTerminal>(new string[2] { "bank loan info", "bank loan information" });
InteractiveTerminalManager.RegisterApplication<BankLoanGetTerminal>(new string[2] { "bank loan get", "bank loan" });
InteractiveTerminalManager.RegisterApplication<BankLoanPaymentTerminal>(new string[2] { "bank loan pay", "bank loan payment" });
Harmony val = new Harmony("tesinormed.FAndCDaveCo");
Logger.LogDebug((object)"patching in progress");
val.PatchAll(Assembly.GetExecutingAssembly());
Logger.LogDebug((object)"finished patching");
Logger.LogInfo((object)"tesinormed.FAndCDaveCo (FAndCDaveCo) version 2.0.0 loaded");
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "tesinormed.FAndCDaveCo";
public const string PLUGIN_NAME = "FAndCDaveCo";
public const string PLUGIN_VERSION = "2.0.0";
}
}
namespace tesinormed.FAndCDaveCo.Patches
{
[HarmonyPatch(typeof(NetworkManager), "Initialize")]
internal static class NetworkManager_Initialize_Patch
{
public static void Postfix(ref NetworkManager __instance)
{
if (LNetworkUtils.IsHostOrServer)
{
__instance.OnClientConnectedCallback += delegate
{
Plugin.Instance.State.MakeDirty();
};
}
}
}
[HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")]
internal static class RoundManager_DespawnPropsAtEndOfRound_Patch
{
public static void Prefix(ref RoundManager __instance)
{
if (!((NetworkBehaviour)__instance).IsServer || !StartOfRound.Instance.allPlayersDead || Plugin.Instance.State.Policy.Tier == PolicyTier.None)
{
return;
}
int totalScrapValue = (from grabbableObject in GameObject.Find("/Environment/HangarShip").GetComponentsInChildren<GrabbableObject>()
where grabbableObject.itemProperties.isScrap && !(grabbableObject is RagdollGrabbableObject)
select grabbableObject).Sum((GrabbableObject grabbableObject) => grabbableObject.scrapValue);
if (totalScrapValue > 0)
{
int claimDay = StartOfRound.Instance.gameStats.daysSpent - 1;
Plugin.Instance.State.MutateClaims(delegate(Dictionary<int, Claim> claims)
{
claims[claimDay] = new Claim(totalScrapValue);
});
Plugin.Logger.LogInfo((object)$"crew all dead, recorded pending claim with value of {totalScrapValue} for day {claimDay}");
HUDManagerEvents.InsuranceClaimAvailable.InvokeClients();
}
}
}
[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
internal static class StartOfRound_EndOfGame_Patch
{
public static void Prefix(ref StartOfRound __instance)
{
StartOfRound val = __instance;
if (val == null || !((NetworkBehaviour)val).IsServer || val.isChallengeFile)
{
return;
}
foreach (KeyValuePair<int, Claim> keyValuePair in Plugin.Instance.State.Claims.Where<KeyValuePair<int, Claim>>((KeyValuePair<int, Claim> pair) => StartOfRound.Instance.gameStats.daysSpent - pair.Key > SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.ClaimRetentionDays)))
{
Plugin.Instance.State.MutateClaims(delegate(Dictionary<int, Claim> claims)
{
claims.Remove(keyValuePair.Key);
});
Plugin.Logger.LogDebug((object)$"deleted old claim from day {keyValuePair.Key}: {keyValuePair.Value}");
}
if (Plugin.Instance.State.Policy != Policy.None)
{
if (Plugin.Terminal.groupCredits >= Plugin.Instance.State.TotalPremium)
{
CreditEvents.DeductGroupCredits.SendServer(Plugin.Instance.State.TotalPremium);
HUDManagerEvents.InsuranceRenewalSuccess.SendClients(Plugin.Instance.State.TotalPremium);
Plugin.Logger.LogDebug((object)$"insurance successfully renewed with premium of {Plugin.Instance.State.TotalPremium}");
}
else
{
Plugin.Instance.State.Policy = Policy.None;
HUDManagerEvents.InsuranceRenewalFail.InvokeClients();
Plugin.Logger.LogDebug((object)"insurance failed to renew");
}
}
if (Plugin.Instance.State.Loan.AmountUnpaid > 0 && Plugin.Instance.State.Loan.DaysSinceIssuance >= SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.PenaltyStartDaysFromIssuance))
{
int num = Math.Min((int)((double)Plugin.Terminal.groupCredits * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.PenaltyAmount)), Plugin.Instance.State.Loan.AmountUnpaid);
CreditEvents.DeductGroupCredits.SendServer(num);
Plugin.Logger.LogDebug((object)$"garnished ${num} from group credits due to loan nonpayment");
if (Plugin.Instance.State.Loan.AmountUnpaid - num == 0)
{
Plugin.Instance.State.Loan = Loan.None;
Plugin.Logger.LogDebug((object)"loan fully paid off due to garnishment");
}
else
{
Plugin.Instance.State.Loan = Plugin.Instance.State.Loan with
{
AmountPaid = Plugin.Instance.State.Loan.AmountPaid + num
};
Plugin.Logger.LogDebug((object)$"loan amount paid increased by {num}");
}
HUDManagerEvents.BankLoanCreditsGarnished.SendClients(num);
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
CodeMatcher obj = new CodeMatcher(instructions, generator).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.Calls(instruction, AccessTools.Method(typeof(HUDManager), "ApplyPenalty", (Type[])null, (Type[])null)))).SearchBack((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsField(instruction, AccessTools.Field(typeof(StartOfRound), "isChallengeFile"), false))).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Brtrue));
object operand = obj.Operand;
return obj.Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(State), "DisableDeathCreditPenalty")),
new CodeInstruction(OpCodes.Brtrue, operand)
}).InstructionEnumeration();
}
public static IEnumerator Postfix(IEnumerator values, StartOfRound __instance)
{
do
{
yield return values.Current;
}
while (values.MoveNext());
if (__instance != null && ((NetworkBehaviour)__instance).IsServer && !__instance.isChallengeFile && !((double)TimeOfDay.Instance.timeUntilDeadline <= 0.0))
{
HUDManagerEvents.RunShowQueuedHudTips.InvokeClients();
}
}
}
[HarmonyPatch(typeof(Terminal), "Awake")]
internal static class Terminal_Awake_Patch
{
public static void Postfix(ref Terminal __instance)
{
Plugin.Terminal = __instance;
}
}
}
namespace tesinormed.FAndCDaveCo.Network
{
public static class CreditEvents
{
public static LNetworkMessage<int> DeductGroupCredits;
public static LNetworkMessage<int> SpawnGoldBar;
internal static LNetworkMessage<Tuple<NetworkObjectReference, int>> SyncItemScrap;
public static LNetworkEvent TakeOutLoan;
internal static void Init()
{
DeductGroupCredits = LNetworkMessage<int>.Connect("DeductGroupCredits", (Action<int, ulong>)delegate(int amount, ulong _)
{
if (Plugin.Terminal.groupCredits < amount)
{
Plugin.Logger.LogError((object)$"could not deduct {amount} credits; balance would be under 0");
}
else
{
Terminal terminal = Plugin.Terminal;
terminal.groupCredits -= amount;
Plugin.Terminal.SyncGroupCreditsServerRpc(Plugin.Terminal.groupCredits, Plugin.Terminal.numberOfItemsInDropship);
Plugin.Logger.LogDebug((object)$"deducted {amount} credits");
}
}, (Action<int>)null, (Action<int, ulong>)null);
SpawnGoldBar = LNetworkMessage<int>.Connect("SpawnGoldBar", (Action<int, ulong>)delegate(int value, ulong client)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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_0104: Unknown result type (might be due to invalid IL or missing references)
Item val = StartOfRound.Instance.allItemsList.itemsList.Single((Item item) => item.itemName.ToLower() == "gold bar");
PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(client);
if ((Object)(object)playerController == (Object)null)
{
Plugin.Logger.LogError((object)$"could not get player controller for client {client}");
}
else
{
Vector3 position = ((Component)playerController).transform.position;
GameObject val2 = Object.Instantiate<GameObject>(val.spawnPrefab, position, Quaternion.identity, GameObject.Find("/Environment/HangarShip").transform);
val2.GetComponent<GrabbableObject>().itemProperties.isScrap = true;
val2.GetComponent<GrabbableObject>().itemProperties.creditsWorth = value;
val2.GetComponent<GrabbableObject>().SetScrapValue(value);
playerController.SetItemInElevator(true, true, val2.GetComponent<GrabbableObject>());
val2.GetComponent<NetworkObject>().Spawn(true);
Plugin.Logger.LogDebug((object)$"spawned gold bar with value of {value} at client {LethalNetworkExtensions.GetClientId(playerController)}");
SyncItemScrap.SendClients(new Tuple<NetworkObjectReference, int>(NetworkObjectReference.op_Implicit(val2.GetComponent<NetworkObject>()), value));
}
}, (Action<int>)null, (Action<int, ulong>)null);
SyncItemScrap = LNetworkMessage<Tuple<NetworkObjectReference, int>>.Connect("SyncItemScrapValue", (Action<Tuple<NetworkObjectReference, int>, ulong>)null, (Action<Tuple<NetworkObjectReference, int>>)delegate(Tuple<NetworkObjectReference, int> value)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
NetworkObjectReference.op_Implicit(value.Item1).GetComponent<GrabbableObject>().SetScrapValue(value.Item2);
}, (Action<Tuple<NetworkObjectReference, int>, ulong>)null);
TakeOutLoan = LNetworkEvent.Connect("TakeOutLoan", (Action<ulong>)delegate
{
Loan loan = new Loan(StartOfRound.Instance.gameStats.daysSpent, TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled);
Plugin.Instance.State.Loan = loan;
Plugin.Logger.LogDebug((object)$"took out a loan for {loan.Principal}");
TimeOfDay.Instance.quotaFulfilled = TimeOfDay.Instance.profitQuota;
TakeOutLoan.InvokeClients();
}, (Action)delegate
{
TimeOfDay.Instance.quotaFulfilled = TimeOfDay.Instance.profitQuota;
TimeOfDay.Instance.UpdateProfitQuotaCurrentTime();
StartOfRound.Instance.AutoSaveShipData();
}, (Action<ulong>)null);
}
}
public static class HUDManagerEvents
{
public static LNetworkMessage<int> InsuranceRenewalSuccess = null;
public static LNetworkEvent InsuranceRenewalFail = null;
public static LNetworkEvent InsuranceClaimAvailable = null;
public static LNetworkMessage<int> BankLoanCreditsGarnished = null;
public static LNetworkEvent RunShowQueuedHudTips = null;
internal static readonly List<Action> QueuedHudTips = new List<Action>();
internal static void Init()
{
InsuranceRenewalSuccess = LNetworkMessage<int>.Connect("InsuranceRenewalSuccess", (Action<int, ulong>)null, (Action<int>)delegate(int value)
{
QueuedHudTips.Add(delegate
{
HUDManager.Instance.DisplayTip("Insurance renewed", $"{value} credits have been deducted.", false, false, "LC_Tip1");
});
Plugin.Logger.LogDebug((object)"queued insurance renewal success on HUD");
}, (Action<int, ulong>)null);
InsuranceRenewalFail = LNetworkEvent.Connect("InsuranceRenewalFail", (Action<ulong>)null, (Action)delegate
{
QueuedHudTips.Add(delegate
{
HUDManager.Instance.DisplayTip("Insurance canceled", "You do not have sufficient credits.", true, false, "LC_Tip1");
});
Plugin.Logger.LogDebug((object)"queued insurance renewal fail on HUD");
}, (Action<ulong>)null);
InsuranceClaimAvailable = LNetworkEvent.Connect("InsuranceClaimAvailable", (Action<ulong>)null, (Action)delegate
{
QueuedHudTips.Add(delegate
{
HUDManager.Instance.DisplayTip("Insurance claim", "Confirm the pending claim at the terminal.", false, false, "LC_Tip1");
});
Plugin.Logger.LogDebug((object)"queued insurance claim available on HUD");
}, (Action<ulong>)null);
BankLoanCreditsGarnished = LNetworkMessage<int>.Connect("BankLoanCreditsGarnished", (Action<int, ulong>)null, (Action<int>)delegate(int value)
{
QueuedHudTips.Add(delegate
{
HUDManager.Instance.DisplayTip("Credits garnished", $"Due to loan nonpayment, {(int)(SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.PenaltyAmount) * 100.0)}% of your credits (▮{value}) have been garnished.", true, false, "LC_Tip1");
});
Plugin.Logger.LogDebug((object)"queued loan credit garnishing warning on HUD");
}, (Action<int, ulong>)null);
RunShowQueuedHudTips = LNetworkEvent.Connect("RunShowQueuedHudTips", (Action<ulong>)null, (Action)delegate
{
((MonoBehaviour)HUDManager.Instance).StartCoroutine(ShowQueuedHudTips());
}, (Action<ulong>)null);
}
private static IEnumerator ShowQueuedHudTips()
{
for (int index = 0; index < QueuedHudTips.Count; index++)
{
Action tip = QueuedHudTips[index];
if (index == 0)
{
yield return (object)new WaitForSeconds(3f);
}
tip();
Plugin.Logger.LogDebug((object)"displayed queued HUD tip");
yield return (object)new WaitForSeconds(7.5f);
}
QueuedHudTips.Clear();
}
}
public record State
{
public static bool DisableDeathCreditPenalty
{
get
{
if (Plugin.Instance.State.Policy.Tier == PolicyTier.None)
{
return false;
}
return SyncedEntry<bool>.op_Implicit(Plugin.Instance.Config.GameDisableDeathCreditPenalty);
}
}
public Policy Policy
{
get
{
return _policy.Value;
}
set
{
_policy.Value = value;
}
}
public Dictionary<int, Claim> Claims
{
get
{
return _claims.Value;
}
set
{
_claims.Value = value;
}
}
public Dictionary<int, Claim> ClaimedClaims => Claims.Where<KeyValuePair<int, Claim>>((KeyValuePair<int, Claim> pair) => pair.Value.Claimed).ToDictionary();
public Dictionary<int, Claim> UnclaimedClaims => Claims.Where<KeyValuePair<int, Claim>>((KeyValuePair<int, Claim> pair) => !pair.Value.Claimed).ToDictionary();
public double FractionalPremiumIncrease => (double)ClaimedClaims.Count * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.ClaimPremiumIncrease);
public int TotalPremium => CalculateTotalPremium(Policy.BasePremium);
public Loan Loan
{
get
{
return _loan.Value;
}
set
{
_loan.Value = value;
}
}
private readonly LNetworkVariable<Policy> _policy = LNetworkVariable<tesinormed.FAndCDaveCo.Insurance.Policy>.Connect("Policy", (Policy)null, (LNetworkVariableWritePerms)2, (Action<Policy, Policy>)delegate(Policy previous, Policy current)
{
Plugin.Logger.LogDebug((object)string.Format("{0} changed from ({1}) to ({2})", "Policy", previous, current));
});
private readonly LNetworkVariable<Dictionary<int, Claim>> _claims = LNetworkVariable<Dictionary<int, Claim>>.Connect("Claims", (Dictionary<int, Claim>)null, (LNetworkVariableWritePerms)2, (Action<Dictionary<int, Claim>, Dictionary<int, Claim>>)delegate(Dictionary<int, Claim> previous, Dictionary<int, Claim> current)
{
Plugin.Logger.LogDebug((object)("Claims changed from (" + string.Join(", ", previous ?? new Dictionary<int, Claim>()) + ") to (" + string.Join(", ", current ?? new Dictionary<int, Claim>()) + ")"));
});
private readonly LNetworkVariable<Loan> _loan = LNetworkVariable<tesinormed.FAndCDaveCo.Bank.Loan>.Connect("Loan", (Loan)null, (LNetworkVariableWritePerms)2, (Action<Loan, Loan>)delegate(Loan previous, Loan current)
{
Plugin.Logger.LogDebug((object)string.Format("{0} changed from ({1}) to ({2})", "Loan", previous, current));
});
public void MutateClaims(Action<Dictionary<int, Claim>> mutation)
{
mutation(Claims);
_claims.MakeDirty();
}
internal int CalculateTotalPremium(Policy policy)
{
return CalculateTotalPremium(policy.BasePremium);
}
private int CalculateTotalPremium(int basePremium)
{
return (int)((double)basePremium * (1.0 + FractionalPremiumIncrease));
}
public void MutateLoan(Action<Loan> mutation)
{
mutation(Loan);
_loan.MakeDirty();
}
internal void Save()
{
SaveLoadHandler.SaveData<Policy>(Policy, "Policy", (SaveLocation)0, true);
SaveLoadHandler.SaveData<Dictionary<int, Claim>>(Claims, "Claims", (SaveLocation)0, true);
SaveLoadHandler.SaveData<Loan>(Loan, "Loan", (SaveLocation)0, true);
}
internal void Load()
{
if (LNetworkUtils.IsHostOrServer)
{
Policy = SaveLoadHandler.LoadData<Policy>("Policy", (SaveLocation)0, tesinormed.FAndCDaveCo.Insurance.Policy.None, true);
Claims = SaveLoadHandler.LoadData<Dictionary<int, Claim>>("Claims", (SaveLocation)0, new Dictionary<int, Claim>(), true);
Loan = SaveLoadHandler.LoadData<Loan>("Loan", (SaveLocation)0, tesinormed.FAndCDaveCo.Bank.Loan.None, true);
}
}
internal void Reset()
{
Policy = tesinormed.FAndCDaveCo.Insurance.Policy.None;
Claims = new Dictionary<int, Claim>();
Loan = tesinormed.FAndCDaveCo.Bank.Loan.None;
}
internal void MakeDirty()
{
_policy.MakeDirty();
_claims.MakeDirty();
_loan.MakeDirty();
}
[CompilerGenerated]
protected virtual bool PrintMembers(StringBuilder builder)
{
RuntimeHelpers.EnsureSufficientExecutionStack();
builder.Append("Policy = ");
builder.Append(Policy);
builder.Append(", Claims = ");
builder.Append(Claims);
builder.Append(", ClaimedClaims = ");
builder.Append(ClaimedClaims);
builder.Append(", UnclaimedClaims = ");
builder.Append(UnclaimedClaims);
builder.Append(", FractionalPremiumIncrease = ");
builder.Append(FractionalPremiumIncrease.ToString());
builder.Append(", TotalPremium = ");
builder.Append(TotalPremium.ToString());
builder.Append(", Loan = ");
builder.Append(Loan);
return true;
}
}
}
namespace tesinormed.FAndCDaveCo.Insurance
{
[ES3Serializable]
public record Claim
{
public int Value;
public bool Claimed;
public Claim(int value, bool claimed = false)
{
if (value < 0)
{
throw new ArgumentOutOfRangeException("value", "nonnegative number required");
}
Value = value;
Claimed = claimed;
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("Claim { ");
stringBuilder.Append(string.Format("{0} = {1}, ", "Value", Value));
stringBuilder.Append(string.Format("{0} = {1}", "Claimed", Claimed));
stringBuilder.Append(" }");
return stringBuilder.ToString();
}
}
[ES3Serializable]
public record Policy
{
[ES3NonSerializable]
public int BasePremium => Tier switch
{
PolicyTier.HighDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.EconomicBasePremium)),
PolicyTier.LowDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.StandardBasePremium)),
PolicyTier.NoDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.BespokeBasePremium)),
_ => 0,
};
[ES3NonSerializable]
public double DeductiblePercent => Tier switch
{
PolicyTier.HighDeductible => SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.EconomicDeductible),
PolicyTier.LowDeductible => SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.StandardDeductible),
_ => 0.0,
};
[ES3NonSerializable]
public int DeductibleMinimum => Tier switch
{
PolicyTier.HighDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.EconomicDeductibleMinimum)),
PolicyTier.LowDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.StandardDeductibleMinimum)),
_ => 0,
};
[ES3NonSerializable]
public int DeductibleMaximum => Tier switch
{
PolicyTier.HighDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.EconomicDeductibleMaximum)),
PolicyTier.LowDeductible => (int)Math.Floor((double)Coverage * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.StandardDeductibleMaximum)),
_ => 0,
};
[ES3NonSerializable]
public static readonly Policy None = new Policy(PolicyTier.None, 0);
public PolicyTier Tier;
public int Coverage;
public Policy(PolicyTier tier, int coverage)
{
if (coverage < 0)
{
throw new ArgumentOutOfRangeException("coverage", "nonnegative number required");
}
Tier = tier;
Coverage = coverage;
}
public int CalculatePayout(int value)
{
if (value < 0)
{
throw new ArgumentOutOfRangeException("value", "nonnegative number required");
}
return Math.Min(value, Coverage);
}
public int CalculateDeductible(int value)
{
if (value < 0)
{
throw new ArgumentOutOfRangeException("value", "nonnegative number required");
}
return Math.Clamp((int)Math.Floor((double)CalculatePayout(value) * DeductiblePercent), DeductibleMinimum, DeductibleMaximum);
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("Policy { ");
stringBuilder.Append(string.Format("{0} = {1}, ", "Tier", Tier));
stringBuilder.Append(string.Format("{0} = {1}", "Coverage", Coverage));
stringBuilder.Append(" }");
return stringBuilder.ToString();
}
[CompilerGenerated]
protected virtual bool PrintMembers(StringBuilder builder)
{
RuntimeHelpers.EnsureSufficientExecutionStack();
builder.Append("Tier = ");
builder.Append(Tier.ToString());
builder.Append(", Coverage = ");
builder.Append(Coverage.ToString());
builder.Append(", BasePremium = ");
builder.Append(BasePremium.ToString());
builder.Append(", DeductiblePercent = ");
builder.Append(DeductiblePercent.ToString());
builder.Append(", DeductibleMinimum = ");
builder.Append(DeductibleMinimum.ToString());
builder.Append(", DeductibleMaximum = ");
builder.Append(DeductibleMaximum.ToString());
return true;
}
[CompilerGenerated]
protected Policy(Policy original)
{
Tier = original.Tier;
Coverage = original.Coverage;
}
}
public static class PolicyExtensions
{
public static Policy CreatePolicy(this PolicyTier policyTier, int coverage)
{
return new Policy(policyTier, coverage);
}
}
public enum PolicyTier : byte
{
None,
HighDeductible,
LowDeductible,
NoDeductible
}
public static class PolicyTierExtensions
{
public static string ToFriendlyString(this PolicyTier policyTier)
{
return policyTier switch
{
PolicyTier.HighDeductible => "Economic",
PolicyTier.LowDeductible => "Standard",
PolicyTier.NoDeductible => "Bespoke",
PolicyTier.None => "No Policy?",
_ => throw new ArgumentOutOfRangeException("policyTier", $"unexpected value: {policyTier}"),
};
}
}
}
namespace tesinormed.FAndCDaveCo.Insurance.UI
{
public class PolicyClaimTerminal : InteractiveTerminalApplication
{
protected override string Title => "F&C Dave Co. Insurance: Make a claim";
private CursorElement CreateCursorElement(int day, Claim claim)
{
Claim claim2 = claim;
return CursorElement.Create($"Day {day}: ${claim2.Value}", "", (Action)delegate
{
ConfirmClaim(day, claim2);
}, (Func<CursorElement, bool>)((CursorElement _) => true), false);
}
public override void Initialization()
{
if (Plugin.Instance.State.Policy.Tier == PolicyTier.None)
{
LockedNotification((ITextElement)TextElement.Create("You do not have an active insurance policy."));
return;
}
if (Plugin.Instance.State.UnclaimedClaims.Count == 0)
{
LockedNotification((ITextElement)TextElement.Create("You do not have any claims."));
return;
}
CursorElement[] seed = Array.Empty<CursorElement>();
seed = Plugin.Instance.State.UnclaimedClaims.Aggregate<KeyValuePair<int, Claim>, CursorElement[]>(seed, delegate(CursorElement[] current, KeyValuePair<int, Claim> pair)
{
int num = 0;
CursorElement[] array = (CursorElement[])(object)new CursorElement[1 + current.Length];
ReadOnlySpan<CursorElement> readOnlySpan = new ReadOnlySpan<CursorElement>(current);
readOnlySpan.CopyTo(new Span<CursorElement>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
array[num] = CreateCursorElement(pair.Key, pair.Value);
num++;
return array;
});
(base.MainScreen, base.MainCursorMenu) = Selection("Select a pending claim.", seed);
}
private void ConfirmClaim(int day, Claim claim)
{
Claim claim2 = claim;
int deductible = Plugin.Instance.State.Policy.CalculateDeductible(claim2.Value);
int payout = Plugin.Instance.State.Policy.CalculatePayout(claim2.Value);
Confirm(delegate
{
ProcessClaim(day, deductible, payout, claim2);
}, delegate
{
ConfirmDeleteClaim(day);
}, (ITextElement[])(object)new ITextElement[2]
{
(ITextElement)TextElement.Create($"Are you sure you want to confirm this claim? You will need to pay a deductible of ${deductible}."),
(ITextElement)TextElement.Create($"You will be given back ${payout}.")
});
}
private void ConfirmDeleteClaim(int day)
{
Confirm(delegate
{
DeleteClaim(day);
}, base.PreviousMainScreenAction, (ITextElement)TextElement.Create($"Do you want to delete this claim for day {day}?"));
}
private void DeleteClaim(int day)
{
Plugin.Instance.State.MutateClaims(delegate(Dictionary<int, Claim> claims)
{
claims.Remove(day);
});
LockedNotification((ITextElement)TextElement.Create($"The claim for day {day} has been deleted."));
}
private void ProcessClaim(int day, int deductible, int payout, Claim claim)
{
Claim claim2 = claim;
if (((TerminalApplication)this).terminal.groupCredits < deductible)
{
Notification(base.PreviousMainScreenAction, (ITextElement)TextElement.Create("You do not have enough credits to continue with this claim."));
return;
}
Plugin.Instance.State.MutateClaims(delegate(Dictionary<int, Claim> claims)
{
claims[day] = new Claim(claim2.Value, claimed: true);
});
CreditEvents.DeductGroupCredits.SendServer(deductible);
CreditEvents.SpawnGoldBar.SendServer(payout);
LockedNotification((ITextElement)TextElement.Create($"You have been given a gold bar worth ${payout}."), (ITextElement)TextElement.Create($"You have been charged ${deductible}."), (ITextElement)TextElement.Create($"Your premiums have increased by {(int)(Plugin.Instance.State.FractionalPremiumIncrease * 100.0)}%."));
}
}
public class PolicyInformationTerminal : TerminalApplication
{
public override void Initialization()
{
List<ITextElement> list = new List<ITextElement>();
if (Plugin.Instance.State.Policy.Tier == PolicyTier.None)
{
list.Add((ITextElement)(object)TextElement.Create("You do not currently have an insurance policy."));
}
else
{
list.Add((ITextElement)(object)TextElement.Create($"You currently have the {Plugin.Instance.State.Policy.Tier.ToFriendlyString()} policy (${Plugin.Instance.State.Policy.Coverage})."));
list.Add((ITextElement)(object)TextElement.Create($"You have made {Plugin.Instance.State.ClaimedClaims.Count} claim(s) recently (within {Plugin.Instance.Config.ClaimRetentionDays.Value} days)."));
list.Add((ITextElement)(object)((Plugin.Instance.State.FractionalPremiumIncrease == 0.0) ? TextElement.Create($"You pay ${Plugin.Instance.State.TotalPremium} per day.") : TextElement.Create($"You pay ${Plugin.Instance.State.TotalPremium} (+{(int)(Plugin.Instance.State.FractionalPremiumIncrease * 100.0)}%) per day.")));
list.Add((ITextElement)(object)((Plugin.Instance.State.Policy.DeductiblePercent != 0.0) ? TextElement.Create($"Your deductible is currently {(int)(Plugin.Instance.State.Policy.DeductiblePercent * 100.0)}% (minimum: ${Plugin.Instance.State.Policy.DeductibleMinimum}, maximum: ${Plugin.Instance.State.Policy.DeductibleMaximum}).") : TextElement.Create("You do not pay deductibles.")));
}
BoxedScreen currentScreen = BoxedScreen.Create("F&C Dave Co. Insurance: Policy information", list.ToArray());
((TerminalApplication)this).currentScreen = (IScreen)(object)currentScreen;
}
}
public class PolicySelectTerminal : InteractiveTerminalApplication
{
protected override string Title => "F&C Dave Co. Insurance: Selection";
private CursorElement CreatePolicyTierCursorElement(PolicyTier policyTier, string description)
{
return CursorElement.Create(policyTier.ToFriendlyString() + ": " + description, "", (Action)delegate
{
SelectCoverage(policyTier);
}, (Func<CursorElement, bool>)((CursorElement _) => true), false);
}
private CursorElement CreateCoverageCursorElement(Policy policy)
{
Policy policy2 = policy;
return CursorElement.Create($"${policy2.Coverage}", "", (Action)delegate
{
ConfirmEverything(policy2);
}, (Func<CursorElement, bool>)((CursorElement _) => ((TerminalApplication)this).terminal.groupCredits >= Plugin.Instance.State.CalculateTotalPremium(policy2)), true);
}
public override void Initialization()
{
if (StartOfRound.Instance.isChallengeFile)
{
LockedNotification((ITextElement)TextElement.Create("You cannot get an insurance policy while doing a challenge moon."));
Plugin.Logger.LogDebug((object)"local player tried to get an insurance policy while doing a challenge moon");
return;
}
(base.MainScreen, base.MainCursorMenu) = Selection("Select a policy tier.", CreatePolicyTierCursorElement(PolicyTier.HighDeductible, "High deductible, low premium"), CreatePolicyTierCursorElement(PolicyTier.LowDeductible, "Low deductible, medium premium"), CreatePolicyTierCursorElement(PolicyTier.NoDeductible, "No deductible, high premium"), CursorElement.Create("Cancel policy", "", (Action)ConfirmCancelPolicy, (Func<CursorElement, bool>)((CursorElement _) => Plugin.Instance.State.Policy.Tier != PolicyTier.None), true));
}
private void ConfirmCancelPolicy()
{
if (Plugin.Instance.State.Policy.Tier == PolicyTier.None)
{
Notification(base.PreviousScreenAction, (ITextElement)TextElement.Create("You do not currently have a policy."));
}
else
{
Confirm(CancelPolicy, base.PreviousScreenAction, (ITextElement)TextElement.Create("Are you sure you want to cancel your current policy?"), (ITextElement)TextElement.Create($"Your current policy is {Plugin.Instance.State.Policy.Tier.ToFriendlyString()} (${Plugin.Instance.State.Policy.Coverage})."));
}
}
private void CancelPolicy()
{
Plugin.Instance.State.Policy = Policy.None;
LockedNotification((ITextElement)TextElement.Create("Your policy has been canceled."));
}
private void SelectCoverage(PolicyTier policyTier)
{
SelectionWithBack("Select the coverage amount.", base.PreviousMainScreenAction, CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption00))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption01))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption02))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption03))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption04))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption05))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption06))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption07))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption08))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption09))), CreateCoverageCursorElement(policyTier.CreatePolicy(SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.CoverageOption10))));
}
private void ConfirmEverything(Policy policy)
{
Policy policy2 = policy;
if (policy2 == Plugin.Instance.State.Policy)
{
Notification(base.PreviousScreenAction, (ITextElement)TextElement.Create("You already have this policy."));
return;
}
if (((TerminalApplication)this).terminal.groupCredits < Plugin.Instance.State.CalculateTotalPremium(policy2))
{
Notification(base.PreviousScreenAction, (ITextElement)TextElement.Create("You do not have enough credits to purchase this policy."));
return;
}
Confirm(delegate
{
SetEverything(policy2, Plugin.Instance.State.CalculateTotalPremium(policy2));
}, base.PreviousScreenAction, (ITextElement)TextElement.Create($"Are you sure you want to pick {policy2.Tier.ToFriendlyString()} (${policy2.Coverage})?"), (ITextElement)TextElement.Create((policy2.DeductiblePercent == 0.0) ? "This policy has no deductibles." : $"The deductibles are {(int)(policy2.DeductiblePercent * 100.0)}%, with a minimum of ${policy2.DeductibleMinimum} and a maximum of ${policy2.DeductibleMaximum}."), (ITextElement)TextElement.Create($"You will be charged ${Plugin.Instance.State.CalculateTotalPremium(policy2)}."));
}
private void SetEverything(Policy policy, int cost)
{
Plugin.Instance.State.Policy = policy;
CreditEvents.DeductGroupCredits.SendServer(cost);
LockedNotification((ITextElement)TextElement.Create($"Your policy has been updated to {policy.Tier.ToFriendlyString()} (${policy.Coverage})."), (ITextElement)TextElement.Create($"You have been charged ${cost}."));
}
}
internal static class PolicyTerminal
{
internal const string Title = "F&C Dave Co. Insurance";
}
}
namespace tesinormed.FAndCDaveCo.Extensions
{
public static class DictionaryExtensions
{
public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> dictionary)
{
return dictionary.ToDictionary<KeyValuePair<TKey, TValue>, TKey, TValue>((KeyValuePair<TKey, TValue> keyValuePair) => keyValuePair.Key, (KeyValuePair<TKey, TValue> keyValuePair) => keyValuePair.Value);
}
}
public abstract class InteractiveTerminalApplication : InteractiveTerminalApplication
{
protected abstract string Title { get; }
protected IScreen MainScreen { get; set; }
protected CursorMenu MainCursorMenu { get; set; }
private IScreen? PreviousScreen { get; set; }
private CursorMenu? PreviousCursorMenu { get; set; }
protected Action PreviousMainScreenAction => delegate
{
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen(MainScreen, MainCursorMenu, true);
};
protected Action PreviousScreenAction => delegate
{
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen(PreviousScreen ?? throw new InvalidOperationException("no previous screen"), PreviousCursorMenu ?? throw new InvalidOperationException("no previous cursor menu"), true);
};
protected override void SwitchScreen(IScreen screen, CursorMenu cursorMenu, bool previous)
{
PreviousScreen = ((TerminalApplication)this).currentScreen;
PreviousCursorMenu = ((BaseInteractiveApplication<CursorMenu, CursorElement>)this).currentCursorMenu;
((BaseInteractiveApplication<CursorMenu, CursorElement>)this).SwitchScreen(screen, cursorMenu, previous);
}
protected (IScreen, CursorMenu) Selection(string prompt, params CursorElement[] options)
{
CursorMenu val = CursorMenu.Create(0, '>', options, (Func<CursorElement, CursorElement, int>[])null);
ITextElement[] array = (ITextElement[])(object)new ITextElement[3]
{
(ITextElement)TextElement.Create(prompt),
(ITextElement)TextElement.Create(" "),
(ITextElement)val
};
BoxedScreen val2 = BoxedScreen.Create(Title, array);
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen((IScreen)(object)val2, val, false);
return ((IScreen)(object)val2, val);
}
protected void SelectionWithBack(string prompt, Action backAction, params CursorElement[] options)
{
CursorElement[] array = options;
int num = 0;
CursorElement[] array2 = (CursorElement[])(object)new CursorElement[1 + array.Length];
ReadOnlySpan<CursorElement> readOnlySpan = new ReadOnlySpan<CursorElement>(array);
readOnlySpan.CopyTo(new Span<CursorElement>(array2).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
array2[num] = CursorElement.Create("Back", "", backAction, (Func<CursorElement, bool>)((CursorElement _) => true), false);
num++;
options = array2;
CursorMenu val = CursorMenu.Create(0, '>', options, (Func<CursorElement, CursorElement, int>[])null);
ITextElement[] array3 = (ITextElement[])(object)new ITextElement[3]
{
(ITextElement)TextElement.Create(prompt),
(ITextElement)TextElement.Create(" "),
(ITextElement)val
};
BoxedScreen val2 = BoxedScreen.Create(Title, array3);
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen((IScreen)(object)val2, val, false);
}
protected void Confirm(Action confirmAction, params ITextElement[] text)
{
CursorMenu val = CursorMenu.Create(0, '>', (CursorElement[])(object)new CursorElement[1] { CursorElement.Create("Confirm", "", confirmAction, (Func<CursorElement, bool>)null, true) }, (Func<CursorElement, CursorElement, int>[])null);
int num = 0;
ITextElement[] array = (ITextElement[])(object)new ITextElement[2 + text.Length];
ReadOnlySpan<ITextElement> readOnlySpan = new ReadOnlySpan<ITextElement>(text);
readOnlySpan.CopyTo(new Span<ITextElement>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
array[num] = (ITextElement)(object)TextElement.Create(" ");
num++;
array[num] = (ITextElement)(object)val;
num++;
ITextElement[] array2 = array;
BoxedScreen val2 = BoxedScreen.Create(Title, array2);
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen((IScreen)(object)val2, val, false);
}
protected void Confirm(Action confirmAction, Action declineAction, params ITextElement[] text)
{
CursorMenu val = CursorMenu.Create(0, '>', (CursorElement[])(object)new CursorElement[2]
{
CursorElement.Create("Confirm", "", confirmAction, (Func<CursorElement, bool>)null, true),
CursorElement.Create("Decline", "", declineAction, (Func<CursorElement, bool>)null, true)
}, (Func<CursorElement, CursorElement, int>[])null);
int num = 0;
ITextElement[] array = (ITextElement[])(object)new ITextElement[2 + text.Length];
ReadOnlySpan<ITextElement> readOnlySpan = new ReadOnlySpan<ITextElement>(text);
readOnlySpan.CopyTo(new Span<ITextElement>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
array[num] = (ITextElement)(object)TextElement.Create(" ");
num++;
array[num] = (ITextElement)(object)val;
num++;
ITextElement[] array2 = array;
BoxedScreen val2 = BoxedScreen.Create(Title, array2);
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen((IScreen)(object)val2, val, false);
}
protected void Notification(Action backAction, params ITextElement[] text)
{
CursorMenu val = CursorMenu.Create(0, '>', (CursorElement[])(object)new CursorElement[1] { CursorElement.Create("Back", "", backAction, (Func<CursorElement, bool>)null, true) }, (Func<CursorElement, CursorElement, int>[])null);
int num = 0;
ITextElement[] array = (ITextElement[])(object)new ITextElement[2 + text.Length];
ReadOnlySpan<ITextElement> readOnlySpan = new ReadOnlySpan<ITextElement>(text);
readOnlySpan.CopyTo(new Span<ITextElement>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
array[num] = (ITextElement)(object)TextElement.Create(" ");
num++;
array[num] = (ITextElement)(object)val;
num++;
ITextElement[] array2 = array;
BoxedScreen val2 = BoxedScreen.Create(Title, array2);
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen((IScreen)(object)val2, val, false);
}
protected void LockedNotification(params ITextElement[] text)
{
BoxedScreen val = BoxedScreen.Create(Title, text);
CursorMenu val2 = CursorMenu.Create(0, '>', (CursorElement[])null, (Func<CursorElement, CursorElement, int>[])null);
((BaseInteractiveApplication<CursorMenu, CursorElement>)(object)this).SwitchScreen((IScreen)(object)val, val2, false);
}
}
public static class InteractiveTerminalManager
{
public static void RegisterApplication<T>(params string[] commands) where T : TerminalApplication, new()
{
for (int i = 0; i < commands.Length; i++)
{
InteractiveTerminalManager.RegisterApplication<T>(commands[i]);
}
}
}
public abstract class TerminalApplication : TerminalApplication
{
protected override string GetApplicationText()
{
return ((ITextElement)base.currentScreen).GetText(51);
}
protected override Action PreviousScreen()
{
return delegate
{
};
}
}
}
namespace tesinormed.FAndCDaveCo.Bank
{
[ES3Serializable]
public record Loan
{
[ES3NonSerializable]
public int DaysSinceIssuance => StartOfRound.Instance.gameStats.daysSpent - IssuanceDate;
[ES3NonSerializable]
public int Interest => CalculateInterest(Principal);
[ES3NonSerializable]
public int Total => Principal + Interest;
[ES3NonSerializable]
public int AmountUnpaid => Total - AmountPaid;
[ES3NonSerializable]
public static readonly Loan None = new Loan(0, 0);
public int IssuanceDate;
public int Principal;
public int AmountPaid;
public static int CalculateInterest(int principal)
{
return (int)((double)principal * SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.InterestAmount));
}
public Loan(int issuanceDate, int principal, int amountPaid = 0)
{
if (issuanceDate < 0)
{
throw new ArgumentOutOfRangeException("issuanceDate", "nonnegative number required");
}
if (principal < 0)
{
throw new ArgumentOutOfRangeException("principal", "nonnegative number required");
}
if (amountPaid < 0)
{
throw new ArgumentOutOfRangeException("amountPaid", "nonnegative number required");
}
IssuanceDate = issuanceDate;
Principal = principal;
AmountPaid = amountPaid;
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("Loan { ");
stringBuilder.Append(string.Format("{0} = {1}, ", "IssuanceDate", IssuanceDate));
stringBuilder.Append(string.Format("{0} = {1}, ", "Principal", Principal));
stringBuilder.Append(string.Format("{0} = {1}", "AmountPaid", AmountPaid));
stringBuilder.Append(" }");
return stringBuilder.ToString();
}
[CompilerGenerated]
protected virtual bool PrintMembers(StringBuilder builder)
{
RuntimeHelpers.EnsureSufficientExecutionStack();
builder.Append("IssuanceDate = ");
builder.Append(IssuanceDate.ToString());
builder.Append(", DaysSinceIssuance = ");
builder.Append(DaysSinceIssuance.ToString());
builder.Append(", Principal = ");
builder.Append(Principal.ToString());
builder.Append(", Interest = ");
builder.Append(Interest.ToString());
builder.Append(", Total = ");
builder.Append(Total.ToString());
builder.Append(", AmountPaid = ");
builder.Append(AmountPaid.ToString());
builder.Append(", AmountUnpaid = ");
builder.Append(AmountUnpaid.ToString());
return true;
}
[CompilerGenerated]
protected Loan(Loan original)
{
IssuanceDate = original.IssuanceDate;
Principal = original.Principal;
AmountPaid = original.AmountPaid;
}
}
}
namespace tesinormed.FAndCDaveCo.Bank.UI
{
public class BankLoanGetTerminal : InteractiveTerminalApplication
{
protected override string Title => "F&C Dave Co. Bank: Get a loan";
public override void Initialization()
{
if (!StartOfRound.Instance.inShipPhase || !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)
{
LockedNotification((ITextElement)TextElement.Create("You can only get a loan while you are in orbit."));
Plugin.Logger.LogDebug((object)"local player tried to get a loan when not in orbit");
return;
}
if (StartOfRound.Instance.isChallengeFile)
{
LockedNotification((ITextElement)TextElement.Create("You cannot get a loan while doing a challenge moon."));
Plugin.Logger.LogDebug((object)"local player tried to get a loan while doing a challenge moon");
return;
}
if (Plugin.Instance.State.Loan.Principal != 0)
{
LockedNotification((ITextElement)TextElement.Create("You can only have one loan at a time."));
Plugin.Logger.LogDebug((object)"local player tried to get a loan when there already was a loan");
return;
}
if (TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled <= 0)
{
LockedNotification((ITextElement)TextElement.Create("Your quota is already fulfilled."));
Plugin.Logger.LogDebug((object)"local player tried to get a loan when quota was already fulfilled");
return;
}
int principal = TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled;
Confirm(delegate
{
GetLoan(principal);
}, (ITextElement)TextElement.Create($"Are you sure you want to get a loan for ${principal}? The total cost will be ${principal + Loan.CalculateInterest(principal)}."));
}
private void GetLoan(int principal)
{
CreditEvents.TakeOutLoan.InvokeServer();
LockedNotification((ITextElement)TextElement.Create($"You have successfully taken out a loan for ${principal}."));
}
}
public class BankLoanInformationTerminal : TerminalApplication
{
public override void Initialization()
{
List<ITextElement> list = new List<ITextElement>();
if (Plugin.Instance.State.Loan.Principal == 0)
{
list.Add((ITextElement)(object)TextElement.Create("You do not currently have an unpaid loan."));
}
else
{
list.Add((ITextElement)(object)TextElement.Create($"You currently have an unpaid loan from {Plugin.Instance.State.Loan.DaysSinceIssuance} day(s) ago (day {Plugin.Instance.State.Loan.IssuanceDate})."));
list.Add((ITextElement)(object)TextElement.Create($"The loan is for ${Plugin.Instance.State.Loan.Principal} with ${Plugin.Instance.State.Loan.Interest} added as interest."));
list.Add((ITextElement)(object)TextElement.Create($"Amount paid: ${Plugin.Instance.State.Loan.AmountPaid}, amount left: ${Plugin.Instance.State.Loan.AmountUnpaid}, total: ${Plugin.Instance.State.Loan.Total}."));
if (Plugin.Instance.State.Loan.DaysSinceIssuance >= SyncedEntry<int>.op_Implicit(Plugin.Instance.Config.PenaltyStartDaysFromIssuance))
{
list.Add((ITextElement)(object)TextElement.Create($"{(int)(SyncedEntry<double>.op_Implicit(Plugin.Instance.Config.PenaltyAmount) * 100.0)}% of your credits are currently being garnished each day."));
}
}
BoxedScreen currentScreen = BoxedScreen.Create("F&C Dave Co. Bank: Loan information", list.ToArray());
((TerminalApplication)this).currentScreen = (IScreen)(object)currentScreen;
}
}
public class BankLoanPaymentTerminal : InteractiveTerminalApplication
{
protected override string Title => "F&C Dave Co. Bank: Submit loan payment";
private CursorElement CreateCursorElement(double amount)
{
int cost = Math.Min((int)((double)Plugin.Instance.State.Loan.Total * amount), Plugin.Instance.State.Loan.AmountUnpaid);
return CursorElement.Create($"{(int)(amount * 100.0)}% (${cost})", "", (Action)delegate
{
ConfirmPayLoan(cost);
}, (Func<CursorElement, bool>)((CursorElement _) => ((TerminalApplication)this).terminal.groupCredits >= cost), true);
}
public override void Initialization()
{
if (Plugin.Instance.State.Loan.Principal == 0)
{
LockedNotification((ITextElement)TextElement.Create("You can only submit a loan payment if you have a loan."));
Plugin.Logger.LogDebug((object)"local player tried to submit a loan payment when there was no loan");
return;
}
(base.MainScreen, base.MainCursorMenu) = Selection("Pick an amount to pay towards the loan.", CreateCursorElement(0.1), CreateCursorElement(0.25), CreateCursorElement(0.5), CreateCursorElement(0.75), CreateCursorElement(1.0));
}
private void ConfirmPayLoan(int amount)
{
if (((TerminalApplication)this).terminal.groupCredits < amount)
{
Notification(base.PreviousScreenAction, (ITextElement)TextElement.Create($"You do not have enough credits to submit a payment of ${amount} for the loan."));
return;
}
Confirm(delegate
{
PayLoan(amount);
}, base.PreviousScreenAction, (ITextElement)TextElement.Create($"Are you sure you want to pay ${amount}?"));
}
private void PayLoan(int amount)
{
CreditEvents.DeductGroupCredits.SendServer(amount);
if (Plugin.Instance.State.Loan.AmountUnpaid - amount == 0)
{
Plugin.Instance.State.Loan = Loan.None;
Plugin.Logger.LogDebug((object)"loan paid off fully; removed");
LockedNotification((ITextElement)TextElement.Create("You have paid off your loan fully."));
return;
}
Plugin.Instance.State.MutateLoan(delegate(Loan loan)
{
loan.AmountPaid += amount;
});
Plugin.Logger.LogDebug((object)$"paid {amount} towards the current loan");
LockedNotification((ITextElement)TextElement.Create($"You have paid ${amount}; ${Plugin.Instance.State.Loan.AmountUnpaid} must still be paid."));
}
}
internal static class BankTerminal
{
internal const string Title = "F&C Dave Co. Bank";
}
}
namespace System.Runtime.CompilerServices
{
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}