From f6bf7b8576a6c2a7d89d463b4998c44324d6d370 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 22 May 2024 13:57:28 -0400 Subject: More stuff! Big keys are now locations. Health cicadas work now, both as locations and items. The two checks in the Street now also give their vanilla items. --- AnodyneArchipelago/Plugin.cs | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) (limited to 'AnodyneArchipelago/Plugin.cs') diff --git a/AnodyneArchipelago/Plugin.cs b/AnodyneArchipelago/Plugin.cs index f49ba35..d40da7c 100644 --- a/AnodyneArchipelago/Plugin.cs +++ b/AnodyneArchipelago/Plugin.cs @@ -2,11 +2,16 @@ using AnodyneSharp.Entities; using AnodyneSharp.Entities.Gadget; using AnodyneSharp.Entities.Gadget.Treasures; +using AnodyneSharp.Entities.Interactive; +using AnodyneSharp.Registry; +using AnodyneSharp.Utilities; using BepInEx; using BepInEx.NET.Common; using HarmonyLib; using HarmonyLib.Tools; using System; +using System.Collections; +using System.Collections.Generic; using System.Reflection; namespace AnodyneArchipelago @@ -85,4 +90,107 @@ namespace AnodyneArchipelago return true; } } + + [HarmonyPatch(typeof(Big_Key), nameof(Big_Key.PlayerInteraction))] + class BigKeyTouchPatch + { + // We basically just rewrite this method, because we need to get rid of the part that adds the key to the inventory. + static bool Prefix(Big_Key __instance, ref bool __result) + { + Type keyType = typeof(Big_Key); + FieldInfo presetField = keyType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); + EntityPreset preset = presetField.GetValue(__instance) as EntityPreset; + + MethodInfo statesMethod = keyType.GetMethod("States", BindingFlags.NonPublic | BindingFlags.Instance); + + preset.Alive = false; + __instance.Solid = false; + GlobalState.StartCutscene = (System.Collections.Generic.IEnumerator)statesMethod.Invoke(__instance, new object[] { }); + __result = true; + return false; + } + } + + [HarmonyPatch(typeof(Big_Key), "States")] + class BigKeyStatesPatch + { + static void Postfix(Big_Key __instance) + { + Type keyType = typeof(Big_Key); + FieldInfo presetField = keyType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); + EntityPreset preset = presetField.GetValue(__instance) as EntityPreset; + + if (preset.Frame == 0) + { + ArchipelagoManager.SendLocation("Temple of the Seeing One - Green Key"); + } else if (preset.Frame == 1) + { + ArchipelagoManager.SendLocation("Red Grotto - Red Key"); + } else if (preset.Frame == 2) + { + ArchipelagoManager.SendLocation("Mountain Cavern - Blue Key"); + } + } + } + + [HarmonyPatch(typeof(HealthCicadaSentinel), nameof(HealthCicadaSentinel.Collided))] + class HealthCicadaInteractPatch + { + static void Prefix(TreasureChest __instance) + { + Type hcsType = typeof(HealthCicadaSentinel); + FieldInfo childField = hcsType.GetField("_child", BindingFlags.NonPublic | BindingFlags.Instance); + HealthCicada healthCicada = (HealthCicada)childField.GetValue(__instance); + + Type cicadaType = typeof(HealthCicada); + FieldInfo presetField = cicadaType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); + EntityPreset preset = presetField.GetValue(healthCicada) as EntityPreset; + Plugin.Instance.Log.LogInfo($"Touched cicada: {preset.EntityID.ToString()}"); + } + } + + [HarmonyPatch(typeof(HealthCicada), nameof(HealthCicada.Update))] + class HealthCicadaUpdatePatch + { + static void Postfix(HealthCicada __instance) + { + Type cicadaType = typeof(HealthCicada); + FieldInfo chirpField = cicadaType.GetField("_chirp", BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo sentinelField = cicadaType.GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance); + + HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(__instance); + Type hcsType = typeof(HealthCicadaSentinel); + FieldInfo flyDistanceField = hcsType.GetField("_flyDistance", BindingFlags.NonPublic | BindingFlags.Instance); + float flyDistance = (float)flyDistanceField.GetValue(sentinel); + + if (__instance.visible && !(bool)chirpField.GetValue(__instance) && flyDistance > 0) + { + flyDistanceField.SetValue(sentinel, 0f); + + FieldInfo stateField = cicadaType.GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance); + stateField.SetValue(__instance, StateLogic(__instance)); + } + } + + static IEnumerator StateLogic(HealthCicada healthCicada) + { + Type cicadaType = typeof(HealthCicada); + FieldInfo presetField = cicadaType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); + EntityPreset preset = presetField.GetValue(healthCicada) as EntityPreset; + + while (!MathUtilities.MoveTo(ref healthCicada.opacity, 0.0f, 0.6f)) + yield return "FadingOut"; + preset.Alive = false; + + FieldInfo sentinelField = cicadaType.GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance); + HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(healthCicada); + + sentinel.exists = false; + + if (Locations.LocationsByGuid.ContainsKey(preset.EntityID)) + { + ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]); + } + } + } } -- cgit 1.4.1