Decompiled source of FAndCDaveCo v3.0.1

BepInEx/plugins/tesinormed.FAndCDaveCo.dll

Decompiled 2 weeks ago
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 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("3.0.1.0")]
[assembly: AssemblyInformationalVersion("3.0.1+7c9733f6f9b39ce8c174871ec60ada29d10bc618")]
[assembly: AssemblyProduct("FAndCDaveCo")]
[assembly: AssemblyTitle("tesinormed.FAndCDaveCo")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.1.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
	{
		public readonly ConfigEntry<bool> GameDisableDeathCreditPenalty;

		public readonly ConfigEntry<double> EconomicBasePremium;

		public readonly ConfigEntry<double> EconomicDeductible;

		public readonly ConfigEntry<double> EconomicDeductibleMaximum;

		public readonly ConfigEntry<double> EconomicDeductibleMinimum;

		public readonly ConfigEntry<double> StandardBasePremium;

		public readonly ConfigEntry<double> StandardDeductible;

		public readonly ConfigEntry<double> StandardDeductibleMaximum;

		public readonly ConfigEntry<double> StandardDeductibleMinimum;

		public readonly ConfigEntry<double> BespokeBasePremium;

		public readonly ConfigEntry<int> CoverageOption00;

		public readonly ConfigEntry<int> CoverageOption01;

		public readonly ConfigEntry<int> CoverageOption02;

		public readonly ConfigEntry<int> CoverageOption03;

		public readonly ConfigEntry<int> CoverageOption04;

		public readonly ConfigEntry<int> CoverageOption05;

		public readonly ConfigEntry<int> CoverageOption06;

		public readonly ConfigEntry<int> CoverageOption07;

		public readonly ConfigEntry<int> CoverageOption08;

		public readonly ConfigEntry<int> CoverageOption09;

		public readonly ConfigEntry<int> CoverageOption10;

		public readonly ConfigEntry<int> ClaimRetentionDays;

		public readonly ConfigEntry<double> ClaimPremiumIncrease;

		public readonly ConfigEntry<int> PenaltyStartDaysFromIssuance;

		public readonly ConfigEntry<double> PenaltyAmount;

		public readonly ConfigEntry<double> InterestAmount;

		public Config(ConfigFile configFile)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0061: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_0095: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00c9: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00fd: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0131: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0165: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_0199: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_01cd: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Expected O, but got Unknown
			//IL_0201: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Expected O, but got Unknown
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Expected O, but got Unknown
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Expected O, but got Unknown
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Expected O, but got Unknown
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Expected O, but got Unknown
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Expected O, but got Unknown
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Expected O, but got Unknown
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Expected O, but got Unknown
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Expected O, but got Unknown
			//IL_03a0: Expected O, but got Unknown
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Expected O, but got Unknown
			//IL_03cd: Expected O, but got Unknown
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Expected O, but got Unknown
			//IL_03f9: Expected O, but got Unknown
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Expected O, but got Unknown
			//IL_042d: Expected O, but got Unknown
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Expected O, but got Unknown
			//IL_0461: Expected O, but got Unknown
			GameDisableDeathCreditPenalty = configFile.Bind<bool>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<double>(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 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option00"), 150, (ConfigDescription)null);
			CoverageOption01 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option01"), 400, (ConfigDescription)null);
			CoverageOption02 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option02"), 800, (ConfigDescription)null);
			CoverageOption03 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option03"), 1500, (ConfigDescription)null);
			CoverageOption04 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option04"), 2250, (ConfigDescription)null);
			CoverageOption05 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option05"), 3600, (ConfigDescription)null);
			CoverageOption06 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option06"), 5500, (ConfigDescription)null);
			CoverageOption07 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option07"), 8000, (ConfigDescription)null);
			CoverageOption08 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option08"), 11125, (ConfigDescription)null);
			CoverageOption09 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option09"), 15250, (ConfigDescription)null);
			CoverageOption10 = configFile.Bind<int>(new ConfigDefinition("Insurance.Coverage", "Option10"), 18000, (ConfigDescription)null);
			ClaimPremiumIncrease = configFile.Bind<double>(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 = configFile.Bind<int>(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 = configFile.Bind<int>(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 = configFile.Bind<double>(new ConfigDefinition("Bank.Loan.Penalty", "Amount"), 0.1, new ConfigDescription("Percent of the credits garnished each day", (AcceptableValueBase)null, Array.Empty<object>()));
			InterestAmount = configFile.Bind<double>(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>()));
		}
	}
	[BepInPlugin("tesinormed.FAndCDaveCo", "FAndCDaveCo", "3.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("LethalNetworkAPI", "3.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 3.0.1 loaded");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "tesinormed.FAndCDaveCo";

		public const string PLUGIN_NAME = "FAndCDaveCo";

		public const string PLUGIN_VERSION = "3.0.1";
	}
}
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> pair2 in Plugin.Instance.State.Claims.Where((KeyValuePair<int, Claim> pair) => StartOfRound.Instance.gameStats.daysSpent - pair.Key > Plugin.Instance.Config.ClaimRetentionDays.Value))
			{
				Plugin.Instance.State.MutateClaims(delegate(Dictionary<int, Claim> claims)
				{
					claims.Remove(pair2.Key);
				});
				Plugin.Logger.LogDebug((object)$"deleted old claim from day {pair2.Key}");
			}
			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 >= Plugin.Instance.Config.PenaltyStartDaysFromIssuance.Value)
			{
				int num = Math.Min((int)((double)Plugin.Terminal.groupCredits * Plugin.Instance.Config.PenaltyAmount.Value), 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.Terminal.groupCredits = 0;
					Plugin.Logger.LogError((object)$"could not completely deduct {amount} credits, balance set to zero");
				}
				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_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: 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
				{
					GameObject val2 = Object.Instantiate<GameObject>(val.spawnPrefab, ((Component)playerController).transform.position, Quaternion.identity, StartOfRound.Instance.elevatorTransform);
					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)
				GrabbableObject component = NetworkObjectReference.op_Implicit(value.Item1).GetComponent<GrabbableObject>();
				component.SetScrapValue(value.Item2);
				GameNetworkManager.Instance.localPlayerController.SetItemInElevator(true, true, component);
			}, (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)(Plugin.Instance.Config.PenaltyAmount.Value * 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 != 0)
				{
					return Plugin.Instance.Config.GameDisableDeathCreditPenalty.Value;
				}
				return false;
			}
		}

		public Policy Policy
		{
			get
			{
				return _policy.Value;
			}
			set
			{
				_policy.Value = value;
			}
		}

		public Dictionary<int, Claim> Claims
		{
			get
			{
				return _claims.Value ?? new Dictionary<int, Claim>();
			}
			set
			{
				_claims.Value = value;
			}
		}

		public Dictionary<int, Claim> ClaimedClaims => Claims.Where((KeyValuePair<int, Claim> pair) => pair.Value.Claimed).ToDictionary();

		public Dictionary<int, Claim> UnclaimedClaims => Claims.Where((KeyValuePair<int, Claim> pair) => !pair.Value.Claimed).ToDictionary();

		public double FractionalPremiumIncrease => (double)ClaimedClaims.Count * Plugin.Instance.Config.ClaimPremiumIncrease.Value;

		public int TotalPremium => CalculateTotalPremium(Policy.BasePremium);

		public Loan Loan
		{
			get
			{
				return _loan.Value;
			}
			set
			{
				_loan.Value = value;
			}
		}

		private readonly LNetworkVariable<Policy> _policy = LNetworkVariable<Policy>.Connect("Policy", default(Policy), (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<Loan>.Connect("Loan", default(Loan), (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, Policy.None, true);
				Claims = SaveLoadHandler.LoadData<Dictionary<int, Claim>>("Claims", (SaveLocation)0, (Dictionary<int, Claim>)null, true) ?? new Dictionary<int, Claim>();
				Loan = SaveLoadHandler.LoadData<Loan>("Loan", (SaveLocation)0, Loan.None, true);
			}
		}

		internal void Reset()
		{
			Policy = Policy.None;
			Claims = new Dictionary<int, Claim>();
			Loan = 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.ToString());
			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.ToString());
			return true;
		}
	}
}
namespace tesinormed.FAndCDaveCo.Insurance
{
	public record struct 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();
		}
	}
	public record struct Policy
	{
		[ES3NonSerializable]
		public int BasePremium => Tier switch
		{
			PolicyTier.HighDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.EconomicBasePremium.Value), 
			PolicyTier.LowDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.StandardBasePremium.Value), 
			PolicyTier.NoDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.BespokeBasePremium.Value), 
			_ => 0, 
		};

		[ES3NonSerializable]
		public double DeductiblePercent => Tier switch
		{
			PolicyTier.HighDeductible => Plugin.Instance.Config.EconomicDeductible.Value, 
			PolicyTier.LowDeductible => Plugin.Instance.Config.StandardDeductible.Value, 
			_ => 0.0, 
		};

		[ES3NonSerializable]
		public int DeductibleMinimum => Tier switch
		{
			PolicyTier.HighDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.EconomicDeductibleMinimum.Value), 
			PolicyTier.LowDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.StandardDeductibleMinimum.Value), 
			_ => 0, 
		};

		[ES3NonSerializable]
		public int DeductibleMaximum => Tier switch
		{
			PolicyTier.HighDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.EconomicDeductibleMaximum.Value), 
			PolicyTier.LowDeductible => (int)Math.Floor((double)Coverage * Plugin.Instance.Config.StandardDeductibleMaximum.Value), 
			_ => 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]
		private bool PrintMembers(StringBuilder builder)
		{
			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;
		}
	}
	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)
		{
			return CursorElement.Create($"Day {day}: ${claim.Value}", "", (Action)delegate
			{
				ConfirmClaim(day, claim);
			}, (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(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)
		{
			int deductible = Plugin.Instance.State.Policy.CalculateDeductible(claim.Value);
			int payout = Plugin.Instance.State.Policy.CalculatePayout(claim.Value);
			Confirm(delegate
			{
				ProcessClaim(day, deductible, payout, claim);
			}, delegate
			{
				ConfirmDeleteClaim(day);
			}, (ITextElement[])(object)new ITextElement[3]
			{
				(ITextElement)TextElement.Create($"Are you sure you want to confirm this claim? You will need to pay a deductible of ${deductible}."),
				(ITextElement)TextElement.Create($"Your premiums will increase by {(int)(Plugin.Instance.State.FractionalPremiumIncrease * 100.0)}%."),
				(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)
		{
			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] = claim with
				{
					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)
		{
			return CursorElement.Create($"${policy.Coverage}", "", (Action)delegate
			{
				ConfirmEverything(policy);
			}, (Func<CursorElement, bool>)((CursorElement _) => ((TerminalApplication)this).terminal.groupCredits >= Plugin.Instance.State.CalculateTotalPremium(policy)), true);
		}

		public override void Initialization()
		{
			if (StartOfRound.Instance.isChallengeFile)
			{
				LockedNotification((ITextElement)TextElement.Create("You cannot 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(Plugin.Instance.Config.CoverageOption00.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption01.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption02.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption03.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption04.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption05.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption06.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption07.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption08.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption09.Value)), CreateCoverageCursorElement(policyTier.CreatePolicy(Plugin.Instance.Config.CoverageOption10.Value)));
		}

		private void ConfirmEverything(Policy policy)
		{
			if (policy == 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(policy))
			{
				Notification(base.PreviousScreenAction, (ITextElement)TextElement.Create("You do not have enough credits to purchase this policy."));
				return;
			}
			Confirm(delegate
			{
				SetEverything(policy, Plugin.Instance.State.CalculateTotalPremium(policy));
			}, base.PreviousScreenAction, (ITextElement)TextElement.Create($"Are you sure you want to pick {policy.Tier.ToFriendlyString()} (${policy.Coverage})?"), (ITextElement)TextElement.Create((policy.DeductiblePercent == 0.0) ? "This policy has no deductibles." : $"The deductibles are {(int)(policy.DeductiblePercent * 100.0)}%, with a minimum of ${policy.DeductibleMinimum} and a maximum of ${policy.DeductibleMaximum}."), (ITextElement)TextElement.Create($"You will be charged ${Plugin.Instance.State.CalculateTotalPremium(policy)}."));
		}

		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
{
	public record struct 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 * Plugin.Instance.Config.InterestAmount.Value);
		}

		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]
		private bool PrintMembers(StringBuilder builder)
		{
			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;
		}
	}
}
namespace tesinormed.FAndCDaveCo.Bank.UI
{
	public class BankLoanGetTerminal : InteractiveTerminalApplication
	{
		protected override string Title => "F&C Dave Co. Bank: Take out a loan";

		public override void Initialization()
		{
			if (!StartOfRound.Instance.inShipPhase || !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)
			{
				LockedNotification((ITextElement)TextElement.Create("You can only take out a loan while you are in orbit."));
				return;
			}
			if (StartOfRound.Instance.isChallengeFile)
			{
				LockedNotification((ITextElement)TextElement.Create("You cannot take out a loan while doing a challenge moon."));
				return;
			}
			if (Plugin.Instance.State.Loan.Principal != 0)
			{
				LockedNotification((ITextElement)TextElement.Create("You can only take out one loan at a time."));
				return;
			}
			if (TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled <= 0)
			{
				LockedNotification((ITextElement)TextElement.Create("Your quota is already fulfilled."));
				return;
			}
			int principal = TimeOfDay.Instance.profitQuota - TimeOfDay.Instance.quotaFulfilled;
			Confirm(delegate
			{
				GetLoan(principal);
			}, (ITextElement)TextElement.Create($"Are you sure you want to take out 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 >= Plugin.Instance.Config.PenaltyStartDaysFromIssuance.Value)
				{
					list.Add((ITextElement)(object)TextElement.Create($"{(int)(Plugin.Instance.Config.PenaltyAmount.Value * 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 do not have a loan taken out."));
				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} towards 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)
		{
		}
	}
}