From b9df7b832e4e837cdafde0b3de352938841d177b Mon Sep 17 00:00:00 2001 From: BubkisLord <101391373+BubkisLord@users.noreply.github.com> Date: Sun, 5 Jun 2022 18:35:09 +0800 Subject: [PATCH] Add files via upload --- Charm.cs | 24 +++ CharmMod.cs | 271 ++++++++++++++++++++++++++++++ CharmMod.csproj | 365 +++++++++++++++++++++++++++++++++++++++++ CharmSettings.cs | 10 ++ DebugModHook.cs | 32 ++++ DummyMonoBehaviour.cs | 3 + EmbeddedSprites.cs | 32 ++++ FuncAction.cs | 20 +++ PlayMakerExtensions.cs | 82 +++++++++ README.md | 3 + RandoSettings.cs | 0 RawRandoSettings.cs | 11 ++ SaveSettings.cs | 21 +++ 13 files changed, 874 insertions(+) create mode 100644 Charm.cs create mode 100644 CharmMod.cs create mode 100644 CharmMod.csproj create mode 100644 CharmSettings.cs create mode 100644 DebugModHook.cs create mode 100644 DummyMonoBehaviour.cs create mode 100644 EmbeddedSprites.cs create mode 100644 FuncAction.cs create mode 100644 PlayMakerExtensions.cs create mode 100644 README.md create mode 100644 RandoSettings.cs create mode 100644 RawRandoSettings.cs create mode 100644 SaveSettings.cs diff --git a/Charm.cs b/Charm.cs new file mode 100644 index 0000000..40f0e3a --- /dev/null +++ b/Charm.cs @@ -0,0 +1,24 @@ +namespace CharmMod +{ + internal abstract class Charm + { + public abstract string Sprite { get; } + public abstract string Name { get; } + public abstract string Description { get; } + public abstract int DefaultCost { get; } + public abstract string Scene { get; } + public abstract float X { get; } + public abstract float Y { get; } + + // assigned at runtime by SFCore's CharmHelper + public int Num { get; set; } + + public bool Equipped() => PlayerData.instance.GetBool($"equippedCharm_{Num}"); + + public abstract CharmSettings Settings(SaveSettings s); + + public virtual void Hook() {} + public virtual List<(string obj, string fsm, Action edit)> FsmEdits => new(); + public virtual List<(int Period, Action Func)> Tickers => new(); + } +} diff --git a/CharmMod.cs b/CharmMod.cs new file mode 100644 index 0000000..06546d4 --- /dev/null +++ b/CharmMod.cs @@ -0,0 +1,271 @@ +global using System; +global using System.IO; +global using System.Collections; +global using Modding; +global using UnityEngine; +global using SFCore; +global using System.Collections.Generic; +global using System.Linq; + +namespace CharmMod +{ + public class CharmMod : Mod, ILocalSettings + { + private static List Charms = new() + { + Quickfall.Instance, + Slowfall.Instance, + SturdyNail.Instance, + BetterCDash.Instance, + GlassCannon.Instance, + HKBlessing.Instance, + HuntersMark.Instance, + PowerfulDash.Instance, + WealthyAmulet.Instance, + TripleJump.Instance + }; + + internal static CharmMod Instance; + + private Dictionary> BoolGetters = new(); + private Dictionary> BoolSetters = new(); + private Dictionary> IntGetters = new(); + private Dictionary<(string, string), Action> FSMEdits = new(); + private List<(int Period, Action Func)> Tickers = new(); + + public override void Initialize() + { + Log("Initializing"); + Instance = this; + foreach (var charm in Charms) + { + var num = CharmHelper.AddSprites(EmbeddedSprites.Get(charm.Sprite))[0]; + charm.Num = num; + var settings = charm.Settings; + this.IntGetters[string.Format("charmCost_{0}", num)] = ((int _) => settings(this.Settings).Cost); + AddTextEdit($"CHARM_NAME_{num}", "UI", charm.Name); + AddTextEdit($"CHARM_DESC_{num}", "UI", () => charm.Description); + BoolGetters[$"equippedCharm_{num}"] = _ => settings(Settings).Equipped; + BoolSetters[$"equippedCharm_{num}"] = value => settings(Settings).Equipped = value; + BoolGetters[$"gotCharm_{num}"] = _ => settings(Settings).Got; + BoolSetters[$"gotCharm_{num}"] = value => settings(Settings).Got = value; + BoolGetters[$"newCharm_{num}"] = _ => settings(Settings).New; + BoolSetters[$"newCharm_{num}"] = value => settings(Settings).New = value; + charm.Hook(); + foreach (var edit in charm.FsmEdits) + { + AddFsmEdit(edit.obj, edit.fsm, edit.edit); + } + Tickers.AddRange(charm.Tickers); + } + for (var i = 1; i <= 40; i++) + { + var num = i; // needed for closure to capture a different copy of the variable each time + BoolGetters[$"equippedCharm_{num}"] = value => value; + this.IntGetters[string.Format("charmCost_{0}", num)] = ((int value) => value); + } + + ModHooks.GetPlayerBoolHook += ReadCharmBools; + ModHooks.SetPlayerBoolHook += WriteCharmBools; + ModHooks.GetPlayerIntHook += ReadCharmCosts; + ModHooks.LanguageGetHook += GetCharmStrings; + // This will run after Rando has already set up its item placements. + On.PlayMakerFSM.OnEnable += EditFSMs; + On.PlayerData.CountCharms += CountOurCharms; + ModHooks.NewGameHook += GiveCharms; + ModHooks.HeroUpdateHook += SetDefaultNotchCosts; + StartTicking(); + if (ModHooks.GetMod("DebugMod") != null) + { + DebugModHook.GiveAllCharms(() => { + GrantAllOurCharms(); + PlayerData.instance.CountCharms(); + }); + } + } + // breaks infinite loop when reading equippedCharm_X + private bool Equipped(Charm c) => c.Settings(Settings).Equipped; + + private Dictionary<(string Key, string Sheet), Func> TextEdits = new(); + + internal void AddTextEdit(string key, string sheetName, string text) + { + TextEdits.Add((key, sheetName), () => text); + } + + internal void AddTextEdit(string key, string sheetName, Func text) + { + TextEdits.Add((key, sheetName), text); + } + private void GiveCharms() + { + GrantAllOurCharms(); + } + public override string GetVersion() => "6.3.2"; + + internal SaveSettings Settings = new(); + + + + private bool ReadCharmBools(string boolName, bool value) + { + if (BoolGetters.TryGetValue(boolName, out var f)) + { + return f(value); + } + return value; + } + + private bool WriteCharmBools(string boolName, bool value) + { + if (BoolSetters.TryGetValue(boolName, out var f)) + { + f(value); + } + return value; + } + + private int ReadCharmCosts(string intName, int value) + { + Func cost; + bool flag = this.IntGetters.TryGetValue(intName, out cost); + int result; + if (flag) + { + result = cost(value); + } + else + { + result = value; + } + return result; + } + + private string GetCharmStrings(string key, string sheetName, string orig) + { + if (TextEdits.TryGetValue((key, sheetName), out var text)) + { + return text(); + } + return orig; + } + private void SetDefaultNotchCosts() + { + GrantAllOurCharms(); + foreach (Charm charm in CharmMod.Charms) + { + charm.Settings(this.Settings).Cost = charm.DefaultCost; + } + } + + internal void AddFsmEdit(string objName, string fsmName, Action edit) + { + var key = (objName, fsmName); + var newEdit = edit; + if (FSMEdits.TryGetValue(key, out var orig)) + { + newEdit = fsm => { + orig(fsm); + edit(fsm); + }; + } + FSMEdits[key] = newEdit; + } + + private void EditFSMs(On.PlayMakerFSM.orig_OnEnable orig, PlayMakerFSM fsm) + { + orig(fsm); + if (FSMEdits.TryGetValue((fsm.gameObject.name, fsm.FsmName), out var edit)) + { + edit(fsm); + } + } + + private void StartTicking() + { + // Use our own object to hold timers so that GameManager.StopAllCoroutines + // does not kill them. + var timerHolder = new GameObject("Timer Holder"); + GameObject.DontDestroyOnLoad(timerHolder); + var timers = timerHolder.AddComponent(); + foreach (var t in Tickers) + { + IEnumerator ticker() + { + while (true) + { + try + { + t.Func(); + } + catch (Exception ex) + { + LogError(ex); + } + yield return new WaitForSeconds(t.Period); + } + } + + timers.StartCoroutine(ticker()); + } + } + + private void CountOurCharms(On.PlayerData.orig_CountCharms orig, PlayerData self) + { + orig(self); + self.SetInt("charmsOwned", self.GetInt("charmsOwned") + Charms.Count(c => c.Settings(Settings).Got)); + } + + private void RandomizeNotchCosts(int seed) + { + // This log statement is here to help diagnose a possible bug where charms cost more than + // they ever should. + Log("Randomizing notch costs"); + var rng = new System.Random(seed); + var total = Charms.Select(x => x.DefaultCost).Sum(); + for (var i = 0; i < total; i++) + { + var possiblePicks = Charms.Select(x => x.Settings(Settings)).Where(s => s.Cost < 6).ToList(); + if (possiblePicks.Count == 0) + { + break; + } + var pick = rng.Next(possiblePicks.Count); + possiblePicks[pick].Cost++; + } + } + + internal static void UpdateNailDamage() + { + IEnumerator WaitThenUpdate() + { + yield return null; + PlayMakerFSM.BroadcastEvent("UPDATE NAIL DAMAGE"); + } + GameManager.instance.StartCoroutine(WaitThenUpdate()); + } + + public void GrantAllOurCharms() + { + foreach (var charm in Charms) + { + charm.Settings(Settings).Got = true; + } + } + + public void OnLoadLocal(SaveSettings s) + { + ((ILocalSettings)Instance).OnLoadLocal(s); + } + + SaveSettings ILocalSettings.OnSaveLocal() + { + return ((ILocalSettings)Instance).OnSaveLocal(); + } + + public SaveSettings OnSaveLocal() + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/CharmMod.csproj b/CharmMod.csproj new file mode 100644 index 0000000..d4c4af9 --- /dev/null +++ b/CharmMod.csproj @@ -0,0 +1,365 @@ + + + + C:\Program Files (x86)\Hollow Knight\Hollow Knight_Data\Managed\ + + C:\Users\oldfi\Desktop\ + + + + + CharmMod + CharmMod + net472 + CharmMod + CharmMod + A Hollow Knight Mod + Copyright © $year$ + 1.5.2 + 1.5.2 + bin\$(Configuration)\ + latest + + + + + + + + + + + + + + + SHA256 - $(AssemblyTitle).dll, Version $(AssemblyVersion): + + + + + + + + C:/Program Files (x86)/Hollow Knight/Hollow Knight_Data/Managed/Mods/Satchel/Satchel.dll + + + C:/Program Files (x86)/Hollow Knight/Hollow Knight_Data/Managed/Mods/ModCommon/ModCommon.dll + + + $(HollowKnightRefs)/Assembly-CSharp.dll + + + $(HollowKnightRefs)/MMHOOK_Assembly-CSharp.dll + + + $(HollowKnightRefs)/MMHOOK_PlayMaker.dll + + + $(HollowKnightRefs)/MonoMod.RuntimeDetour.dll + + + $(HollowKnightRefs)/Newtonsoft.Json.dll + + + $(HollowKnightRefs)/PlayMaker.dll + + + $(HollowKnightRefs)/UnityEngine.dll + + + $(HollowKnightRefs)/UnityEngine.CoreModule.dll + + + $(HollowKnightRefs)/UnityEngine.Physics2DModule.dll + + + $(HollowKnightRefs)/UnityEngine.ImageConversionModule.dll + + + $(HollowKnightRefs)/Mods/SFCore/SFCore.dll + + + $(HollowKnightRefs)/Mods/ItemChanger/ItemChanger.dll + + + $(HollowKnightRefs)/Mods/MenuChanger/MenuChanger.dll + + + $(HollowKnightRefs)/Mods/Randomizer 4/RandomizerMod.dll + + + $(HollowKnightRefs)/Mods/RandomizerCore/RandomizerCore.dll + + + $(HollowKnightRefs)/Assembly-CSharp.dll + + + $(HollowKnightRefs)/Assembly-CSharp-firstpass.dll + + + $(HollowKnightRefs)/GalaxyCSharp.dll + + + $(HollowKnightRefs)/MMHOOK_Assembly-CSharp.dll + + + $(HollowKnightRefs)/MMHOOK_PlayMaker.dll + + + $(HollowKnightRefs)/Mono.Cecil.dll + + + $(HollowKnightRefs)/Mono.Security.dll + + + $(HollowKnightRefs)/MonoMod.RuntimeDetour.dll + + + $(HollowKnightRefs)/MonoMod.Utils.dll + + + $(HollowKnightRefs)/netstandard.dll + + + $(HollowKnightRefs)/Newtonsoft.Json.dll + + + $(HollowKnightRefs)/PlayMaker.dll + + + $(HollowKnightRefs)/System.ComponentModel.Composition.dll + + + $(HollowKnightRefs)/System.Configuration.dll + + + $(HollowKnightRefs)/System.Diagnostics.StackTrace.dll + + + $(HollowKnightRefs)/System.EnterpriseServices.dll + + + $(HollowKnightRefs)/System.Globalization.Extensions.dll + + + $(HollowKnightRefs)/System.IO.Compression.dll + + + $(HollowKnightRefs)/System.Net.Http.dll + + + $(HollowKnightRefs)/System.Runtime.Serialization.Xml.dll + + + $(HollowKnightRefs)/System.ServiceModel.Internals.dll + + + $(HollowKnightRefs)/System.Transactions.dll + + + $(HollowKnightRefs)/System.Xml.XPath.XDocument.dll + + + $(HollowKnightRefs)/Unity.Timeline.dll + + + $(HollowKnightRefs)/UnityEngine.dll + + + $(HollowKnightRefs)/UnityEngine.AccessibilityModule.dll + + + $(HollowKnightRefs)/UnityEngine.AIModule.dll + + + $(HollowKnightRefs)/UnityEngine.AndroidJNIModule.dll + + + $(HollowKnightRefs)/UnityEngine.AnimationModule.dll + + + $(HollowKnightRefs)/UnityEngine.ARModule.dll + + + $(HollowKnightRefs)/UnityEngine.AssetBundleModule.dll + + + $(HollowKnightRefs)/UnityEngine.AudioModule.dll + + + $(HollowKnightRefs)/UnityEngine.ClothModule.dll + + + $(HollowKnightRefs)/UnityEngine.ClusterInputModule.dll + + + $(HollowKnightRefs)/UnityEngine.ClusterRendererModule.dll + + + $(HollowKnightRefs)/UnityEngine.CoreModule.dll + + + $(HollowKnightRefs)/UnityEngine.CrashReportingModule.dll + + + $(HollowKnightRefs)/UnityEngine.DirectorModule.dll + + + $(HollowKnightRefs)/UnityEngine.DSPGraphModule.dll + + + $(HollowKnightRefs)/UnityEngine.GameCenterModule.dll + + + $(HollowKnightRefs)/UnityEngine.GIModule.dll + + + $(HollowKnightRefs)/UnityEngine.GridModule.dll + + + $(HollowKnightRefs)/UnityEngine.HotReloadModule.dll + + + $(HollowKnightRefs)/UnityEngine.ImageConversionModule.dll + + + $(HollowKnightRefs)/UnityEngine.IMGUIModule.dll + + + $(HollowKnightRefs)/UnityEngine.InputLegacyModule.dll + + + $(HollowKnightRefs)/UnityEngine.InputModule.dll + + + $(HollowKnightRefs)/UnityEngine.JSONSerializeModule.dll + + + $(HollowKnightRefs)/UnityEngine.LocalizationModule.dll + + + $(HollowKnightRefs)/UnityEngine.ParticleSystemModule.dll + + + $(HollowKnightRefs)/UnityEngine.PerformanceReportingModule.dll + + + $(HollowKnightRefs)/UnityEngine.Physics2DModule.dll + + + $(HollowKnightRefs)/UnityEngine.PhysicsModule.dll + + + $(HollowKnightRefs)/UnityEngine.ProfilerModule.dll + + + $(HollowKnightRefs)/UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll + + + $(HollowKnightRefs)/UnityEngine.ScreenCaptureModule.dll + + + $(HollowKnightRefs)/UnityEngine.SharedInternalsModule.dll + + + $(HollowKnightRefs)/UnityEngine.SpriteMaskModule.dll + + + $(HollowKnightRefs)/UnityEngine.SpriteShapeModule.dll + + + $(HollowKnightRefs)/UnityEngine.StreamingModule.dll + + + $(HollowKnightRefs)/UnityEngine.SubstanceModule.dll + + + $(HollowKnightRefs)/UnityEngine.SubsystemsModule.dll + + + $(HollowKnightRefs)/UnityEngine.TerrainModule.dll + + + $(HollowKnightRefs)/UnityEngine.TerrainPhysicsModule.dll + + + $(HollowKnightRefs)/UnityEngine.TextCoreModule.dll + + + $(HollowKnightRefs)/UnityEngine.TextRenderingModule.dll + + + $(HollowKnightRefs)/UnityEngine.TilemapModule.dll + + + $(HollowKnightRefs)/UnityEngine.TLSModule.dll + + + $(HollowKnightRefs)/UnityEngine.UI.dll + + + $(HollowKnightRefs)/UnityEngine.UIElementsModule.dll + + + $(HollowKnightRefs)/UnityEngine.UIElementsNativeModule.dll + + + $(HollowKnightRefs)/UnityEngine.UIModule.dll + + + $(HollowKnightRefs)/UnityEngine.UmbraModule.dll + + + $(HollowKnightRefs)/UnityEngine.UNETModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityAnalyticsModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityConnectModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityCurlModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityTestProtocolModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityWebRequestAssetBundleModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityWebRequestAudioModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityWebRequestModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityWebRequestTextureModule.dll + + + $(HollowKnightRefs)/UnityEngine.UnityWebRequestWWWModule.dll + + + $(HollowKnightRefs)/UnityEngine.VehiclesModule.dll + + + $(HollowKnightRefs)/UnityEngine.VFXModule.dll + + + $(HollowKnightRefs)/UnityEngine.VideoModule.dll + + + $(HollowKnightRefs)/UnityEngine.VirtualTexturingModule.dll + + + $(HollowKnightRefs)/UnityEngine.VRModule.dll + + + $(HollowKnightRefs)/UnityEngine.WindModule.dll + + + $(HollowKnightRefs)/UnityEngine.XRModule.dll + + + \ No newline at end of file diff --git a/CharmSettings.cs b/CharmSettings.cs new file mode 100644 index 0000000..f63872e --- /dev/null +++ b/CharmSettings.cs @@ -0,0 +1,10 @@ +namespace CharmMod +{ + public class CharmSettings + { + public bool Got; + public bool Equipped; + public bool New; + public int Cost; + } +} \ No newline at end of file diff --git a/DebugModHook.cs b/DebugModHook.cs new file mode 100644 index 0000000..a38cdd7 --- /dev/null +++ b/DebugModHook.cs @@ -0,0 +1,32 @@ +global using System.Reflection; +global using MonoMod.RuntimeDetour; + +namespace CharmMod +{ + // This needs to be in its own class because for some reason the Hook constructor would do reflection on the + // Transcendence class, see methods with signatures that reference Randomizer and MenuChanger, and throw an + // exception if those weren't installed. + internal static class DebugModHook + { + public static void GiveAllCharms(Action a) + { + var commands = Type.GetType("DebugMod.BindableFunctions, DebugMod"); + if (commands == null) + { + return; + } + var method = commands.GetMethod("GiveAllCharms", BindingFlags.Public | BindingFlags.Static); + if (method == null) + { + return; + } + new Hook( + method, + (Action orig) => { + orig(); + a(); + } + ); + } + } +} \ No newline at end of file diff --git a/DummyMonoBehaviour.cs b/DummyMonoBehaviour.cs new file mode 100644 index 0000000..fbf51e2 --- /dev/null +++ b/DummyMonoBehaviour.cs @@ -0,0 +1,3 @@ +using UnityEngine; + +internal class DummyMonoBehaviour : MonoBehaviour {} \ No newline at end of file diff --git a/EmbeddedSprites.cs b/EmbeddedSprites.cs new file mode 100644 index 0000000..80e382d --- /dev/null +++ b/EmbeddedSprites.cs @@ -0,0 +1,32 @@ +using UnityEngine; +using System.Reflection; +using System.IO; + +namespace CharmMod +{ + internal static class EmbeddedSprites + { + private static Dictionary Sprites = new(); + + public static Sprite Get(string name) + { + if (Sprites.TryGetValue(name, out var sprite)) + { + return sprite; + } + sprite = LoadSprite(name); + Sprites[name] = sprite; + return sprite; + } + + private static Sprite LoadSprite(string name) + { + var loc = Path.Combine(Path.GetDirectoryName(typeof(EmbeddedSprites).Assembly.Location), name); + var imageData = File.ReadAllBytes(loc); + var tex = new Texture2D(1, 1, TextureFormat.RGBA32, false); + ImageConversion.LoadImage(tex, imageData, true); + tex.filterMode = FilterMode.Bilinear; + return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(.5f, .5f)); + } + } +} \ No newline at end of file diff --git a/FuncAction.cs b/FuncAction.cs new file mode 100644 index 0000000..daa6870 --- /dev/null +++ b/FuncAction.cs @@ -0,0 +1,20 @@ +using HutongGames.PlayMaker; + +namespace CharmMod +{ + internal class FuncAction : FsmStateAction + { + private readonly Action _func; + + public FuncAction(Action func) + { + _func = func; + } + + public override void OnEnter() + { + _func(); + Finish(); + } + } +} \ No newline at end of file diff --git a/PlayMakerExtensions.cs b/PlayMakerExtensions.cs new file mode 100644 index 0000000..0587112 --- /dev/null +++ b/PlayMakerExtensions.cs @@ -0,0 +1,82 @@ +global using HutongGames.PlayMaker; + +namespace CharmMod +{ + internal static class PlayMakerExtensions + { + internal static FsmState AddState(this PlayMakerFSM fsm, string name) + { + var dest = new FsmState[fsm.FsmStates.Length + 1]; + Array.Copy(fsm.FsmStates, dest, fsm.FsmStates.Length); + var newState = new FsmState(fsm.Fsm) + { + Name = name, + Transitions = Array.Empty(), + Actions = Array.Empty() + }; + dest[fsm.FsmStates.Length] = newState; + fsm.Fsm.States = dest; + return newState; + } + + internal static FsmState GetState(this PlayMakerFSM fsm, string name) + { + return fsm.FsmStates.FirstOrDefault(s => s.Name == name); + } + + internal static void RemoveAction(this FsmState s, int i) + { + var actions = new FsmStateAction[s.Actions.Length - 1]; + Array.Copy(s.Actions, actions, i); + Array.Copy(s.Actions, i + 1, actions, i, s.Actions.Length - i - 1); + s.Actions = actions; + } + + internal static void AddAction(this FsmState s, Action a) + { + SpliceAction(s, s.Actions.Length, a); + } + + internal static void SpliceAction(this FsmState s, int pos, Action a) + { + var actions = new FsmStateAction[s.Actions.Length + 1]; + Array.Copy(s.Actions, actions, pos); + actions[pos] = new FuncAction(a); + Array.Copy(s.Actions, pos, actions, pos + 1, s.Actions.Length - pos); + s.Actions = actions; + } + + internal static void PrependAction(this FsmState s, Action a) + { + SpliceAction(s, 0, a); + } + + internal static void ReplaceAction(this FsmState s, int i, Action a) + { + s.Actions[i] = new FuncAction(a); + } + + internal static void AddTransition(this FsmState s, string eventName, string toState) + { + var transitions = new FsmTransition[s.Transitions.Length + 1]; + Array.Copy(s.Transitions, transitions, s.Transitions.Length); + transitions[s.Transitions.Length] = new FsmTransition + { + FsmEvent = FsmEvent.GetFsmEvent(eventName), + ToFsmState = s.Fsm.GetState(toState), + ToState = toState, + }; + s.Transitions = transitions; + } + + internal static void RemoveAllTransitions(this FsmState s) + { + s.Transitions = new FsmTransition[0]; + } + + internal static FsmInt GetFsmInt(this PlayMakerFSM fsm, string name) + { + return fsm.FsmVariables.IntVariables.FirstOrDefault(v => v.Name == name); + } + } +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c96a165 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Don't readme. + +Why u still reading? \ No newline at end of file diff --git a/RandoSettings.cs b/RandoSettings.cs new file mode 100644 index 0000000..e69de29 diff --git a/RawRandoSettings.cs b/RawRandoSettings.cs new file mode 100644 index 0000000..7def456 --- /dev/null +++ b/RawRandoSettings.cs @@ -0,0 +1,11 @@ +namespace CharmMod +{ + // Used as the type of the GlobalSettings for the mod so that it will work without MenuChanger installed + // (the MenuChanger attribute on RandoSettings will prevent (de)serialization from working even though it's + // not actually used for anything) + public class RawRandoSettings + { + public bool AddCharms = true; + public int IncreaseMaxCharmCostBy = 7; + } +} \ No newline at end of file diff --git a/SaveSettings.cs b/SaveSettings.cs new file mode 100644 index 0000000..d1c3cc1 --- /dev/null +++ b/SaveSettings.cs @@ -0,0 +1,21 @@ +namespace CharmMod +{ + public class SaveSettings + { + public CharmSettings Quickfall = new(); + public CharmSettings Slowfall = new(); + public CharmSettings SturdyNail = new(); + public CharmSettings BetterCDash = new(); + public CharmSettings HuntersMark = new(); + public CharmSettings HKBlessing = new(); + public CharmSettings GlassCannon = new(); + public CharmSettings WealthyAmulet = new(); + public CharmSettings PowerfulDash = new(); + public CharmSettings TripleJump = new(); + + public bool[] gotCharms = new[] { true, true, true, true }; + public bool[] newCharms = new[] { false, false, false, false }; + public bool[] equippedCharms = new[] { false, false, false, false }; + public int[] charmCosts = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + } +} \ No newline at end of file