From 229fb4bc9185d8b575c56d4da2071c3495e3cb85 Mon Sep 17 00:00:00 2001 From: Frank Yang Date: Fri, 27 Jan 2023 01:32:52 +0800 Subject: [PATCH] feat: make no low health effect toggleable any time --- GodSeekerPlus/GodSeekerPlus.csproj | 2 +- .../Modules/Cosmetic/NoLowHealthEffect.cs | 76 ++++++++++++++----- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/GodSeekerPlus/GodSeekerPlus.csproj b/GodSeekerPlus/GodSeekerPlus.csproj index 1d8afe6..4067573 100644 --- a/GodSeekerPlus/GodSeekerPlus.csproj +++ b/GodSeekerPlus/GodSeekerPlus.csproj @@ -1,7 +1,7 @@ GodSeekerPlus - 0.22.0 + 0.23.0 A Hollow Knight mod to enhance your Godhome experience Clazex diff --git a/GodSeekerPlus/Modules/Cosmetic/NoLowHealthEffect.cs b/GodSeekerPlus/Modules/Cosmetic/NoLowHealthEffect.cs index 0bb7427..d7f519c 100644 --- a/GodSeekerPlus/Modules/Cosmetic/NoLowHealthEffect.cs +++ b/GodSeekerPlus/Modules/Cosmetic/NoLowHealthEffect.cs @@ -3,42 +3,84 @@ namespace GodSeekerPlus.Modules.Cosmetic; public sealed class NoLowHealthEffect : Module { - public override ToggleableLevel ToggleableLevel => ToggleableLevel.ReloadSave; + private static readonly GameObjectRef healthRef = + new(GameObjectRef.DONT_DESTROY_ON_LOAD, "_GameCameras", "HudCamera", "Hud Canvas", "Health"); - private protected override void Load() { + private static readonly GameObjectRef damageEffectsRef = + new(GameObjectRef.DONT_DESTROY_ON_LOAD, "Knight", "Effects", "Damage Effect"); + + public NoLowHealthEffect() => On.PlayMakerFSM.Start += ModifyFSM; + + private protected override void Load() { IL.HeroAnimationController.PlayIdle += RemoveAnimation; + + if (Ref.HC != null) { + Fsm fsm = GameObjectUtil.FindGameObjectByRef(Ref.DDOL, healthRef).LocateMyFSM("Low Health FX").Fsm; + + if (fsm.ActiveStateName is "Low Health On Entry" or "Low Health") { + fsm.SetState("Idle"); + } + } } private protected override void Unload() { - On.PlayMakerFSM.Start -= ModifyFSM; IL.HeroAnimationController.PlayIdle -= RemoveAnimation; + + if (Ref.HC != null) { + Fsm fsm = GameObjectUtil.FindGameObjectByRef(Ref.DDOL, healthRef).LocateMyFSM("Low Health FX").Fsm; + + if (fsm.ActiveStateName == "Idle") { + fsm.SetState("Low Health?"); + } + } } private void ModifyFSM(On.PlayMakerFSM.orig_Start orig, PlayMakerFSM self) { orig(self); - if (self is { - name: "Health", - FsmName: "Low Health FX" - }) { + if (self.FsmName == "Low Health FX" && healthRef.MatchGameObject(self.gameObject)) { ModifyLowHealthFXFSM(self); - } else if (self is { - name: "Damage Effect", - FsmName: "Knight Damage" - }) { + } else if (self.FsmName == "Knight Damage" && damageEffectsRef.MatchGameObject(self.gameObject)) { ModifyDamageEffectFSM(self); } } - private static void ModifyLowHealthFXFSM(PlayMakerFSM fsm) { - fsm.ChangeTransition("Init", "LOW", "Idle"); - fsm.ChangeTransition("HUD In HP Check", "LOW", "Idle"); - fsm.RemoveTransition("Idle", "HERO DAMAGED"); + private void ModifyLowHealthFXFSM(PlayMakerFSM fsm) { + bool shouldActivate() => Loaded; + + fsm.Intercept(new TransitionInterceptor() { + fromState = "Init", + eventName = "LOW", + toStateDefault = "Low Health On Entry", + toStateCustom = "Idle", + shouldIntercept = shouldActivate + }); + + fsm.Intercept(new TransitionInterceptor() { + fromState = "HUD In HP Check", + eventName = "LOW", + toStateDefault = "Low Health On Entry", + toStateCustom = "Idle", + shouldIntercept = shouldActivate + }); + + fsm.Intercept(new TransitionInterceptor() { + fromState = "Idle", + eventName = "HERO DAMAGED", + toStateDefault = "Low Health Pause", + toStateCustom = "Idle", + shouldIntercept = shouldActivate + }); } - private static void ModifyDamageEffectFSM(PlayMakerFSM fsm) => - fsm.ChangeTransition("Check Focus Prompt", FsmEvent.Finished.Name, "Leak"); + private void ModifyDamageEffectFSM(PlayMakerFSM fsm) => fsm.Intercept(new TransitionInterceptor() { + fromState = "Check Focus Prompt", + eventName = FsmEvent.Finished.Name, + toStateDefault = "Last HP?", + toStateCustom = "Leak", + shouldIntercept = () => Loaded + }); private static void RemoveAnimation(ILContext il) { int index = new ILCursor(il).Goto(0).GotoNext(