Decompiled source of ApartmentRent v0.9.1

ApartmentRent.dll

Decompiled 7 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SOD.Common;
using SOD.Common.Extensions;
using SOD.Common.Helpers;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UniverseLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ApartmentRent")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyDescription("Changes apartments into rentals with ongoing costs")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4972100ffad60d48e06f371d93aac0f7efb18621")]
[assembly: AssemblyProduct("ApartmentRent")]
[assembly: AssemblyTitle("ApartmentRent")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ApartmentRent
{
	[BepInPlugin("ApartmentRent", "ApartmentRent", "1.0.0")]
	public class ApartmentRentPlugin : BasePlugin
	{
		private enum RentalOwingFrequencyChoices
		{
			Hourly,
			Daily,
			Weekly,
			Monthly
		}

		[HarmonyPatch(typeof(MainMenuController), "Start")]
		internal class MainMenuController_Start
		{
			[HarmonyPostfix]
			internal static void Postfix()
			{
				Transform val = GameObject.Find("MenuCanvas").transform.Find("MainMenu/MainMenuPanel/Credits");
				if ((Object)(object)val != (Object)null)
				{
					ApartmentClosedNoteRepayButtonTemplate = ((Component)Object.Instantiate<Transform>(val)).gameObject;
					Button component = ApartmentClosedNoteRepayButtonTemplate.GetComponent<Button>();
					Object.DestroyImmediate((Object)(object)component);
				}
			}
		}

		[HarmonyPatch(typeof(NewDoor), "Barge")]
		internal class NewDoor_Barge
		{
			[HarmonyPrefix]
			internal static bool Prefix(NewDoor __instance, Actor barger)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Expected O, but got Unknown
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				if (foreclosedDoorIDs.ContainsKey(((Object)__instance).GetInstanceID()) && foreclosedDoorIDs[((Object)__instance).GetInstanceID()] && barger.isPlayer)
				{
					ManualLogSource pluginLogger = PluginLogger;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(28, 0, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Barging blocked: Foreclosed!");
					}
					pluginLogger.LogInfo(val);
					AudioController.Instance.PlayWorldOneShot(AudioControls.Instance.bargeDoorContact, barger, barger.currentNode, barger.lookAtThisTransform.position, (Interactable)null, (List<FMODParam>)null, 1f, (List<NewNode>)null, false, (SoundMaterialOverride)null, false);
					Player.Instance.TransformPlayerController(GameplayControls.Instance.bargeDoorFail, (PlayerTransitionPreset)null, __instance.doorInteractable, (Transform)null, false, false, 0f, false, default(Vector3), 1f, true);
					InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, "The door is reinforced and jammed shut...", (Icon)8, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(ActionController), "OpenDoor")]
		internal class ActionController_OpenDoor
		{
			[HarmonyPrefix]
			internal static bool Prefix(Interactable what, Actor who)
			{
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Expected O, but got Unknown
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				if (what.objectRef != null)
				{
					NewDoor val = (NewDoor)((dynamic)what.objectRef).Cast<NewDoor>();
					if (foreclosedDoorIDs.ContainsKey(((Object)val).GetInstanceID()) && foreclosedDoorIDs[((Object)val).GetInstanceID()] && who.isPlayer)
					{
						ManualLogSource pluginLogger = PluginLogger;
						bool flag = default(bool);
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(44, 0, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Door foreclosed, blocking door from opening!");
						}
						pluginLogger.LogInfo(val2);
						InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, "The door is jammed shut...", (Icon)8, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(InterfaceController), "SpawnWindow")]
		internal class InterfaceController_SpawnWindow
		{
			[HarmonyPostfix]
			internal static void Postfix(Interactable passedInteractable, InfoWindow __result)
			{
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Expected O, but got Unknown
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_0196: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				if (passedInteractable == null)
				{
					return;
				}
				bool flag = default(bool);
				foreach (var (residenceNumber, list2) in foreclosedInteractables)
				{
					foreach (Interactable item in list2)
					{
						if (item.id != passedInteractable.id)
						{
							continue;
						}
						ManualLogSource pluginLogger = PluginLogger;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 0, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found the interactable door note!");
						}
						pluginLogger.LogInfo(val);
						NewAddress apartment2 = EnumerableExtensions.Where<NewAddress>(Player.Instance.apartmentsOwned, (Func<NewAddress, bool>)((NewAddress apartment) => ((NewGameLocation)apartment).residenceNumber == residenceNumber)).First();
						int num2 = Mathf.RoundToInt((float)((NewGameLocation)apartment2).GetPrice(false) * RentalPriceScalingFactor.Value) * ((!OweBackpayToUnlock.Value) ? 1 : missedPayments[residenceNumber]);
						GameObject gameObject = Object.Instantiate<GameObject>(ApartmentClosedNoteRepayButtonTemplate, GameObject.Find("GameCanvas/WindowCanvas/Note/Page/Scroll View/Viewport/Summary/Page").transform).gameObject;
						RectTransform component = gameObject.GetComponent<RectTransform>();
						component.anchoredPosition += new Vector2(15f, 160f);
						((TMP_Text)((Component)gameObject.transform.Find("Text")).GetComponent<TextMeshProUGUI>()).SetText($"Repay and unlock ${num2}", true);
						if (GameplayController.Instance.money >= num2)
						{
							Button val2 = gameObject.gameObject.AddComponent<Button>();
							((UnityEventBase)val2.onClick).RemoveAllListeners();
							Il2CppExtensions.AddListener((UnityEvent)(object)val2.onClick, (Action)delegate
							{
								PayToUnlock(apartment2);
								__result.CloseWindow(true);
							});
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnGameLocationChange")]
		internal class Player_OnGameLocationChange
		{
			[HarmonyPostfix]
			internal static void Prefix()
			{
				Player instance = Player.Instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					NewGameLocation previousGameLocation = ((Actor)instance).previousGameLocation;
					obj = ((previousGameLocation != null) ? previousGameLocation.thisAsAddress : null);
				}
				if ((Object)obj != (Object)null && foreclosedAddresses.Contains(((NewGameLocation)((Actor)Player.Instance).previousGameLocation.thisAsAddress).residenceNumber))
				{
					bool flag = (Object)(object)EnumerableExtensions.Where<NewAddress>(Player.Instance.apartmentsOwned, (Func<NewAddress, bool>)((NewAddress apartment) => (Object)(object)apartment == (Object)(object)((Actor)Player.Instance).previousGameLocation.thisAsAddress)).FirstOrDefault() != (Object)null;
					bool flag2 = (Object)(object)EnumerableExtensions.Where<NewAddress>(Player.Instance.apartmentsOwned, (Func<NewAddress, bool>)((NewAddress apartment) => (Object)(object)apartment == (Object)(object)((Actor)Player.Instance).currentGameLocation.thisAsAddress)).FirstOrDefault() != (Object)null;
					if (flag && !flag2)
					{
						LockOutApartment(((Actor)Player.Instance).previousGameLocation.thisAsAddress);
					}
				}
			}
		}

		private static ConfigEntry<RentalOwingFrequencyChoices> RentalOwingFrequency;

		private static ConfigEntry<float> RentalPriceScalingFactor;

		private static ConfigEntry<int> MissedPaymentGraceAmount;

		private static ConfigEntry<bool> OweBackpayToUnlock;

		private static ApartmentRentPlugin instance;

		public static ManualLogSource PluginLogger;

		public static List<int> foreclosedAddresses = new List<int>();

		public static Dictionary<int, bool> foreclosedDoorIDs = new Dictionary<int, bool>();

		public static Dictionary<int, int> missedPayments = new Dictionary<int, int>();

		public static Dictionary<int, List<Interactable>> foreclosedInteractables = new Dictionary<int, List<Interactable>>();

		private static GameObject ApartmentClosedNoteRepayButtonTemplate;

		public override void Load()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			PluginLogger = ((BasePlugin)this).Log;
			instance = this;
			ManualLogSource pluginLogger = PluginLogger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ApartmentRent");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			pluginLogger.LogInfo(val);
			Harmony val2 = new Harmony("ApartmentRent");
			val2.PatchAll();
			ManualLogSource pluginLogger2 = PluginLogger;
			val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ApartmentRent");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is patched!");
			}
			pluginLogger2.LogInfo(val);
			RentalOwingFrequency = ((BasePlugin)this).Config.Bind<RentalOwingFrequencyChoices>("General", "How often should rent be charged?", RentalOwingFrequencyChoices.Weekly, (ConfigDescription)null);
			RentalPriceScalingFactor = ((BasePlugin)this).Config.Bind<float>("General", "What percentage of the inital purchase cost should be charged as rent? (1 is 100% of the inital cost)", 0.1f, (ConfigDescription)null);
			MissedPaymentGraceAmount = ((BasePlugin)this).Config.Bind<int>("General", "How many payments can be missed before the apartment is closed?", 1, (ConfigDescription)null);
			OweBackpayToUnlock = ((BasePlugin)this).Config.Bind<bool>("General", "Should payments keep being owed while locked out?", true, (ConfigDescription)null);
			Lib.Time.OnHourChanged += TimePassedCheck;
			Lib.Time.OnDayChanged += TimePassedCheck;
			Lib.Time.OnMonthChanged += TimePassedCheck;
			Lib.SaveGame.OnAfterSave += OnAfterSave;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
		}

		public static void GiveMoney(int amount)
		{
			GameplayController.Instance.AddMoney(amount, false, "Added money");
		}

		private void TimePassedCheck(object sender, TimeChangedArgs args)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			RentalOwingFrequencyChoices value = RentalOwingFrequency.Value;
			if (args.IsDayChanged && value == RentalOwingFrequencyChoices.Daily)
			{
				ActionRentDue();
			}
			else if (args.IsDayChanged && value == RentalOwingFrequencyChoices.Weekly)
			{
				TimeData current = args.Current;
				if (((TimeData)(ref current)).Day == 0)
				{
					ActionRentDue();
				}
			}
			else if (args.IsMonthChanged && value == RentalOwingFrequencyChoices.Monthly)
			{
				ActionRentDue();
			}
			else if (args.IsHourChanged && value == RentalOwingFrequencyChoices.Hourly)
			{
				ActionRentDue();
			}
		}

		public static void ActionRentDue()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<NewAddress> enumerator = Player.Instance.apartmentsOwned.GetEnumerator();
			while (enumerator.MoveNext())
			{
				NewAddress current = enumerator.Current;
				int num = Mathf.RoundToInt((float)((NewGameLocation)current).GetPrice(false) * RentalPriceScalingFactor.Value);
				bool flag = foreclosedAddresses.Contains(((NewGameLocation)current).residenceNumber);
				if (GameplayController.Instance.money >= num)
				{
					GameplayController.Instance.AddMoney(-num, false, "Rent paid for " + ((Object)current).name);
					InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, $"Apartment rent paid: {((Object)current).name} - {num}", (Icon)8, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
				}
				else if (flag)
				{
					missedPayments[((NewGameLocation)current).residenceNumber]++;
				}
				else if (!flag)
				{
					if (!missedPayments.ContainsKey(((NewGameLocation)current).residenceNumber))
					{
						missedPayments[((NewGameLocation)current).residenceNumber] = 0;
					}
					missedPayments[((NewGameLocation)current).residenceNumber]++;
					if (missedPayments[((NewGameLocation)current).residenceNumber] > MissedPaymentGraceAmount.Value)
					{
						foreclosedAddresses.Add(((NewGameLocation)current).residenceNumber);
						LockOutApartment(current);
						InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, "Rental payments missed, apartment locked out: " + ((Object)current).name, (Icon)8, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
					}
					else
					{
						InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, $"Rental payments missed, {MissedPaymentGraceAmount.Value - (missedPayments[((NewGameLocation)current).residenceNumber] - 2)} grace periods remain", (Icon)8, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
					}
				}
			}
		}

		private static void LockOutApartment(NewAddress apartment)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Actor)Player.Instance).currentGameLocation.thisAsAddress == (Object)(object)apartment)
			{
				return;
			}
			Enumerator<NodeAccess> enumerator = ((NewGameLocation)apartment).entrances.GetEnumerator();
			while (enumerator.MoveNext())
			{
				NodeAccess current = enumerator.Current;
				if ((Object)(object)((current != null) ? current.door : null) != (Object)null && !foreclosedDoorIDs.GetValueOrDefault(((Object)current.door).GetInstanceID(), defaultValue: false))
				{
					current.door.SetOpen(0f, (Actor)null, true, 1f);
					Vector3 val = ((Component)current.door).gameObject.transform.TransformPoint(new Vector3(0f, 0f, -0.11f));
					Interactable val2 = InteractableCreator.Instance.CreateWorldInteractable(InteriorControls.Instance.doorWedge, (Human)(object)Player.Instance, (Human)null, (Human)null, val, current.door.peekInteractable.wEuler, (List<Passed>)null, (Object)null, "");
					val2.locked = true;
					current.door.SetJammed(true, val2, true);
					Vector3 val3 = ((Component)current.door).gameObject.transform.TransformPoint(new Vector3(0f, 1.5f, -0.11f));
					Vector3 val4 = ((Component)current.door).gameObject.transform.TransformPoint(new Vector3(0f, 1.5f, 0.01f));
					Interactable item = InteractableCreator.Instance.CreateWorldInteractable(InteriorControls.Instance.note, (Human)(object)Player.Instance, (Human)null, (Human)null, val3, current.door.peekInteractable.wEuler + new Vector3(90f, 0f, 0f), (List<Passed>)null, (Object)null, "fdf6930b-0c20-434f-a181-dd4975944331");
					Interactable item2 = InteractableCreator.Instance.CreateWorldInteractable(InteriorControls.Instance.note, (Human)(object)Player.Instance, (Human)null, (Human)null, val4, current.door.peekInteractable.wEuler + new Vector3(270f, 0f, 0f), (List<Passed>)null, (Object)null, "fdf6930b-0c20-434f-a181-dd4975944331");
					foreclosedInteractables[((NewGameLocation)apartment).residenceNumber] = new List<Interactable> { val2, item, item2 };
					foreclosedDoorIDs[((Object)current.door).GetInstanceID()] = true;
				}
			}
		}

		public static void PayToUnlock(NewAddress apartment)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource pluginLogger = PluginLogger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(11, 0, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PayToUnlock");
			}
			pluginLogger.LogInfo(val);
			if (!foreclosedAddresses.Contains(((NewGameLocation)apartment).residenceNumber))
			{
				return;
			}
			int num = Mathf.RoundToInt((float)((NewGameLocation)apartment).GetPrice(false) * RentalPriceScalingFactor.Value) * ((!OweBackpayToUnlock.Value) ? 1 : missedPayments[((NewGameLocation)apartment).residenceNumber]);
			if (GameplayController.Instance.money < num)
			{
				return;
			}
			GameplayController.Instance.AddMoney(-num, false, "Backpaid rent owing for " + ((Object)apartment).name);
			InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, $"Apartment unlocked: {((Object)apartment).name} - {num}", (Icon)8, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
			missedPayments[((NewGameLocation)apartment).residenceNumber] = 0;
			foreclosedAddresses.Remove(((NewGameLocation)apartment).residenceNumber);
			Enumerator<NodeAccess> enumerator = ((NewGameLocation)apartment).entrances.GetEnumerator();
			while (enumerator.MoveNext())
			{
				NodeAccess current = enumerator.Current;
				if ((Object)(object)((current != null) ? current.door : null) != (Object)null)
				{
					current.door.SetJammed(false, (Interactable)null, true);
					foreclosedDoorIDs.Remove(((Object)current.door).GetInstanceID());
				}
			}
			foreach (Interactable item in foreclosedInteractables[((NewGameLocation)apartment).residenceNumber])
			{
				item.SafeDelete(false);
			}
			foreclosedInteractables.Remove(((NewGameLocation)apartment).residenceNumber);
		}

		private void OnAfterLoad(object sender, SaveGameArgs e)
		{
			string savePath = GetSavePath(e.FilePath);
			if (!File.Exists(savePath))
			{
				return;
			}
			RentSaveFile rentSaveFile = JsonSerializer.Deserialize<RentSaveFile>(File.ReadAllText(savePath));
			foreach (ApartmentSaveFile addressSaveFile in rentSaveFile.apartmentSaveFiles)
			{
				NewAddress val = EnumerableExtensions.Where<NewAddress>(Player.Instance.apartmentsOwned, (Func<NewAddress, bool>)((NewAddress apartment) => ((NewGameLocation)apartment).residenceNumber == addressSaveFile.residenceNumber)).FirstOrDefault();
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreclosedAddresses.Add(addressSaveFile.residenceNumber);
				missedPayments[addressSaveFile.residenceNumber] = addressSaveFile.missedPayments;
				foreclosedInteractables[addressSaveFile.residenceNumber] = new List<Interactable>();
				foreach (int interactableId in addressSaveFile.interactableIds)
				{
					foreclosedInteractables[addressSaveFile.residenceNumber].Add(CityData.Instance.savableInteractableDictionary[interactableId]);
				}
				Enumerator<NodeAccess> enumerator3 = ((NewGameLocation)val).entrances.GetEnumerator();
				while (enumerator3.MoveNext())
				{
					NodeAccess current2 = enumerator3.Current;
					foreclosedDoorIDs[((Object)current2.door).GetInstanceID()] = true;
				}
			}
		}

		private void OnAfterSave(object sender, SaveGameArgs e)
		{
			string savePath = GetSavePath(e.FilePath);
			RentSaveFile rentSaveFile = new RentSaveFile();
			foreach (int foreclosedAddress in foreclosedAddresses)
			{
				ApartmentSaveFile apartmentSaveFile = new ApartmentSaveFile
				{
					residenceNumber = foreclosedAddress,
					missedPayments = (missedPayments.ContainsKey(foreclosedAddress) ? missedPayments[foreclosedAddress] : 0)
				};
				foreach (Interactable item in foreclosedInteractables[foreclosedAddress])
				{
					apartmentSaveFile.interactableIds.Add(item.id);
				}
				rentSaveFile.apartmentSaveFiles.Add(apartmentSaveFile);
			}
			string contents = JsonSerializer.Serialize(rentSaveFile, new JsonSerializerOptions
			{
				WriteIndented = true
			});
			File.WriteAllText(savePath, contents);
		}

		private string GetSavePath(string savePath)
		{
			string uniqueString = Lib.SaveGame.GetUniqueString(savePath);
			return Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "ApartmentRental_" + uniqueString + ".json");
		}
	}
	[Serializable]
	internal class RentSaveFile
	{
		public int version { get; } = 1;


		public List<ApartmentSaveFile> apartmentSaveFiles { get; set; } = new List<ApartmentSaveFile>();

	}
	[Serializable]
	internal class ApartmentSaveFile
	{
		public int residenceNumber { get; set; }

		public int missedPayments { get; set; }

		public List<int> interactableIds { get; set; } = new List<int>();

	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ApartmentRent";

		public const string PLUGIN_NAME = "ApartmentRent";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}