Decompiled source of ShadowsOfDoubtExpanded v1.0.0

ShadowsOfDoubtExpanded.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("ShadowsOfDoubtExpanded")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShadowsOfDoubtExpanded")]
[assembly: AssemblyTitle("ShadowsOfDoubtExpanded")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ShadowsOfDoubtExpanded
{
	public class BrokerKillerDefinition : KillerMODefinition
	{
		public const string MO_NAME = "MO_BrokerKiller_Closer";

		private static readonly string[] WealthTraitNames = new string[3] { "Quirk-StatusWealthy", "Quirk-StatusElite", "Principle-Capitalist" };

		private static readonly string[] MarkTraitNames = new string[9] { "Char-Greedy", "Char-Extravagant", "Char-Reckless", "Char-Impulsive", "Char-Trusting", "Char-Boastful", "Affliction-GamblingAddict", "Interest-Poker", "Secret-SecretMoneyStash" };

		public const float MARK_WEIGHT = 4f;

		public override string MOName => "MO_BrokerKiller_Closer";

		public static string SuicideNoteTextID { get; private set; }

		protected override void ConfigureMO(MurderMO mo, Toolbox toolbox)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Expected O, but got Unknown
			mo.baseDifficulty = 2;
			mo.allowHome = true;
			mo.allowWork = true;
			mo.allowPublic = false;
			mo.allowStreets = false;
			mo.allowDen = false;
			mo.acquaintedSuitabilityBoost = 0;
			mo.likeSuitabilityBoost = 0;
			mo.attractedToSuitabilityBoost = 0;
			mo.sameWorkplaceBoost = 0;
			mo.murdererIsTenantBoost = 0;
			List<CharacterTrait> list = new List<CharacterTrait>();
			string[] wealthTraitNames = WealthTraitNames;
			foreach (string traitName in wealthTraitNames)
			{
				CharacterTrait val = FindTrait(toolbox, traitName);
				if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
				{
					list.Add(val);
				}
			}
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(30, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Resolved ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(WealthTraitNames.Length);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" wealth trait(s).");
			}
			logger.LogInfo(val2);
			if (list.Count > 0)
			{
				mo.victimTraitModifiers.Add(RequiredAnyOf(list));
			}
			else
			{
				SoDExpandedPlugin.Logger.LogWarning((object)("[" + MOName + "] No wealth traits resolved — victim selection has no wealth requirement at all. Fix the trait name pool before testing this killer."));
			}
			List<CharacterTrait> list2 = new List<CharacterTrait>();
			string[] markTraitNames = MarkTraitNames;
			foreach (string traitName2 in markTraitNames)
			{
				CharacterTrait val3 = FindTrait(toolbox, traitName2);
				if ((SoCustomComparison)(object)val3 != (SoCustomComparison)null)
				{
					list2.Add(val3);
				}
			}
			ManualLogSource logger2 = SoDExpandedPlugin.Logger;
			val2 = new BepInExInfoLogInterpolatedStringHandler(28, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Resolved ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(list2.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(MarkTraitNames.Length);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" mark trait(s).");
			}
			logger2.LogInfo(val2);
			foreach (CharacterTrait item in list2)
			{
				mo.victimTraitModifiers.Add(OptionalTrait(item, 4f));
			}
			WeaponType[] array = new WeaponType[4];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			MurderWeaponsPool val4 = BuildFilteredWeaponPool(toolbox, (WeaponType[])(object)array);
			if (val4.murderWeaponPool.Count > 0)
			{
				mo.weaponsPool.Add(val4);
				ManualLogSource logger3 = SoDExpandedPlugin.Logger;
				val2 = new BepInExInfoLogInterpolatedStringHandler(96, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Weapon pool: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(val4.murderWeaponPool.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" poison/weapon gathered across all registered MOs (firearms and fists excluded).");
				}
				logger3.LogInfo(val2);
			}
			else
			{
				SoDExpandedPlugin.Logger.LogWarning((object)("[" + MOName + "] No poison/weapon resolved by type — falling back to the unfiltered donor-borrow so the killer stays functional."));
				MurderMO val5 = FindWeaponDonor(toolbox);
				if ((SoCustomComparison)(object)val5 != (SoCustomComparison)null)
				{
					Enumerator<MurderWeaponsPool> enumerator2 = val5.weaponsPool.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						MurderWeaponsPool current2 = enumerator2.Current;
						mo.weaponsPool.Add(current2);
					}
				}
			}
			mo.monkierDDSMessageList = BuildSimpleDDSMessage(toolbox, "SoDExpanded_BrokerKiller_Moniker", "The Closer", "The Advisor", "The Broker", "The Silent Partner");
		}

		protected override void RegisterLeads(MurderMO mo, Toolbox toolbox)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Expected O, but got Unknown
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Expected O, but got Unknown
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Expected O, but got Unknown
			string suicideNoteTextID = DDSBuilder.Document(toolbox).Named("SoDExpanded_BrokerKiller_SuicideNote").Message(0, 1, "I can't make the numbers work anymore. I've tried everything. I didn't want anyone to have to deal with this, but I don't see another way out of it. I'm sorry.", "BrokerKiller_Note_Body", handwriting: true)
				.Build();
			SuicideNoteTextID = suicideNoteTextID;
			InteractablePreset val = FindInteractable(toolbox, "SuicideNote") ?? FindInteractable(toolbox, "LetterGeneral");
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val2;
			if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
			{
				mo.callingCardPool.Add(new CallingCardPick
				{
					item = val,
					origin = (CallingCardOrigin)0,
					randomScoreRange = new Vector2(0f, 0f)
				});
			}
			else
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(63, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] No note-shaped preset found — calling card skipped entirely.");
				}
				logger.LogWarning(val2);
			}
			string treeID = DDSBuilder.Document(toolbox).Named("SoDExpanded_BrokerKiller_Contract_Fallback").Message(0, 1, "This agreement guarantees a return well above anything the firm would ever offer through normal channels — which is exactly why it stays between us. Sign below and consider it handled.", "BrokerKiller_Contract_Fallback_Body")
				.Build();
			InteractablePreset val3 = FindInteractable(toolbox, "LetterGeneral");
			ManualLogSource logger2 = SoDExpandedPlugin.Logger;
			BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(32, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("] Contract preset resolved to: ");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((val3 != null) ? ((Object)val3).name : null) ?? "null");
			}
			logger2.LogInfo(val4);
			if ((SoCustomComparison)(object)val3 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("BrokerKiller_Contract").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)1)
					.At((LeadSpawnWhere)0)
					.WithItem(val3)
					.WithPhysicalText(treeID)
					.SpawnOn((MurderState)1)
					.Security(4)
					.Tag((JobTag)3)
					.Build());
			}
			else
			{
				ManualLogSource logger3 = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(51, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] LetterGeneral not found — contract lead skipped.");
				}
				logger3.LogWarning(val2);
			}
			string treeID2 = DDSBuilder.Vmail(toolbox).Named("SoDExpanded_BrokerKiller_PanicVmail").Message(0, 1, "I think I made a horrible mistake with some money. I can't talk about it properly over this but I'm scared.", "BrokerKiller_Vmail_Line1")
				.Message(1, 0, "What kind of mistake? You're worrying me now.", "BrokerKiller_Vmail_Line2")
				.Message(0, 1, "I'll sort it. Forget I said anything, okay? Please.", "BrokerKiller_Vmail_Line3")
				.Build();
			mo.MOleads.Add(LeadBuilder.New("BrokerKiller_PanicVmail").WrittenBy((LeadCitizen)1).ReceivedBy((LeadCitizen)3)
				.WithTree(treeID2)
				.SpawnOn((MurderState)1)
				.Tag((JobTag)9)
				.Build());
			string treeID3 = DDSBuilder.Document(toolbox).Named("SoDExpanded_BrokerKiller_Ledger_Fallback").Message(0, 1, "— paid in full, quietly. no further contact needed.\n— still deciding. good prospect, careless with money.\n— close to the end of the line. will need resolving soon.", "BrokerKiller_Ledger_Fallback_Body", handwriting: true)
				.Build();
			InteractablePreset val5 = FindInteractable(toolbox, "LetterGeneral");
			ManualLogSource logger4 = SoDExpandedPlugin.Logger;
			val4 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("] Ledger preset resolved to: ");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((val5 != null) ? ((Object)val5).name : null) ?? "null");
			}
			logger4.LogInfo(val4);
			if ((SoCustomComparison)(object)val5 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("BrokerKiller_Ledger").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)0)
					.BelongsTo((LeadCitizen)2)
					.At((LeadSpawnWhere)2)
					.WithItem(val5)
					.WithPhysicalText(treeID3)
					.SpawnOn((MurderState)1)
					.Security(3)
					.Tag((JobTag)12)
					.Build());
			}
			else
			{
				ManualLogSource logger5 = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(49, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] LetterGeneral not found — ledger lead skipped.");
				}
				logger5.LogWarning(val2);
			}
			string treeID4 = DDSBuilder.Document(toolbox).Named("SoDExpanded_BrokerKiller_BusinessCard_Fallback").Message(0, 1, "Discreet financial solutions. Call anytime — day or night.", "BrokerKiller_BusinessCard_Fallback_Body")
				.Build();
			InteractablePreset val6 = FindInteractable(toolbox, "BusinessCardKiller") ?? FindInteractable(toolbox, "BusinessCard");
			if ((SoCustomComparison)(object)val6 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("BrokerKiller_BusinessCard").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)1)
					.BelongsTo((LeadCitizen)2)
					.At((LeadSpawnWhere)0)
					.WithItem(val6)
					.WithPhysicalText(treeID4)
					.SpawnOn((MurderState)1)
					.Tag((JobTag)10)
					.Build());
			}
			else
			{
				ManualLogSource logger6 = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(73, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Neither BusinessCardKiller nor BusinessCard found — card lead skipped.");
				}
				logger6.LogWarning(val2);
			}
			string treeID5 = DDSBuilder.Document(toolbox).Named("SoDExpanded_BrokerKiller_DebtNotice").Message(0, 1, "FINAL NOTICE: your account remains significantly overdue. Immediate payment in full is required to avoid further action.", "BrokerKiller_DebtNotice_Body")
				.Build();
			InteractablePreset val7 = FindInteractable(toolbox, "DebtCollectionLetter") ?? FindInteractable(toolbox, "BillFinalNotice") ?? FindInteractable(toolbox, "RepossessionNotice") ?? FindInteractable(toolbox, "LetterGeneral");
			if ((SoCustomComparison)(object)val7 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("BrokerKiller_DebtNotice").WrittenBy((LeadCitizen)0).ReceivedBy((LeadCitizen)1)
					.At((LeadSpawnWhere)0)
					.WithItem(val7)
					.WithPhysicalText(treeID5)
					.SpawnOn((MurderState)1)
					.Tag((JobTag)11)
					.Build());
				return;
			}
			ManualLogSource logger7 = SoDExpandedPlugin.Logger;
			val2 = new BepInExWarningLogInterpolatedStringHandler(65, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] No debt-notice-shaped preset found — debt notice lead skipped.");
			}
			logger7.LogWarning(val2);
		}
	}
	[HarmonyPatch(typeof(MurderController), "PickNewMurderer")]
	public static class PickNewMurderer_BrokerPatch
	{
		private const int MaxRetries = 15;

		[ThreadStatic]
		private static bool _inRetryLoop;

		[HarmonyPostfix]
		public static void Postfix(MurderController __instance)
		{
			if (_inRetryLoop)
			{
				return;
			}
			_inRetryLoop = true;
			try
			{
				int num = 0;
				while (IsInvalidBrokerPick(__instance) && num < 15)
				{
					num++;
					__instance.PickNewMurderer();
				}
				if (IsInvalidBrokerPick(__instance))
				{
					MurderMO val = FindBrokerMO();
					if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
					{
						bool disabled = val.disabled;
						val.disabled = true;
						__instance.PickNewMurderer();
						val.disabled = disabled;
					}
					SoDExpandedPlugin.Logger.LogWarning((object)($"[{"MO_BrokerKiller_Closer"}] Could not land on an employed murderer after {15} retries — disabled The Closer for one pick to avoid a stuck state. " + "If this warning shows up often, the employed-citizen pool may be too small."));
				}
			}
			finally
			{
				_inRetryLoop = false;
			}
		}

		private static bool IsInvalidBrokerPick(MurderController instance)
		{
			return (SoCustomComparison)(object)instance.chosenMO != (SoCustomComparison)null && ((Object)instance.chosenMO).name == "MO_BrokerKiller_Closer" && (Object)(object)instance.currentMurderer != (Object)null && !IsGenuinelyEmployed(instance.currentMurderer);
		}

		private static MurderMO FindBrokerMO()
		{
			Dictionary<string, ScriptableObject> val = Toolbox.Instance.resourcesCache[Il2CppType.Of<MurderMO>()];
			Enumerator<string, ScriptableObject> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, ScriptableObject> current = enumerator.Current;
				MurderMO val2 = ((Il2CppObjectBase)current.Value).TryCast<MurderMO>();
				if ((SoCustomComparison)(object)val2 != (SoCustomComparison)null && ((Object)val2).name == "MO_BrokerKiller_Closer")
				{
					return val2;
				}
			}
			return null;
		}

		private static bool IsGenuinelyEmployed(Human human)
		{
			Occupation job = human.job;
			return job != null && job.employer != null && !job.preset.selfEmployed && (Object)(object)job.employer.address != (Object)null;
		}
	}
	[HarmonyPatch(typeof(Murder), "PlaceCallingCard")]
	public static class BrokerCallingCard_DDSOverride_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(Murder __instance)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if (__instance == null || __instance.moStr != "MO_BrokerKiller_Closer")
			{
				return;
			}
			if (__instance.callingCard == null)
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_BrokerKiller_Closer] PlaceCallingCard ran but callingCard is null — the note was not actually placed for this murder.");
				return;
			}
			__instance.callingCard.SetDDSOverride(BrokerKillerDefinition.SuicideNoteTextID);
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(84, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MO_BrokerKiller_Closer");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Calling card (forged suicide note) placed for ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("murder ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(__instance.murderID);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", next to the victim's body.");
			}
			logger.LogInfo(val);
		}
	}
	[HarmonyPatch(typeof(MurderController), "SpawnItem")]
	public static class BrokerContract_DDSOverride_Patch
	{
		[HarmonyPriority(200)]
		[HarmonyPostfix]
		public static void Postfix(Interactable __result, Murder murder, JobTag itemTag)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			if (__result == null || murder == null || (int)itemTag != 3 || murder.moStr != "MO_BrokerKiller_Closer")
			{
				return;
			}
			Human murderer = murder.murderer;
			object obj;
			if (murderer == null)
			{
				obj = null;
			}
			else
			{
				Occupation job = murderer.job;
				if (job == null)
				{
					obj = null;
				}
				else
				{
					Company employer = job.employer;
					obj = ((employer != null) ? employer.name : null);
				}
			}
			string text = (string)obj;
			if (string.IsNullOrEmpty(text))
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_BrokerKiller_Closer] Contract spawn: killer/job/employer/name was null or empty — leaving the generic fallback text in place.");
				return;
			}
			string dDSOverride = DDSBuilder.Document(Toolbox.Instance).Named($"SoDExpanded_BrokerKiller_Contract_{murder.murderID}").Message(0, 1, "This agreement guarantees a return well above anything " + text + " would ever offer through normal channels — which is exactly why it stays between us. Sign below and consider it handled.", $"BrokerKiller_Contract_{murder.murderID}_Body")
				.Build();
			__result.SetDDSOverride(dDSOverride);
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MO_BrokerKiller_Closer");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Contract for murder ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(murder.murderID);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" names '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
			}
			logger.LogInfo(val);
		}
	}
	[HarmonyPatch(typeof(MurderController), "SpawnItem")]
	public static class BrokerBusinessCard_DDSOverride_Patch
	{
		[HarmonyPriority(200)]
		[HarmonyPostfix]
		public static void Postfix(Interactable __result, Murder murder, JobTag itemTag)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			if (__result == null || murder == null || (int)itemTag != 10 || murder.moStr != "MO_BrokerKiller_Closer")
			{
				return;
			}
			Human murderer = murder.murderer;
			object obj;
			if (murderer == null)
			{
				obj = null;
			}
			else
			{
				Occupation job = murderer.job;
				if (job == null)
				{
					obj = null;
				}
				else
				{
					Company employer = job.employer;
					obj = ((employer != null) ? employer.name : null);
				}
			}
			string text = (string)obj;
			object obj2;
			if (murderer == null)
			{
				obj2 = null;
			}
			else
			{
				Occupation job2 = murderer.job;
				if (job2 == null)
				{
					obj2 = null;
				}
				else
				{
					OccupationPreset preset = job2.preset;
					obj2 = ((preset != null) ? ((Object)preset).name : null);
				}
			}
			string text2 = (string)obj2;
			string text3 = ((murderer != null) ? murderer.GetCitizenName() : null);
			if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text3))
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_BrokerKiller_Closer] Business card spawn: killer/company name was null or empty — leaving the generic fallback text in place.");
				return;
			}
			string text4 = (string.IsNullOrEmpty(text2) ? "Senior Advisor" : text2);
			string dDSOverride = DDSBuilder.Document(Toolbox.Instance).Named($"SoDExpanded_BrokerKiller_BusinessCard_{murder.murderID}").Message(0, 1, $"Your Finantial Solution — {text4}, {text}. Discreet financial solutions.", $"BrokerKiller_BusinessCard_{murder.murderID}_Body")
				.Build();
			__result.SetDDSOverride(dDSOverride);
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(45, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MO_BrokerKiller_Closer");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Business card for murder ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(murder.murderID);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" names ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' — ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
			}
			logger.LogInfo(val);
		}
	}
	[HarmonyPatch(typeof(MurderController), "SpawnItem")]
	public static class BrokerLedger_DDSOverride_Patch
	{
		private static readonly int[] FlavorAmounts = new int[5] { 4200, 7850, 12400, 19000, 26500 };

		[HarmonyPriority(200)]
		[HarmonyPostfix]
		public static void Postfix(Interactable __result, Murder murder, JobTag itemTag)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			if (__result == null || murder == null || (int)itemTag != 12 || murder.moStr != "MO_BrokerKiller_Closer")
			{
				return;
			}
			List<Human> list = FindOtherMarks(murder, 2);
			if (list.Count == 0)
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_BrokerKiller_Closer] Ledger spawn: no other qualifying citizens found — leaving the generic fallback text in place.");
				return;
			}
			List<string> list2 = new List<string>();
			foreach (Human item in list)
			{
				int value = FlavorAmounts[Toolbox.Instance.Rand(0, FlavorAmounts.Length - 1, false)];
				list2.Add($"— {item.GetCitizenName()}: ${value} outstanding. handling it quietly.");
			}
			string text = string.Join("\n", list2);
			string dDSOverride = DDSBuilder.Document(Toolbox.Instance).Named($"SoDExpanded_BrokerKiller_Ledger_{murder.murderID}").Message(0, 1, text, $"BrokerKiller_Ledger_{murder.murderID}_Body", handwriting: true)
				.Build();
			__result.SetDDSOverride(dDSOverride);
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MO_BrokerKiller_Closer");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Ledger for murder ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(murder.murderID);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" names ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" other citizen(s).");
			}
			logger.LogInfo(val);
		}

		private static List<Human> FindOtherMarks(Murder murder, int count)
		{
			List<Human> list = new List<Human>();
			Dictionary<string, ScriptableObject> traitCache = Toolbox.Instance.resourcesCache[Il2CppType.Of<CharacterTrait>()];
			Enumerator<Citizen> enumerator = CityData.Instance.citizenDirectory.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Citizen current = enumerator.Current;
				if (list.Count >= count)
				{
					break;
				}
				if (!((Actor)current).isPlayer && !((Actor)current).isDead && !((Actor)current).isHomeless && !((Object)(object)current == (Object)(object)murder.victim) && !((Object)(object)current == (Object)(object)murder.murderer))
				{
					Human val = ((Il2CppObjectBase)current).TryCast<Human>();
					if (!((Object)(object)val == (Object)null) && LooksLikeAMark(val, traitCache))
					{
						list.Add(val);
					}
				}
			}
			return list;
		}

		private static bool LooksLikeAMark(Human human, Dictionary<string, ScriptableObject> traitCache)
		{
			string[] array = new string[12]
			{
				"Quirk-StatusWealthy", "Quirk-StatusElite", "Principle-Capitalist", "Char-Greedy", "Char-Extravagant", "Char-Reckless", "Char-Impulsive", "Char-Trusting", "Char-Boastful", "Affliction-GamblingAddict",
				"Interest-Poker", "Secret-SecretMoneyStash"
			};
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (traitCache.ContainsKey(text))
				{
					CharacterTrait val = ((Il2CppObjectBase)traitCache[text]).TryCast<CharacterTrait>();
					if ((SoCustomComparison)(object)val != (SoCustomComparison)null && human.TraitExists(val))
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Toolbox), "LoadAll")]
	public static class ToolboxLoadAll_FanaticBook_Patch
	{
		[HarmonyPriority(200)]
		[HarmonyPostfix]
		public static void Postfix(Toolbox __instance)
		{
			FanaticBibleBook.Register(__instance);
		}
	}
	public static class FanaticBibleBook
	{
		public const string BOOK_NAME = "SoDExpanded_FanaticKiller_BibleBook";

		private const string FANATIC_TRAIT = "Principle-Religious";

		public static void Register(Toolbox toolbox)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Expected O, but got Unknown
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Expected O, but got Unknown
			Type val = Il2CppType.Of<BookPreset>();
			bool flag = default(bool);
			if (!toolbox.resourcesCache.ContainsKey(val))
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("SoDExpanded_FanaticKiller_BibleBook");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] BookPreset cache missing — skipping.");
				}
				logger.LogWarning(val2);
				return;
			}
			Dictionary<string, ScriptableObject> val3 = toolbox.resourcesCache[val];
			if (val3.ContainsKey("SoDExpanded_FanaticKiller_BibleBook"))
			{
				return;
			}
			string[] array = new string[5] { "KolobGrieving", "HowIAscended", "GoddessInTheWaitingRoom", "TheCandorBookOfAncientHistory", "CompendiumOfDiseases" };
			BookPreset val4 = null;
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (val3.ContainsKey(text))
				{
					BookPreset val5 = ((Il2CppObjectBase)val3[text]).TryCast<BookPreset>();
					if ((SoCustomComparison)(object)val5 != (SoCustomComparison)null && (Object)(object)val5.bookMesh != (Object)null)
					{
						val4 = val5;
						break;
					}
				}
			}
			if ((SoCustomComparison)(object)val4 == (SoCustomComparison)null)
			{
				Enumerator<string, ScriptableObject> enumerator = val3.GetEnumerator();
				while (enumerator.MoveNext())
				{
					KeyValuePair<string, ScriptableObject> current = enumerator.Current;
					BookPreset val6 = ((Il2CppObjectBase)current.Value).TryCast<BookPreset>();
					if ((SoCustomComparison)(object)val6 != (SoCustomComparison)null && (Object)(object)val6.bookMesh != (Object)null)
					{
						val4 = val6;
						break;
					}
				}
			}
			if ((SoCustomComparison)(object)val4 == (SoCustomComparison)null)
			{
				ManualLogSource logger2 = SoDExpandedPlugin.Logger;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(65, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("SoDExpanded_FanaticKiller_BibleBook");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] No donor BookPreset with a mesh found — skipping registration.");
				}
				logger2.LogWarning(val2);
				return;
			}
			BookPreset val7 = ScriptableObject.CreateInstance<BookPreset>();
			((Object)val7).name = "SoDExpanded_FanaticKiller_BibleBook";
			val7.bookName = "Testimony of the Watchful";
			val7.author = "Unknown";
			val7.genre = new List<BookGenre>();
			val7.genre.Add((BookGenre)2);
			val7.isSeries = false;
			val7.common = 0.2f;
			val7.baseChance = 0.05f;
			val7.spawnRule = (SpawnRules)0;
			val7.bookMesh = val4.bookMesh;
			val7.bookMaterial = val4.bookMaterial;
			val7.pickRules = new List<TraitPickRule>();
			Dictionary<string, ScriptableObject> val8 = toolbox.resourcesCache[Il2CppType.Of<CharacterTrait>()];
			if (val8.ContainsKey("Principle-Religious"))
			{
				CharacterTrait val9 = ((Il2CppObjectBase)val8["Principle-Religious"]).TryCast<CharacterTrait>();
				TraitPickRule val10 = new TraitPickRule();
				val10.rule = (RuleType)0;
				val10.mustPassForApplication = false;
				val10.baseChance = 0.6f;
				val10.reasonChance = 1;
				val10.traitList.Add(val9);
				val7.pickRules.Add(val10);
			}
			else
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[SoDExpanded_FanaticKiller_BibleBook] Trait 'Principle-Religious' not found — book registers with no trait weighting, will spawn at its flat base rarity only.");
			}
			val7.ddsMessage = DDSBuilder.Document(toolbox).Named("SoDExpanded_FanaticKiller_BibleBook_Text").Message(0, 1, "They will tell you the eyes are a metaphor. They are not. Eight watch always: two for what is done, two for what is hidden, two for what is planned, and two for what is only felt. None of the eight ever sleep, and none of them forgive. To be seen by all eight at once is to be judged already; what comes after is only paperwork.", "FanaticKiller_BibleBook_Body")
				.Build();
			toolbox.ProcessLoadedScriptableObject((ScriptableObject)(object)val7);
			ManualLogSource logger3 = SoDExpandedPlugin.Logger;
			BepInExInfoLogInterpolatedStringHandler val11 = new BepInExInfoLogInterpolatedStringHandler(73, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val11).AppendLiteral("[SoDExpanded] Registered book '");
				((BepInExLogInterpolatedStringHandler)val11).AppendFormatted<string>("SoDExpanded_FanaticKiller_BibleBook");
				((BepInExLogInterpolatedStringHandler)val11).AppendLiteral("' (mesh borrowed from '");
				((BepInExLogInterpolatedStringHandler)val11).AppendFormatted<string>(((Object)val4).name);
				((BepInExLogInterpolatedStringHandler)val11).AppendLiteral("') ");
				((BepInExLogInterpolatedStringHandler)val11).AppendLiteral("(");
				((BepInExLogInterpolatedStringHandler)val11).AppendFormatted<int>(val7.pickRules.Count);
				((BepInExLogInterpolatedStringHandler)val11).AppendLiteral(" pick rule(s)).");
			}
			logger3.LogInfo(val11);
		}
	}
	public class FanaticKillerDefinition : KillerMODefinition
	{
		public const string MO_NAME = "MO_FanaticKiller_Angel";

		private const string FANATIC_TRAIT = "Principle-Religious";

		private static readonly string[] SinTraitNames = new string[15]
		{
			"Secret-Affair", "Secret-Paramour", "Secret-Abusive", "Secret-AbusivePartner", "Secret-CrimeSyndicate", "Secret-StealsFromWork", "Secret-KilledSomeone", "Secret-Addict", "Affliction-DrugAddict", "Affliction-GamblingAddict",
			"Affliction-Alcoholic", "Char-Dishonest", "Char-Greedy", "Char-Spiteful", "Char-Hostile"
		};

		public const float SIN_WEIGHT = 4f;

		public override string MOName => "MO_FanaticKiller_Angel";

		protected override void ConfigureMO(MurderMO mo, Toolbox toolbox)
		{
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Expected O, but got Unknown
			mo.baseDifficulty = 2;
			mo.allowHome = true;
			mo.allowWork = false;
			mo.allowPublic = false;
			mo.allowStreets = false;
			mo.allowDen = false;
			mo.acquaintedSuitabilityBoost = 0;
			mo.likeSuitabilityBoost = 0;
			mo.attractedToSuitabilityBoost = 0;
			mo.sameWorkplaceBoost = 0;
			mo.murdererIsTenantBoost = 0;
			CharacterTrait val = FindTrait(toolbox, "Principle-Religious");
			if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
			{
				mo.murdererTraitModifiers.Add(RequiredTrait(val));
			}
			else
			{
				SoDExpandedPlugin.Logger.LogWarning((object)($"[{MOName}] Trait '{"Principle-Religious"}' not found — The Angel currently has NO " + "hard murderer-trait requirement. Verify the real trait name before relying on this killer type."));
			}
			List<CharacterTrait> list = new List<CharacterTrait>();
			string[] sinTraitNames = SinTraitNames;
			foreach (string traitName in sinTraitNames)
			{
				CharacterTrait val2 = FindTrait(toolbox, traitName);
				if ((SoCustomComparison)(object)val2 != (SoCustomComparison)null)
				{
					list.Add(val2);
				}
			}
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(41, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] Resolved ");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("/");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(SinTraitNames.Length);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" sin trait(s) from the pool.");
			}
			logger.LogInfo(val3);
			if (list.Count > 0)
			{
				mo.victimTraitModifiers.Add(RequiredAnyOf(list));
				foreach (CharacterTrait item in list)
				{
					mo.victimTraitModifiers.Add(OptionalTrait(item, 4f));
				}
			}
			else
			{
				SoDExpandedPlugin.Logger.LogWarning((object)("[" + MOName + "] No sin traits resolved at all — victim selection has no sin requirement and will behave like a MO with an empty trait pool. Fix the trait name pool before testing this killer."));
			}
			MurderMO val4 = FindWeaponDonor(toolbox);
			if ((SoCustomComparison)(object)val4 != (SoCustomComparison)null)
			{
				Enumerator<MurderWeaponsPool> enumerator2 = val4.weaponsPool.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					MurderWeaponsPool current2 = enumerator2.Current;
					mo.weaponsPool.Add(current2);
				}
			}
			mo.monkierDDSMessageList = BuildSimpleDDSMessage(toolbox, "SoDExpanded_FanaticKiller_Moniker", "The Angel", "The Confessor", "The Watchful", "The Zealot");
			Graffiti val5 = FindTextGraffitiDonor(toolbox);
			if (val5 != null)
			{
				string ddsMessageTextList = BuildSimpleDDSMessage(toolbox, "SoDExpanded_FanaticKiller_Graffiti", "GOD IS WATCHING");
				mo.graffiti.Add(new Graffiti
				{
					preset = val5.preset,
					artImage = val5.artImage,
					pos = (GraffitiPosition)1,
					ddsMessageTextList = ddsMessageTextList,
					color = val5.color,
					size = val5.size
				});
			}
		}

		protected override void RegisterLeads(MurderMO mo, Toolbox toolbox)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Expected O, but got Unknown
			string treeID = DDSBuilder.Document(toolbox).Named("SoDExpanded_FanaticKiller_BiblePassage").Message(0, 1, "\"Vengeance is mine; I will repay,\" saith the Lord. I am only the hand. You were weighed, and you were found wanting.", "FanaticKiller_Passage_Body", handwriting: true)
				.Build();
			InteractablePreset val = FindInteractable(toolbox, "KillerTauntNoteGeneral") ?? FindInteractable(toolbox, "LetterGeneral");
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val2;
			if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("FanaticKiller_BiblePassage").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)1)
					.At((LeadSpawnWhere)0)
					.WithItem(val)
					.WithPhysicalText(treeID)
					.Tag((JobTag)19)
					.Build());
			}
			else
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(56, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] LetterGeneral not found — bible passage lead skipped.");
				}
				logger.LogWarning(val2);
			}
			string treeID2 = DDSBuilder.Document(toolbox).Named("SoDExpanded_FanaticKiller_Journal_Fallback").Message(0, 1, "That person stopped me again today. Started going on about sin and judgement, like he already knew things about me he shouldn't. I don't know why he's always right there. I've started taking the long way around.", "FanaticKiller_Journal_Fallback_Body", handwriting: true)
				.Build();
			InteractablePreset val3 = FindInteractable(toolbox, "Murder_Journal") ?? FindInteractable(toolbox, "Diary") ?? FindInteractable(toolbox, "LetterGeneral");
			if ((SoCustomComparison)(object)val3 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("FanaticKiller_Journal").WrittenBy((LeadCitizen)1).ReceivedBy((LeadCitizen)0)
					.At((LeadSpawnWhere)0)
					.WithItem(val3)
					.WithPhysicalText(treeID2)
					.Tag((JobTag)18)
					.Build());
			}
			else
			{
				ManualLogSource logger2 = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(50, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] LetterGeneral not found — journal lead skipped.");
				}
				logger2.LogWarning(val2);
			}
			string treeID3 = DDSBuilder.Document(toolbox).Named("SoDExpanded_FanaticKiller_Scripture").Message(0, 1, "How long, O Lord, holy and true, dost thou not judge? \"Someone has to. No one else will look at them and see.\"", "FanaticKiller_Scripture_Body", handwriting: true)
				.Build();
			InteractablePreset val4 = FindInteractable(toolbox, "LetterGeneral") ?? FindInteractable(toolbox, "AssortedBooks2") ?? FindInteractable(toolbox, "AssortedBooks1");
			if ((SoCustomComparison)(object)val4 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("FanaticKiller_Scripture").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)0)
					.BelongsTo((LeadCitizen)2)
					.At((LeadSpawnWhere)2)
					.WithItem(val4)
					.WithPhysicalText(treeID3)
					.Tag((JobTag)17)
					.Build());
			}
			else
			{
				ManualLogSource logger3 = SoDExpandedPlugin.Logger;
				val2 = new BepInExWarningLogInterpolatedStringHandler(52, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] LetterGeneral not found — scripture lead skipped.");
				}
				logger3.LogWarning(val2);
			}
			string treeID4 = DDSBuilder.Document(toolbox).Named("SoDExpanded_FanaticKiller_Ledger").Message(0, 1, "the one who works late. pride, he doesn't even hide it. third floor, corner unit. still watching. not yet. loud laugh, no shame. greed, maybe. maybe both. the one two floors down. not sure yet. watching a little longer.", "FanaticKiller_Ledger_Body", handwriting: true)
				.Build();
			InteractablePreset val5 = FindInteractable(toolbox, "CrumpledPaper") ?? FindInteractable(toolbox, "CrumpledHalfWrittenLetter") ?? FindInteractable(toolbox, "Murder_SightingLog") ?? FindInteractable(toolbox, "LetterGeneral");
			if ((SoCustomComparison)(object)val5 != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("FanaticKiller_Ledger").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)0)
					.BelongsTo((LeadCitizen)2)
					.At((LeadSpawnWhere)2)
					.WithItem(val5)
					.WithPhysicalText(treeID4)
					.Tag((JobTag)20)
					.Build());
				return;
			}
			ManualLogSource logger4 = SoDExpandedPlugin.Logger;
			val2 = new BepInExWarningLogInterpolatedStringHandler(49, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] LetterGeneral not found — ledger lead skipped.");
			}
			logger4.LogWarning(val2);
		}
	}
	[HarmonyPatch(typeof(MurderController), "SpawnItem")]
	public static class FanaticJournal_DDSOverride_Patch
	{
		[HarmonyPriority(200)]
		[HarmonyPostfix]
		public static void Postfix(Interactable __result, Murder murder, JobTag itemTag)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Expected O, but got Unknown
			if (__result == null || murder == null || (int)itemTag != 18 || murder.moStr != "MO_FanaticKiller_Angel")
			{
				return;
			}
			Human murderer = murder.murderer;
			object obj;
			if (murderer == null)
			{
				obj = null;
			}
			else
			{
				NewAddress home = murderer.home;
				obj = ((home != null) ? ((NewGameLocation)home).building : null);
			}
			if ((Object)obj == (Object)null)
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_FanaticKiller_Angel] Journal spawn: killer/home/building was null — leaving the generic fallback text in place.");
				return;
			}
			NewBuilding building = ((NewGameLocation)murderer.home).building;
			string text = ((building.isPlayerEditedName && !string.IsNullOrEmpty(building.playerEditedBuildingName)) ? building.playerEditedBuildingName : ((Object)building).name);
			if (string.IsNullOrEmpty(text))
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_FanaticKiller_Angel] Journal spawn: resolved building name was empty — leaving the generic fallback text in place.");
				return;
			}
			string value = (HasTrait(murderer, "Sex-Male") ? "man" : (HasTrait(murderer, "Sex-Female") ? "woman" : "person"));
			string text2 = (HasTrait(murderer, "Sex-Male") ? "he" : (HasTrait(murderer, "Sex-Female") ? "she" : "they"));
			string value2 = BuildAppearanceClause(murderer, text2);
			string dDSOverride = DDSBuilder.Document(Toolbox.Instance).Named($"SoDExpanded_FanaticKiller_Journal_{murder.murderID}").Message(0, 1, $"That {value} stopped me again today, right outside {text}. Started going on about sin and judgement, like {text2} already knew things about me {text2} shouldn't.{value2} I don't know why {text2}'s always right there. I've started taking the long way around.", $"FanaticKiller_Journal_{murder.murderID}_Body", handwriting: true)
				.Build();
			__result.SetDDSOverride(dDSOverride);
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MO_FanaticKiller_Angel");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Journal for murder ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(murder.murderID);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" references ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
			}
			logger.LogInfo(val);
		}

		private static string BuildAppearanceClause(Human killer, string pronoun)
		{
			List<string> list = new List<string>();
			if (HasTrait(killer, "Quirk-LongHair"))
			{
				list.Add("long hair");
			}
			if (HasTrait(killer, "Quirk-ShoesHeels"))
			{
				list.Add("heels, of all things");
			}
			if (HasTrait(killer, "Quirk-StatusWealthy"))
			{
				list.Add("dressed better than anyone round here");
			}
			if (list.Count == 0)
			{
				return "";
			}
			return $" I only really remember the {string.Join(" and ", list)} — {pronoun} didn't stick around long enough for more than that.";
		}

		private static bool HasTrait(Human human, string traitName)
		{
			Dictionary<string, ScriptableObject> val = Toolbox.Instance.resourcesCache[Il2CppType.Of<CharacterTrait>()];
			if (!val.ContainsKey(traitName))
			{
				return false;
			}
			CharacterTrait val2 = ((Il2CppObjectBase)val[traitName]).TryCast<CharacterTrait>();
			return (SoCustomComparison)(object)val2 != (SoCustomComparison)null && human.TraitExists(val2);
		}
	}
	[HarmonyPatch(typeof(Murder), "SetMurderState")]
	public static class FanaticSelfReport_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(Murder __instance, MurderState newState)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			if (__instance == null || __instance.moStr != "MO_FanaticKiller_Angel" || (int)newState != 6)
			{
				return;
			}
			Death death = __instance.death;
			if (death == null)
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_FanaticKiller_Angel] SetMurderState(post) fired but Murder.death was null -- can't self-report.");
				return;
			}
			Human murderer = __instance.murderer;
			if ((Object)(object)murderer == (Object)null)
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[MO_FanaticKiller_Angel] SetMurderState(post) fired but Murder.murderer was null -- can't self-report.");
			}
			else if (death.reported)
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("MO_FanaticKiller_Angel");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Murder ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(__instance.murderID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" already reported, skipping.");
				}
				logger.LogInfo(val);
			}
			else
			{
				NewGameLocation deathLocation = death.GetDeathLocation();
				GameplayController.Instance.CallEnforcers(deathLocation, false, false, 0f);
				death.SetReported(murderer, (ReportType)0);
				SoDExpandedPlugin.Logger.LogInfo((object)($"[{"MO_FanaticKiller_Angel"}] Called GameplayController.CallEnforcers + Death.SetReported for murder {__instance.murderID}. Watch for: do 1-3 Enforcers " + "actually depart City Hall and head to the scene."));
			}
		}
	}
	[HarmonyPatch(typeof(Toolbox), "LoadAll")]
	public static class ToolboxLoadAll_AllKillers_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(Toolbox __instance)
		{
			KillerRegistry.RegisterAll(__instance);
		}
	}
	[HarmonyPatch(typeof(MurderController), "SpawnItem")]
	public static class SpawnItem_DDSOverrideFix_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(Interactable __result, Murder murder, JobTag itemTag)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			if (__result == null)
			{
				return;
			}
			bool flag = false;
			object obj;
			if (murder == null)
			{
				obj = null;
			}
			else
			{
				MurderMO mo = murder.mo;
				obj = ((mo != null) ? mo.MOleads : null);
			}
			if (obj != null)
			{
				Enumerator<MurderLeadItem> enumerator = murder.mo.MOleads.GetEnumerator();
				while (enumerator.MoveNext())
				{
					MurderLeadItem current = enumerator.Current;
					if (current.itemTag == itemTag)
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				return;
			}
			if (PhysicalTextRegistry.TryGet(itemTag, out var treeID))
			{
				__result.SetDDSOverride(treeID);
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(79, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SoDExpanded] Physical-only DDS override '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(treeID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' applied to ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("spawned item '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(__result.name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (tag: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<JobTag>(itemTag);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
				}
				logger.LogInfo(val);
				return;
			}
			object obj2;
			if (murder == null)
			{
				obj2 = null;
			}
			else
			{
				MurderMO mo2 = murder.mo;
				obj2 = ((mo2 != null) ? mo2.MOleads : null);
			}
			if (obj2 == null)
			{
				return;
			}
			MurderLeadItem val2 = null;
			Enumerator<MurderLeadItem> enumerator2 = murder.mo.MOleads.GetEnumerator();
			while (enumerator2.MoveNext())
			{
				MurderLeadItem current2 = enumerator2.Current;
				if (current2.itemTag == itemTag && !string.IsNullOrEmpty(current2.vmailThread))
				{
					val2 = current2;
					break;
				}
			}
			if (val2 != null)
			{
				__result.SetDDSOverride(val2.vmailThread);
				SoDExpandedPlugin.Logger.LogInfo((object)($"[SoDExpanded] DDS override '{val2.vmailThread}' applied to spawned item '{__result.name}' (tag: {itemTag}) — note: this lead also produced a " + "duplicate digital vmail via WithTree(). Consider switching to WithPhysicalText()."));
			}
		}
	}
	public static class KillerRegistry
	{
		private static readonly List<KillerMODefinition> All = new List<KillerMODefinition>
		{
			new NeighborKillerDefinition(),
			new FanaticKillerDefinition(),
			new BrokerKillerDefinition()
		};

		public static void RegisterAll(Toolbox toolbox)
		{
			foreach (KillerMODefinition item in All)
			{
				item.Register(toolbox);
			}
		}
	}
	public abstract class KillerMODefinition
	{
		public abstract string MOName { get; }

		protected abstract void ConfigureMO(MurderMO mo, Toolbox toolbox);

		protected virtual void RegisterLeads(MurderMO mo, Toolbox toolbox)
		{
		}

		public void Register(Toolbox toolbox)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_00b5: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			Type val = Il2CppType.Of<MurderMO>();
			bool flag = default(bool);
			if (!toolbox.resourcesCache.ContainsKey(val))
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] MurderMO cache missing — skipping.");
				}
				logger.LogWarning(val2);
				return;
			}
			Dictionary<string, ScriptableObject> val3 = toolbox.resourcesCache[val];
			if (val3.ContainsKey(MOName))
			{
				return;
			}
			MurderMO val4 = ScriptableObject.CreateInstance<MurderMO>();
			((Object)val4).name = MOName;
			val4.disabled = false;
			val4.pickRandomScoreRange = new Vector2(0f, 1f);
			val4.victimRandomScoreRange = new Vector2(0f, 1f);
			ConfigureMO(val4, toolbox);
			RegisterLeads(val4, toolbox);
			Type val5 = Il2CppType.Of<MurderPreset>();
			if (toolbox.resourcesCache.ContainsKey(val5))
			{
				Enumerator<string, ScriptableObject> enumerator = toolbox.resourcesCache[val5].GetEnumerator();
				while (enumerator.MoveNext())
				{
					KeyValuePair<string, ScriptableObject> current = enumerator.Current;
					MurderPreset val6 = ((Il2CppObjectBase)current.Value).TryCast<MurderPreset>();
					if ((SoCustomComparison)(object)val6 != (SoCustomComparison)null && !val6.disabled)
					{
						val4.compatibleWith.Add(val6);
					}
				}
			}
			toolbox.ProcessLoadedScriptableObject((ScriptableObject)(object)val4);
			ManualLogSource logger2 = SoDExpandedPlugin.Logger;
			BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(68, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[SoDExpanded] Registered '");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(MOName);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("' — ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(val4.compatibleWith.Count);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" preset(s), ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(val4.weaponsPool.Count);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" weapon pool(s), ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(val4.MOleads.Count);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" lead(s).");
			}
			logger2.LogInfo(val7);
		}

		protected CharacterTrait FindTrait(Toolbox toolbox, string traitName)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Dictionary<string, ScriptableObject> val = toolbox.resourcesCache[Il2CppType.Of<CharacterTrait>()];
			if (!val.ContainsKey(traitName))
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(22, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Trait '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(traitName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' not found.");
				}
				logger.LogWarning(val2);
				return null;
			}
			return ((Il2CppObjectBase)val[traitName]).TryCast<CharacterTrait>();
		}

		protected InteractablePreset FindInteractable(Toolbox toolbox, string presetName)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			Type val = Il2CppType.Of<InteractablePreset>();
			bool flag = default(bool);
			if (!toolbox.resourcesCache.ContainsKey(val))
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] InteractablePreset cache not found.");
				}
				logger.LogWarning(val2);
				return null;
			}
			Dictionary<string, ScriptableObject> val3 = toolbox.resourcesCache[val];
			if (!val3.ContainsKey(presetName))
			{
				ManualLogSource logger2 = SoDExpandedPlugin.Logger;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] InteractablePreset '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(presetName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' not found.");
				}
				logger2.LogWarning(val2);
				return null;
			}
			return ((Il2CppObjectBase)val3[presetName]).TryCast<InteractablePreset>();
		}

		protected MurderMO FindWeaponDonor(Toolbox toolbox)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			Dictionary<string, ScriptableObject> val = toolbox.resourcesCache[Il2CppType.Of<MurderMO>()];
			MurderMO val2 = null;
			Enumerator<string, ScriptableObject> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, ScriptableObject> current = enumerator.Current;
				MurderMO val3 = ((Il2CppObjectBase)current.Value).TryCast<MurderMO>();
				if (!((SoCustomComparison)(object)val3 == (SoCustomComparison)null) && !val3.disabled && !(((Object)val3).name == MOName) && val3.weaponsPool.Count != 0 && ((SoCustomComparison)(object)val2 == (SoCustomComparison)null || val3.weaponsPool.Count > val2.weaponsPool.Count))
				{
					val2 = val3;
				}
			}
			if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null)
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("] No weapon donor found.");
				}
				logger.LogWarning(val4);
			}
			return val2;
		}

		protected MurderWeaponsPool BuildFilteredWeaponPool(Toolbox toolbox, params WeaponType[] excludedTypes)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			Type val = Il2CppType.Of<MurderWeaponPreset>();
			if (!toolbox.resourcesCache.ContainsKey(val))
			{
				ManualLogSource logger = SoDExpandedPlugin.Logger;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(67, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MOName);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] No MurderWeaponPreset cache found — can't filter by weapon type.");
				}
				logger.LogWarning(val2);
				return ScriptableObject.CreateInstance<MurderWeaponsPool>();
			}
			Dictionary<string, ScriptableObject> val3 = toolbox.resourcesCache[val];
			Dictionary<string, ScriptableObject> val4 = toolbox.resourcesCache[Il2CppType.Of<MurderMO>()];
			MurderWeaponsPool val5 = ScriptableObject.CreateInstance<MurderWeaponsPool>();
			HashSet<string> hashSet = new HashSet<string>();
			int num = 0;
			Enumerator<string, ScriptableObject> enumerator = val4.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, ScriptableObject> current = enumerator.Current;
				MurderMO val6 = ((Il2CppObjectBase)current.Value).TryCast<MurderMO>();
				if ((SoCustomComparison)(object)val6 == (SoCustomComparison)null || ((Object)val6).name == MOName)
				{
					continue;
				}
				Enumerator<MurderWeaponsPool> enumerator2 = val6.weaponsPool.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					MurderWeaponsPool current2 = enumerator2.Current;
					if ((SoCustomComparison)(object)current2 == (SoCustomComparison)null)
					{
						continue;
					}
					Enumerator<MurderWeaponPick> enumerator3 = current2.murderWeaponPool.GetEnumerator();
					while (enumerator3.MoveNext())
					{
						MurderWeaponPick current3 = enumerator3.Current;
						if ((SoCustomComparison)(object)((current3 != null) ? current3.weapon : null) == (SoCustomComparison)null || !hashSet.Add(((Object)current3.weapon).name))
						{
							continue;
						}
						if (!val3.ContainsKey(((Object)current3.weapon).name))
						{
							num++;
							continue;
						}
						MurderWeaponPreset val7 = ((Il2CppObjectBase)val3[((Object)current3.weapon).name]).TryCast<MurderWeaponPreset>();
						if (!((SoCustomComparison)(object)val7 == (SoCustomComparison)null) && Array.IndexOf(excludedTypes, val7.type) < 0)
						{
							val5.murderWeaponPool.Add(new MurderWeaponPick
							{
								weapon = current3.weapon,
								chanceOfDroppingAtScene = current3.chanceOfDroppingAtScene,
								randomScoreRange = current3.randomScoreRange,
								traitModifiers = current3.traitModifiers
							});
						}
					}
				}
			}
			if (num > 0)
			{
				SoDExpandedPlugin.Logger.LogInfo((object)($"[{MOName}] Weapon pool filter: {num} weapon(s) had no matching " + "MurderWeaponPreset by name — excluded rather than guessed at."));
			}
			return val5;
		}

		protected MurdererModifierRule RequiredTrait(CharacterTrait trait, float scoreBonus = 8f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			MurdererModifierRule val = new MurdererModifierRule();
			val.rule = (RuleType)0;
			val.mustPassForApplication = true;
			val.scoreModifier = scoreBonus;
			val.traitList.Add(trait);
			return val;
		}

		protected MurdererModifierRule OptionalTrait(CharacterTrait trait, float scoreBonus)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			MurdererModifierRule val = new MurdererModifierRule();
			val.rule = (RuleType)0;
			val.mustPassForApplication = false;
			val.scoreModifier = scoreBonus;
			val.traitList.Add(trait);
			return val;
		}

		protected MurdererModifierRule RequiredAnyOf(List<CharacterTrait> traits)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			MurdererModifierRule val = new MurdererModifierRule();
			val.rule = (RuleType)0;
			val.mustPassForApplication = true;
			val.scoreModifier = 0f;
			foreach (CharacterTrait trait in traits)
			{
				val.traitList.Add(trait);
			}
			return val;
		}

		protected string BuildSimpleDDSMessage(Toolbox toolbox, string name, params string[] textOptions)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			DDSMessageSave val = new DDSMessageSave
			{
				id = toolbox.GenerateUniqueID(),
				name = name
			};
			foreach (string text in textOptions)
			{
				string text2 = toolbox.GenerateUniqueID();
				Strings.WriteToDictionary("dds.blocks", text2, "ShadowsOfDoubtExpanded", text, "", 0, false, "");
				DDSBlockSave val2 = new DDSBlockSave
				{
					id = text2,
					name = name + "_" + text2
				};
				toolbox.allDDSBlocks.Add(text2, val2);
				val.AddBlock(text2);
			}
			toolbox.allDDSMessages.Add(((DDSComponent)val).id, val);
			return ((DDSComponent)val).id;
		}

		protected Graffiti FindTextGraffitiDonor(Toolbox toolbox)
		{
			Dictionary<string, ScriptableObject> val = toolbox.resourcesCache[Il2CppType.Of<MurderMO>()];
			Enumerator<string, ScriptableObject> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, ScriptableObject> current = enumerator.Current;
				MurderMO val2 = ((Il2CppObjectBase)current.Value).TryCast<MurderMO>();
				if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null || val2.disabled || ((Object)val2).name == MOName || val2.graffiti == null)
				{
					continue;
				}
				Enumerator<Graffiti> enumerator2 = val2.graffiti.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					Graffiti current2 = enumerator2.Current;
					if (!string.IsNullOrEmpty(current2.ddsMessageTextList))
					{
						return current2;
					}
				}
			}
			SoDExpandedPlugin.Logger.LogWarning((object)("[" + MOName + "] No existing MO with a TEXT graffiti entry (non-empty ddsMessageTextList) found to borrow visual setup from -- graffiti will be skipped rather than spawned with a guessed (and possibly non-functional) artImage/preset combo."));
			return null;
		}
	}
	public class DDSBuilder
	{
		private readonly Toolbox _toolbox;

		private readonly DDSTreeSave _tree;

		private string _lastInstanceID;

		private DDSBuilder(Toolbox toolbox, TreeType treeType)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0067: Expected O, but got Unknown
			_toolbox = toolbox;
			_tree = new DDSTreeSave
			{
				id = toolbox.GenerateUniqueID(),
				treeType = treeType,
				triggerPoint = (TriggerPoint)5,
				repeat = (RepeatSetting)7,
				participantA = new DDSParticipant
				{
					required = true
				},
				participantB = new DDSParticipant
				{
					required = true
				}
			};
		}

		public static DDSBuilder Vmail(Toolbox toolbox)
		{
			return new DDSBuilder(toolbox, (TreeType)1);
		}

		public static DDSBuilder Document(Toolbox toolbox)
		{
			DDSBuilder dDSBuilder = new DDSBuilder(toolbox, (TreeType)2);
			dDSBuilder._tree.document = FindDocumentStyleDonor(toolbox);
			return dDSBuilder;
		}

		private static DDSDocument FindDocumentStyleDonor(Toolbox toolbox)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			Enumerator<string, DDSTreeSave> enumerator = toolbox.allDDSTrees.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, DDSTreeSave> current = enumerator.Current;
				DDSTreeSave value = current.Value;
				if (value != null && (int)value.treeType == 2 && value.document != null)
				{
					return value.document;
				}
			}
			SoDExpandedPlugin.Logger.LogWarning((object)"[DDSBuilder] No existing document-type DDS tree found to borrow page style from — falling back to a plain page (no background sprite).");
			return new DDSDocument
			{
				size = new Vector2(400f, 500f)
			};
		}

		public DDSBuilder Named(string name)
		{
			((DDSComponent)_tree).name = name;
			return this;
		}

		public DDSBuilder HideFromRecipient()
		{
			_tree.participantB.disableInbox = true;
			return this;
		}

		public DDSBuilder Message(int saidBy, int saidTo, string text, string blockName = null, bool handwriting = false)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Invalid comparison between Unknown and I4
			//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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: 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_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			if (blockName == null)
			{
				blockName = "Block_" + _toolbox.GenerateUniqueID();
			}
			string text2 = _toolbox.GenerateUniqueID();
			Strings.WriteToDictionary("dds.blocks", text2, "ShadowsOfDoubtExpanded", text, "", 0, false, "");
			DDSBlockSave val = new DDSBlockSave
			{
				id = text2,
				name = blockName
			};
			_toolbox.allDDSBlocks.Add(text2, val);
			DDSMessageSave val2 = new DDSMessageSave
			{
				id = _toolbox.GenerateUniqueID(),
				name = blockName + "_Msg"
			};
			val2.AddBlock(text2);
			_toolbox.allDDSMessages.Add(((DDSComponent)val2).id, val2);
			string text3 = _tree.AddMessage(((DDSComponent)val2).id);
			DDSMessageSettings val3 = FindSettings(text3);
			val3.saidBy = saidBy;
			val3.saidTo = saidTo;
			val3.isHandwriting = handwriting;
			if ((int)_tree.treeType == 2 && _tree.document != null)
			{
				Vector2 size = _tree.document.size;
				val3.pos = new Vector2(0f, -20f);
				val3.size = new Vector2(size.x - 40f, size.y - 40f);
			}
			if (_lastInstanceID != null)
			{
				FindSettings(_lastInstanceID).links.Add(new DDSMessageLink
				{
					from = _lastInstanceID,
					to = text3,
					isDialogSuccess = true
				});
			}
			else
			{
				_tree.startingMessage = text3;
			}
			_lastInstanceID = text3;
			return this;
		}

		public string Build()
		{
			_tree.messageRef = new Dictionary<string, DDSMessageSettings>();
			Enumerator<DDSMessageSettings> enumerator = _tree.messages.GetEnumerator();
			while (enumerator.MoveNext())
			{
				DDSMessageSettings current = enumerator.Current;
				_tree.messageRef[current.instanceID] = current;
			}
			_toolbox.allDDSTrees.Add(((DDSComponent)_tree).id, _tree);
			return ((DDSComponent)_tree).id;
		}

		private DDSMessageSettings FindSettings(string instanceID)
		{
			Enumerator<DDSMessageSettings> enumerator = _tree.messages.GetEnumerator();
			while (enumerator.MoveNext())
			{
				DDSMessageSettings current = enumerator.Current;
				if (current.instanceID == instanceID)
				{
					return current;
				}
			}
			return null;
		}
	}
	public class LeadBuilder
	{
		private readonly MurderLeadItem _lead = new MurderLeadItem();

		private string _physicalTextTreeID;

		private LeadBuilder()
		{
		}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown


		public static LeadBuilder New(string name)
		{
			LeadBuilder leadBuilder = new LeadBuilder();
			leadBuilder._lead.name = name;
			leadBuilder._lead.chance = 1f;
			leadBuilder._lead.compatibleWithAllMotives = true;
			leadBuilder._lead.tryToSpawnWithEachNewMurder = false;
			leadBuilder._lead.spawnOnPhase = (MurderState)1;
			leadBuilder._lead.security = 3;
			leadBuilder._lead.priority = 1;
			return leadBuilder;
		}

		public LeadBuilder SpawnOn(MurderState phase)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_lead.spawnOnPhase = phase;
			return this;
		}

		public LeadBuilder Chance(float chance)
		{
			_lead.chance = chance;
			return this;
		}

		public LeadBuilder WrittenBy(LeadCitizen citizen)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_lead.writer = citizen;
			return this;
		}

		public LeadBuilder ReceivedBy(LeadCitizen citizen)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_lead.receiver = citizen;
			return this;
		}

		public LeadBuilder BelongsTo(LeadCitizen citizen)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_lead.belongsTo = citizen;
			return this;
		}

		public LeadBuilder At(LeadSpawnWhere where)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_lead.where = where;
			return this;
		}

		public LeadBuilder WithTree(string treeID, float progress = 3f)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			_lead.vmailThread = treeID;
			_lead.vmailProgressThreshold = new Vector2(progress, progress);
			return this;
		}

		public LeadBuilder WithPhysicalText(string treeID)
		{
			_physicalTextTreeID = treeID;
			return this;
		}

		public LeadBuilder WithItem(InteractablePreset preset)
		{
			_lead.spawnItem = preset;
			return this;
		}

		public LeadBuilder Tag(JobTag tag)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_lead.itemTag = tag;
			return this;
		}

		public LeadBuilder OnlyIf(JobTag prerequisiteTag)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			_lead.useIf = true;
			_lead.ifTag = prerequisiteTag;
			return this;
		}

		public LeadBuilder Security(int level)
		{
			_lead.security = level;
			return this;
		}

		public MurderLeadItem Build()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (_physicalTextTreeID != null)
			{
				if ((SoCustomComparison)(object)_lead.spawnItem == (SoCustomComparison)null)
				{
					SoDExpandedPlugin.Logger.LogWarning((object)("[" + _lead.name + "] WithPhysicalText() set but WithItem() is not — the tree has nothing to attach to and will be ignored."));
				}
				PhysicalTextRegistry.Register(_lead.itemTag, _physicalTextTreeID);
			}
			return _lead;
		}
	}
	public static class PhysicalTextRegistry
	{
		private static readonly Dictionary<JobTag, string> _overrides = new Dictionary<JobTag, string>();

		public static void Register(JobTag tag, string treeID)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			_overrides[tag] = treeID;
		}

		public static bool TryGet(JobTag tag, out string treeID)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return _overrides.TryGetValue(tag, out treeID);
		}
	}
	public class NeighborKillerDefinition : KillerMODefinition
	{
		public const string MO_NAME = "MO_NeighborKiller_Unforgiving";

		public const float SAME_FLOOR_BONUS = 6f;

		public override string MOName => "MO_NeighborKiller_Unforgiving";

		protected override void ConfigureMO(MurderMO mo, Toolbox toolbox)
		{
			mo.baseDifficulty = 1;
			mo.allowHome = true;
			mo.allowWork = false;
			mo.allowPublic = false;
			mo.allowStreets = false;
			mo.allowDen = false;
			mo.acquaintedSuitabilityBoost = 3;
			mo.likeSuitabilityBoost = 2;
			mo.attractedToSuitabilityBoost = 0;
			mo.sameWorkplaceBoost = 0;
			mo.murdererIsTenantBoost = 0;
			CharacterTrait val = FindTrait(toolbox, "Char-Unforgiving");
			if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
			{
				mo.murdererTraitModifiers.Add(RequiredTrait(val));
			}
			MurderMO val2 = FindWeaponDonor(toolbox);
			if ((SoCustomComparison)(object)val2 != (SoCustomComparison)null)
			{
				Enumerator<MurderWeaponsPool> enumerator = val2.weaponsPool.GetEnumerator();
				while (enumerator.MoveNext())
				{
					MurderWeaponsPool current = enumerator.Current;
					mo.weaponsPool.Add(current);
				}
			}
			mo.monkierDDSMessageList = BuildMonikerMessage(toolbox);
		}

		protected override void RegisterLeads(MurderMO mo, Toolbox toolbox)
		{
			string treeID = DDSBuilder.Vmail(toolbox).Named("SoDExpanded_NeighborKiller_GrudgeVmail").Message(0, 1, "Music. Again. Three nights this week. I can hear it so loud, it's like you're doing it on purpose.", "NeighborKiller_Vmail_Line1")
				.Message(1, 0, "It's a few songs after work. You're not the only one who lives here.", "NeighborKiller_Vmail_Line2")
				.Message(0, 1, "Then I guess we'll see who lives here longer.", "NeighborKiller_Vmail_Line3")
				.Build();
			mo.MOleads.Add(LeadBuilder.New("NeighborKiller_GrudgeVmail").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)1)
				.WithTree(treeID)
				.Tag((JobTag)21)
				.Build());
			string treeID2 = DDSBuilder.Document(toolbox).Named("SoDExpanded_NeighborKiller_GrudgeLetter").Message(0, 1, "I have asked you three times. Three times. You don't hear me because you don't care. People like you never do. Just know that I notice everything that happens on this floor. Everything. This is the last time I write to you.", "NeighborKiller_Letter_Body", handwriting: true)
				.Build();
			InteractablePreset val = FindInteractable(toolbox, "LetterGeneral");
			if ((SoCustomComparison)(object)val != (SoCustomComparison)null)
			{
				mo.MOleads.Add(LeadBuilder.New("NeighborKiller_GrudgeLetter").WrittenBy((LeadCitizen)2).ReceivedBy((LeadCitizen)1)
					.At((LeadSpawnWhere)0)
					.WithItem(val)
					.WithPhysicalText(treeID2)
					.Tag((JobTag)22)
					.Build());
			}
			else
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[NeighborKiller] LetterGeneral not found — physical letter lead skipped.");
			}
		}

		public static bool IsNeighbor(Human murderer, Human candidate)
		{
			if ((Object)(object)murderer.home == (Object)null || (Object)(object)candidate.home == (Object)null)
			{
				return false;
			}
			if (murderer.home.id == candidate.home.id)
			{
				return false;
			}
			if ((Object)(object)((NewGameLocation)murderer.home).building == (Object)null || (Object)(object)((NewGameLocation)candidate.home).building == (Object)null)
			{
				return false;
			}
			return ((NewGameLocation)murderer.home).building.buildingID == ((NewGameLocation)candidate.home).building.buildingID;
		}

		public static bool IsSameFloor(Human murderer, Human candidate)
		{
			NewAddress home = murderer.home;
			if (!((Object)(object)((home != null) ? ((NewGameLocation)home).floor : null) == (Object)null))
			{
				NewAddress home2 = candidate.home;
				if (!((Object)(object)((home2 != null) ? ((NewGameLocation)home2).floor : null) == (Object)null))
				{
					return ((NewGameLocation)murderer.home).floor.floor == ((NewGameLocation)candidate.home).floor.floor;
				}
			}
			return false;
		}

		private string BuildMonikerMessage(Toolbox toolbox)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			DDSMessageSave val = new DDSMessageSave
			{
				id = toolbox.GenerateUniqueID(),
				name = "SoDExpanded_NeighborKiller_Moniker"
			};
			string[] array = new string[4] { "The Corridor Killer", "The Hallway Killer", "The Floor Killer", "The Building Killer" };
			foreach (string text in array)
			{
				string text2 = toolbox.GenerateUniqueID();
				Strings.WriteToDictionary("dds.blocks", text2, "ShadowsOfDoubtExpanded neighbour killer moniker", text, "", 0, false, "");
				DDSBlockSave val2 = new DDSBlockSave
				{
					id = text2,
					name = "SoDExpanded_NeighborMoniker_" + text.Replace(" ", "")
				};
				toolbox.allDDSBlocks.Add(text2, val2);
				val.AddBlock(text2);
			}
			toolbox.allDDSMessages.Add(((DDSComponent)val).id, val);
			return ((DDSComponent)val).id;
		}
	}
	[HarmonyPatch(typeof(MurderController), "PickNewVictim")]
	public static class PickNewVictim_NeighborPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(MurderController __instance)
		{
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			MurderMO chosenMO = __instance.chosenMO;
			if (((chosenMO != null) ? ((Object)chosenMO).name : null) != "MO_NeighborKiller_Unforgiving")
			{
				return true;
			}
			float num = float.MinValue;
			__instance.currentVictim = null;
			__instance.currentVictimSite = null;
			MurderMO chosenMO2 = __instance.chosenMO;
			Enumerator<Citizen> enumerator = CityData.Instance.citizenDirectory.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Citizen current = enumerator.Current;
				if (((Actor)current).isPlayer || ((Actor)current).isDead || ((Actor)current).isHomeless || (Object)(object)current == (Object)(object)__instance.currentMurderer || __instance.previousMurderers.Contains((Human)(object)current) || !NeighborKillerDefinition.IsNeighbor(__instance.currentMurderer, (Human)(object)current))
				{
					continue;
				}
				float num2 = 0f;
				List<MurdererModifierRule> victimTraitModifiers = chosenMO2.victimTraitModifiers;
				if (MurderController.Instance.TraitTest(current, ref victimTraitModifiers, ref num2))
				{
					chosenMO2.victimTraitModifiers = victimTraitModifiers;
					float num3 = Toolbox.Instance.Rand(chosenMO2.victimRandomScoreRange.x, chosenMO2.victimRandomScoreRange.y, false);
					num3 += num2;
					if (NeighborKillerDefinition.IsSameFloor(__instance.currentMurderer, (Human)(object)current))
					{
						num3 += 6f;
					}
					Acquaintance val = null;
					if (__instance.currentMurderer.FindAcquaintanceExists((Human)(object)current, ref val))
					{
						num3 += (float)chosenMO2.acquaintedSuitabilityBoost;
						num3 += (float)chosenMO2.likeSuitabilityBoost * val.like;
					}
					if (__instance.currentMurderer.attractedTo.Contains(((Human)current).gender))
					{
						num3 += (float)chosenMO2.attractedToSuitabilityBoost;
					}
					if (num3 > num)
					{
						num = num3;
						__instance.currentVictim = (Human)(object)current;
					}
				}
			}
			if ((Object)(object)__instance.currentVictim == (Object)null)
			{
				SoDExpandedPlugin.Logger.LogWarning((object)"[NeighborKiller] No valid neighbor victim found — falling back to default selection.");
				return true;
			}
			ManualLogSource logger = SoDExpandedPlugin.Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[NeighborKiller] Victim selected: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(__instance.currentVictim.GetCitizenName());
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
			}
			logger.LogInfo(val2);
			return false;
		}
	}
	[BepInPlugin("ShadowsOfDoubtExpanded", "ShadowsOfDoubtExpanded", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SoDExpandedPlugin : BasePlugin
	{
		internal static ManualLogSource Logger;

		internal static Harmony HarmonyInstance;

		public override void Load()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			Logger.LogInfo((object)"ShadowsOfDoubtExpanded loading...");
			HarmonyInstance = new Harmony("ShadowsOfDoubtExpanded");
			HarmonyInstance.PatchAll();
			Logger.LogInfo((object)"ShadowsOfDoubtExpanded loaded. Killer pool expansion armed.");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ShadowsOfDoubtExpanded";

		public const string PLUGIN_NAME = "ShadowsOfDoubtExpanded";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}