using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.BepInEx.Configuration;
using SOD.Common.Extensions;
using SOD.Common.Helpers;
using SOD.LethalActionReborn.Patches;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SOD.LethalActionReborn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4d12de394cca59f54d683ec13e921db597f69b1f")]
[assembly: AssemblyProduct("SOD.LethalActionReborn")]
[assembly: AssemblyTitle("SOD.LethalActionReborn")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SOD.LethalActionReborn
{
public interface IPluginBindings
{
[Binding(1, "How many hits on the knocked out citizen are required to kill the citizen by the player?", "Citizens.HitsRequiredForKillAfterKo")]
int HitsRequiredForKillAfterKo { get; set; }
[Binding("", "Which weapon types won't kill citizens when attacked with by the player? (Comma-seperated) Available types are: fists,rifle,blade,bluntObject,handgun,shotgun", "Weapons.WeaponTypesExcludedFromKilling")]
string WeaponTypesExcludedFromKilling { get; set; }
}
[BepInPlugin("Venomaus.SOD.LethalActionReborn", "LethalActionReborn", "1.0.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : PluginController<Plugin, IPluginBindings>
{
public const string PLUGIN_GUID = "Venomaus.SOD.LethalActionReborn";
public const string PLUGIN_NAME = "LethalActionReborn";
public const string PLUGIN_VERSION = "1.0.4";
public override void Load()
{
Lib.SaveGame.OnAfterLoad += SaveGame_OnAfterLoad;
Lib.SaveGame.OnAfterSave += SaveGame_OnAfterSave;
Lib.SaveGame.OnAfterDelete += SaveGame_OnAfterDelete;
base.Harmony.PatchAll(Assembly.GetExecutingAssembly());
PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Plugin is patched.");
}
public override void OnConfigureBindings()
{
base.OnConfigureBindings();
CitizenPatches.Citizen_RecieveDamage.ExcludedWeaponTypes = (from a in base.Config.WeaponTypesExcludedFromKilling.Split(',')
select Enum.TryParse(typeof(WeaponType), a, ignoreCase: true, out object result) ? ((WeaponType?)result) : null into a
where a.HasValue
select a.Value).ToHashSet();
}
private void SaveGame_OnAfterDelete(object sender, SaveGameArgs e)
{
string uniqueString = Lib.SaveGame.GetUniqueString(e.FilePath);
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "lethalActioned_" + uniqueString + ".txt");
if (File.Exists(savestoreDirectoryPath))
{
File.Delete(savestoreDirectoryPath);
}
}
private void SaveGame_OnAfterSave(object sender, SaveGameArgs e)
{
string uniqueString = Lib.SaveGame.GetUniqueString(e.FilePath);
File.WriteAllText(Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "lethalActioned_" + uniqueString + ".txt"), string.Join(",", CitizenPatches.Citizen_RecieveDamage.KilledCitizens));
}
private void SaveGame_OnAfterLoad(object sender, SaveGameArgs e)
{
CitizenPatches.Citizen_RecieveDamage.CitizenHitsTakenOnKo.Clear();
string uniqueString = Lib.SaveGame.GetUniqueString(e.FilePath);
string savestoreDirectoryPath = Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), "lethalActioned_" + uniqueString + ".txt");
if (!File.Exists(savestoreDirectoryPath))
{
return;
}
HashSet<int> hashSet = (from a in File.ReadAllText(savestoreDirectoryPath).Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
select int.Parse(a)).ToHashSet();
HashSet<int> hashSet2 = (from a in EnumerableExtensions.ToList<Human>(CityData.Instance.deadCitizensDirectory)
select a.humanID).ToHashSet();
Human val = default(Human);
foreach (int item in hashSet)
{
CitizenPatches.Citizen_RecieveDamage.KilledCitizens.Add(item);
if (CityData.Instance.citizenDictionary.TryGetValue(item, ref val))
{
((Actor)val).SetHealth(0f);
((Actor)val).animationController.cit.Murder((Human)(object)Player.Instance, false, (Murder)null, (Interactable)null, 1f);
if (!hashSet2.Contains(item))
{
CityData.Instance.deadCitizensDirectory.Add(val);
hashSet2.Add(item);
}
int num = 0;
while ((Object)(object)MurderController.Instance.currentMurderer != (Object)null && MurderController.Instance.currentMurderer.humanID == item && num < 500)
{
num++;
MurderController.Instance.currentMurderer = null;
MurderController.Instance.PickNewMurderer();
}
num = 0;
while ((Object)(object)MurderController.Instance.currentVictim != (Object)null && MurderController.Instance.currentVictim.humanID == item && num < 500)
{
num++;
MurderController.Instance.currentVictim = null;
MurderController.Instance.PickNewVictim();
}
}
}
}
}
}
namespace SOD.LethalActionReborn.Patches
{
internal class CitizenPatches
{
[HarmonyPatch(typeof(Citizen), "RecieveDamage")]
internal static class Citizen_RecieveDamage
{
internal static readonly HashSet<int> KilledCitizens = new HashSet<int>();
private static bool _hasKilled = false;
internal static HashSet<WeaponType> ExcludedWeaponTypes = null;
internal static Dictionary<int, int> CitizenHitsTakenOnKo = new Dictionary<int, int>();
[HarmonyPrefix]
internal static void Prefix(Citizen __instance, Actor fromWho)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)fromWho == (Object)(object)Player.Instance) || !((Actor)__instance).ai.ko)
{
return;
}
if (ExcludedWeaponTypes != null && ExcludedWeaponTypes.Any() && BioScreenController.Instance.selectedSlot != null)
{
Interactable interactable = BioScreenController.Instance.selectedSlot.GetInteractable();
if (interactable != null && (SoCustomComparison)(object)interactable.preset.weapon != (SoCustomComparison)null)
{
MurderWeaponPreset weapon = interactable.preset.weapon;
if (ExcludedWeaponTypes.Contains(weapon.type))
{
_hasKilled = false;
return;
}
}
}
CitizenHitsTakenOnKo.TryGetValue(((Human)__instance).humanID, out var value);
value++;
CitizenHitsTakenOnKo[((Human)__instance).humanID] = value;
if (value >= ((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.HitsRequiredForKillAfterKo)
{
_hasKilled = true;
}
}
[HarmonyPostfix]
internal static void Postfix(Citizen __instance, Actor fromWho)
{
if (!((Actor)__instance).isDead && _hasKilled && (Object)(object)fromWho == (Object)(object)Player.Instance)
{
_hasKilled = false;
((Actor)__instance).SetHealth(0f);
((Actor)__instance).animationController.cit.Murder((Human)(object)Player.Instance, false, (Murder)null, (Interactable)null, 1f);
CityData.Instance.deadCitizensDirectory.Add((Human)(object)__instance);
KilledCitizens.Add(((Human)__instance).humanID);
int num = 0;
while ((Object)(object)MurderController.Instance.currentMurderer != (Object)null && MurderController.Instance.currentMurderer.humanID == ((Human)__instance).humanID && num < 500)
{
num++;
MurderController.Instance.currentMurderer = null;
MurderController.Instance.PickNewMurderer();
}
num = 0;
while ((Object)(object)MurderController.Instance.currentVictim != (Object)null && MurderController.Instance.currentVictim.humanID == ((Human)__instance).humanID && num < 500)
{
num++;
MurderController.Instance.currentVictim = null;
MurderController.Instance.PickNewVictim();
}
}
}
}
[HarmonyPatch(typeof(NewAIController), "SetKO")]
internal static class NewAIController_SetKO
{
[HarmonyPostfix]
internal static void Postfix(NewAIController __instance, bool val)
{
if (!val)
{
Citizen_RecieveDamage.CitizenHitsTakenOnKo.Remove(__instance.human.humanID);
}
}
}
}
}