Decompiled source of SistersOfSin v1.0.0

SistersOfSin.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using Microsoft.CodeAnalysis;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SistersOfSin")]
[assembly: AssemblyDescription("Triple First Sinner, shared health and phases")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Astrum Nova")]
[assembly: AssemblyProduct("Sisters Of Sin")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d13a3b2c-1a23-4c45-9123-7f5a7b8e9abc")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Silksong.Mods.SistersOfSin
{
	internal class Sinner
	{
		private const int SINGLE_SINNER_HP = 1300;

		public const int DEATH_HP_THRESHOLD = 100;

		public readonly GameObject gameObject;

		public readonly PlayMakerFSM[] allFSMs;

		public readonly PlayMakerFSM controlFSM;

		public readonly HealthManager healthManager;

		public Sinner(string tag)
		{
			GameObject obj = GameObject.Find("Boss Scene" + tag);
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = obj.transform.Find("First Weaver");
				obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			}
			gameObject = (GameObject)obj2;
			if (!((Object)(object)gameObject != (Object)null))
			{
				return;
			}
			allFSMs = gameObject.GetComponents<PlayMakerFSM>();
			controlFSM = ((IEnumerable<PlayMakerFSM>)allFSMs).FirstOrDefault((Func<PlayMakerFSM, bool>)((PlayMakerFSM f) => f.FsmName == "Control"));
			healthManager = gameObject.GetComponent<HealthManager>();
			healthManager.hp = 1300;
			Object.Destroy((Object)(object)FSMUtility.LocateMyFSM(gameObject, "Stun Control"));
			FsmState val = ((IEnumerable<FsmState>)controlFSM.FsmStates).FirstOrDefault((Func<FsmState, bool>)((FsmState state) => state.Name == "Bind Silk"));
			if (val == null)
			{
				return;
			}
			FsmStateAction[] actions = val.Actions;
			foreach (FsmStateAction obj4 in actions)
			{
				Wait val2 = (Wait)(object)((obj4 is Wait) ? obj4 : null);
				if (val2 != null)
				{
					val2.time = FsmFloat.op_Implicit(2.2f);
					break;
				}
			}
		}
	}
	[BepInPlugin("com.astrumnova.sistersofsin", "Sisters Of Sin", "0.0.1")]
	[BepInProcess("Hollow Knight Silksong.exe")]
	public class SistersOfSin : BaseUnityPlugin
	{
		private static Sinner sinnerA;

		private static Sinner sinnerB;

		private static Sinner sinnerC;

		private static bool phase2Mode;

		private const string P2_TRIGGER_STATE = "P2 Tele Pause";

		private static int cooldown;

		private void Awake()
		{
			Harmony.CreateAndPatchAll(typeof(SistersOfSin), (string)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"com.astrumnova.sistersofsin loaded and initialized!");
			((MonoBehaviour)this).StartCoroutine(WaitAndPatch());
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayMakerFSM), "OnEnable")]
		private static void OnFsmEnabled(PlayMakerFSM __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Scene scene = ((Component)__instance).gameObject.scene;
			if (((Scene)(ref scene)).name == "Slab_10b" && ((Object)__instance).name == "Boss Scene" && !((Object)__instance).name.Contains("CLONE"))
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)__instance).gameObject, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation, ((Component)__instance).transform.parent);
				GameObject obj = Object.Instantiate<GameObject>(((Component)__instance).gameObject, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation, ((Component)__instance).transform.parent);
				((Object)__instance).name = ((Object)__instance).name + "CLONEA";
				((Object)val).name = ((Object)val).name + "CLONEB";
				((Object)obj).name = ((Object)obj).name + "CLONEC";
				sinnerA = null;
				sinnerB = null;
				sinnerC = null;
				phase2Mode = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FsmState), "OnEnter")]
		private static void OnFSMStateEntered(FsmState __instance)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Fsm fsm = __instance.Fsm;
			PlayMakerFSM val = ((fsm != null) ? fsm.FsmComponent : null);
			if ((Object)(object)val == (Object)null || !(((Object)val).name == "First Weaver"))
			{
				return;
			}
			Scene scene = ((Component)val).gameObject.scene;
			if (!(((Scene)(ref scene)).name == "Slab_10b"))
			{
				return;
			}
			if (__instance.Name == "First Idle" && sinnerA == null && sinnerB == null && sinnerC == null)
			{
				sinnerA = new Sinner("CLONEA");
				sinnerB = new Sinner("(Clone)CLONEB");
				sinnerC = new Sinner("(Clone)CLONEC");
				sinnerA.controlFSM.SetState("Cancel To Tele");
				sinnerB.controlFSM.SetState("Cancel To Tele");
				sinnerC.controlFSM.SetState("Cancel To Tele");
			}
			if (__instance.Name == "Death Stagger F")
			{
				sinnerA.healthManager.hp = 750;
				sinnerB.healthManager.hp = 750;
				sinnerC.healthManager.hp = 750;
			}
			if (__instance.Name == "P2 Tele Pause" && !phase2Mode)
			{
				HandlePhase2(sinnerA);
				HandlePhase2(sinnerB);
				HandlePhase2(sinnerC);
				if (sinnerA.controlFSM.ActiveStateName == "P2 Tele Pause" && sinnerB.controlFSM.ActiveStateName == "P2 Tele Pause" && sinnerC.controlFSM.ActiveStateName == "P2 Tele Pause")
				{
					sinnerA.controlFSM.Fsm.ManualUpdate = false;
					sinnerB.controlFSM.Fsm.ManualUpdate = false;
					sinnerC.controlFSM.Fsm.ManualUpdate = false;
					sinnerA.healthManager.hp = 750;
					sinnerB.healthManager.hp = 750;
					sinnerC.healthManager.hp = 750;
					phase2Mode = true;
				}
			}
			if (__instance.Name == "Hornet Dead")
			{
				sinnerA = null;
				sinnerB = null;
				sinnerC = null;
				phase2Mode = false;
			}
		}

		private static void HandlePhase2(Sinner sinner)
		{
			if (sinner.controlFSM.ActiveStateName == "P2 Tele Pause" && !sinner.controlFSM.Fsm.ManualUpdate)
			{
				sinner.controlFSM.Fsm.ManualUpdate = true;
			}
		}

		private void FixedUpdate()
		{
			if (sinnerA == null || sinnerB == null || sinnerC == null)
			{
				return;
			}
			if (sinnerA.healthManager.hp != sinnerB.healthManager.hp || sinnerB.healthManager.hp != sinnerC.healthManager.hp || sinnerC.healthManager.hp != sinnerA.healthManager.hp)
			{
				int hp = (sinnerA.healthManager.hp + sinnerB.healthManager.hp + sinnerC.healthManager.hp - ((cooldown == 0) ? 30 : 0)) / 3;
				sinnerA.healthManager.hp = (sinnerB.healthManager.hp = (sinnerC.healthManager.hp = hp));
				if (cooldown == 0)
				{
					cooldown = 30;
				}
			}
			if (sinnerA.healthManager.hp <= 100)
			{
				sinnerA.healthManager.Die((float?)1f, (AttackTypes)1, false);
				sinnerB.healthManager.Die((float?)1f, (AttackTypes)1, false);
				sinnerC.healthManager.Die((float?)1f, (AttackTypes)1, false);
			}
			if (cooldown > 0)
			{
				cooldown--;
			}
		}

		private IEnumerator WaitAndPatch()
		{
			yield return (object)new WaitForSeconds(2f);
			Harmony.CreateAndPatchAll(typeof(Language_Get_Patch), (string)null);
		}
	}
	[HarmonyPatch(typeof(Language), "Get")]
	[HarmonyPatch(new Type[]
	{
		typeof(string),
		typeof(string)
	})]
	public static class Language_Get_Patch
	{
		private static void Postfix(string key, string sheetTitle, ref string __result)
		{
			if (key == "FIRST_WEAVER_SUPER")
			{
				__result = "Sisters Of";
			}
			if (key == "FIRST_WEAVER_MAIN")
			{
				__result = "Sin";
			}
		}
	}
}