diff options
| -rw-r--r-- | AnodyneArchipelago/ArchipelagoManager.cs | 11 | ||||
| -rw-r--r-- | AnodyneArchipelago/ArchipelagoTreasure.cs | 22 | ||||
| -rw-r--r-- | AnodyneArchipelago/Locations.cs | 4 | ||||
| -rw-r--r-- | AnodyneArchipelago/Plugin.cs | 108 |
4 files changed, 141 insertions, 4 deletions
| diff --git a/AnodyneArchipelago/ArchipelagoManager.cs b/AnodyneArchipelago/ArchipelagoManager.cs index 4ffa3af..4ceb68a 100644 --- a/AnodyneArchipelago/ArchipelagoManager.cs +++ b/AnodyneArchipelago/ArchipelagoManager.cs | |||
| @@ -131,7 +131,8 @@ namespace AnodyneArchipelago | |||
| 131 | 131 | ||
| 132 | string mapName = GetMapNameForDungeon(dungeonName); | 132 | string mapName = GetMapNameForDungeon(dungeonName); |
| 133 | GlobalState.inventory.AddMapKey(mapName, 1); | 133 | GlobalState.inventory.AddMapKey(mapName, 1); |
| 134 | } else if (itemName == "Green Key") | 134 | } |
| 135 | else if (itemName == "Green Key") | ||
| 135 | { | 136 | { |
| 136 | GlobalState.inventory.BigKeyStatus[0] = true; | 137 | GlobalState.inventory.BigKeyStatus[0] = true; |
| 137 | } | 138 | } |
| @@ -142,10 +143,16 @@ namespace AnodyneArchipelago | |||
| 142 | else if (itemName == "Red Key") | 143 | else if (itemName == "Red Key") |
| 143 | { | 144 | { |
| 144 | GlobalState.inventory.BigKeyStatus[1] = true; | 145 | GlobalState.inventory.BigKeyStatus[1] = true; |
| 145 | } else if (itemName == "Jump Shoes") | 146 | } |
| 147 | else if (itemName == "Jump Shoes") | ||
| 146 | { | 148 | { |
| 147 | GlobalState.inventory.CanJump = true; | 149 | GlobalState.inventory.CanJump = true; |
| 148 | } | 150 | } |
| 151 | else if (itemName == "Health Cicada") | ||
| 152 | { | ||
| 153 | GlobalState.MAX_HEALTH += 1; | ||
| 154 | GlobalState.CUR_HEALTH = GlobalState.MAX_HEALTH; | ||
| 155 | } | ||
| 149 | } | 156 | } |
| 150 | } | 157 | } |
| 151 | } | 158 | } |
| diff --git a/AnodyneArchipelago/ArchipelagoTreasure.cs b/AnodyneArchipelago/ArchipelagoTreasure.cs index 6d000e8..b3812f2 100644 --- a/AnodyneArchipelago/ArchipelagoTreasure.cs +++ b/AnodyneArchipelago/ArchipelagoTreasure.cs | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | using AnodyneSharp.Entities.Gadget.Treasures; | 1 | using AnodyneSharp.Entities; |
| 2 | using AnodyneSharp.Entities.Gadget.Treasures; | ||
| 3 | using AnodyneSharp.Registry; | ||
| 2 | using Microsoft.Xna.Framework; | 4 | using Microsoft.Xna.Framework; |
| 3 | 5 | ||
| 4 | namespace AnodyneArchipelago | 6 | namespace AnodyneArchipelago |
| @@ -14,7 +16,23 @@ namespace AnodyneArchipelago | |||
| 14 | 16 | ||
| 15 | public override void GetTreasure() | 17 | public override void GetTreasure() |
| 16 | { | 18 | { |
| 17 | base.GetTreasure(); | 19 | if (_location == "Street - Broom Chest") |
| 20 | { | ||
| 21 | BroomTreasure broomTreasure = new("broom-icon", this.Position, BroomType.Normal); | ||
| 22 | broomTreasure.GetTreasure(); | ||
| 23 | GlobalState.SpawnEntity(broomTreasure); | ||
| 24 | } | ||
| 25 | else if (_location == "Street - Key Chest") | ||
| 26 | { | ||
| 27 | KeyTreasure keyTreasure = new(this.Position); | ||
| 28 | keyTreasure.GetTreasure(); | ||
| 29 | GlobalState.SpawnEntity(keyTreasure); | ||
| 30 | } | ||
| 31 | else | ||
| 32 | { | ||
| 33 | base.GetTreasure(); | ||
| 34 | } | ||
| 35 | |||
| 18 | ArchipelagoManager.SendLocation(_location); | 36 | ArchipelagoManager.SendLocation(_location); |
| 19 | } | 37 | } |
| 20 | } | 38 | } |
| diff --git a/AnodyneArchipelago/Locations.cs b/AnodyneArchipelago/Locations.cs index 46e2471..a1a54b2 100644 --- a/AnodyneArchipelago/Locations.cs +++ b/AnodyneArchipelago/Locations.cs | |||
| @@ -8,10 +8,14 @@ namespace AnodyneArchipelago | |||
| 8 | { | 8 | { |
| 9 | public static Dictionary<Guid, string> LocationsByGuid = new() | 9 | public static Dictionary<Guid, string> LocationsByGuid = new() |
| 10 | { | 10 | { |
| 11 | {new Guid("1525ead8-4d92-a815-873a-4dc04037d973"), "Street - Broom Chest" }, | ||
| 12 | {new Guid("3307aa58-ccf1-fb0d-1450-5af0a0c458f7"), "Street - Key Chest" }, | ||
| 13 | {new Guid("1bcddffb-5f98-4787-3a81-d1ce8fdeca29"), "Overworld - Near Gate Chest" }, | ||
| 11 | {new Guid("40de36cf-9238-f8b0-7a57-c6c8ca465cc2"), "Temple of the Seeing One - Entrance Chest" }, | 14 | {new Guid("40de36cf-9238-f8b0-7a57-c6c8ca465cc2"), "Temple of the Seeing One - Entrance Chest" }, |
| 12 | {new Guid("621c284f-cbd0-74c3-f51b-2a9fdde8d4d7"), "Temple of the Seeing One - Rock-Surrounded Chest" }, | 15 | {new Guid("621c284f-cbd0-74c3-f51b-2a9fdde8d4d7"), "Temple of the Seeing One - Rock-Surrounded Chest" }, |
| 13 | {new Guid("401939a4-41ba-e07e-3ba2-dc22513dcc5c"), "Temple of the Seeing One - Dark Room Chest" }, | 16 | {new Guid("401939a4-41ba-e07e-3ba2-dc22513dcc5c"), "Temple of the Seeing One - Dark Room Chest" }, |
| 14 | {new Guid("88d0a7b8-eeab-c45f-324e-f1c7885c41ce"), "Temple of the Seeing One - Shieldy Room Chest" }, | 17 | {new Guid("88d0a7b8-eeab-c45f-324e-f1c7885c41ce"), "Temple of the Seeing One - Shieldy Room Chest" }, |
| 18 | {new Guid("c481ee20-662e-6b02-b010-676ab339fc2d"), "Temple of the Seeing One - Health Cicada" }, | ||
| 15 | {new Guid("0bce5346-48a2-47f9-89cb-3f59d9d0b7d2"), "Temple of the Seeing One - Boss Chest" }, | 19 | {new Guid("0bce5346-48a2-47f9-89cb-3f59d9d0b7d2"), "Temple of the Seeing One - Boss Chest" }, |
| 16 | {new Guid("d41f2750-e3c7-bbb4-d650-fafc190ebd32"), "Temple of the Seeing One - After Statue Left Chest" }, | 20 | {new Guid("d41f2750-e3c7-bbb4-d650-fafc190ebd32"), "Temple of the Seeing One - After Statue Left Chest" }, |
| 17 | {new Guid("3167924e-5d52-1cd6-d6f4-b8e0e328215b"), "Temple of the Seeing One - After Statue Right Chest" }, | 21 | {new Guid("3167924e-5d52-1cd6-d6f4-b8e0e328215b"), "Temple of the Seeing One - After Statue Right Chest" }, |
| 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 @@ | |||
| 2 | using AnodyneSharp.Entities; | 2 | using AnodyneSharp.Entities; |
| 3 | using AnodyneSharp.Entities.Gadget; | 3 | using AnodyneSharp.Entities.Gadget; |
| 4 | using AnodyneSharp.Entities.Gadget.Treasures; | 4 | using AnodyneSharp.Entities.Gadget.Treasures; |
| 5 | using AnodyneSharp.Entities.Interactive; | ||
| 6 | using AnodyneSharp.Registry; | ||
| 7 | using AnodyneSharp.Utilities; | ||
| 5 | using BepInEx; | 8 | using BepInEx; |
| 6 | using BepInEx.NET.Common; | 9 | using BepInEx.NET.Common; |
| 7 | using HarmonyLib; | 10 | using HarmonyLib; |
| 8 | using HarmonyLib.Tools; | 11 | using HarmonyLib.Tools; |
| 9 | using System; | 12 | using System; |
| 13 | using System.Collections; | ||
| 14 | using System.Collections.Generic; | ||
| 10 | using System.Reflection; | 15 | using System.Reflection; |
| 11 | 16 | ||
| 12 | namespace AnodyneArchipelago | 17 | namespace AnodyneArchipelago |
| @@ -85,4 +90,107 @@ namespace AnodyneArchipelago | |||
| 85 | return true; | 90 | return true; |
| 86 | } | 91 | } |
| 87 | } | 92 | } |
| 93 | |||
| 94 | [HarmonyPatch(typeof(Big_Key), nameof(Big_Key.PlayerInteraction))] | ||
| 95 | class BigKeyTouchPatch | ||
| 96 | { | ||
| 97 | // We basically just rewrite this method, because we need to get rid of the part that adds the key to the inventory. | ||
| 98 | static bool Prefix(Big_Key __instance, ref bool __result) | ||
| 99 | { | ||
| 100 | Type keyType = typeof(Big_Key); | ||
| 101 | FieldInfo presetField = keyType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 102 | EntityPreset preset = presetField.GetValue(__instance) as EntityPreset; | ||
| 103 | |||
| 104 | MethodInfo statesMethod = keyType.GetMethod("States", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 105 | |||
| 106 | preset.Alive = false; | ||
| 107 | __instance.Solid = false; | ||
| 108 | GlobalState.StartCutscene = (System.Collections.Generic.IEnumerator<AnodyneSharp.States.CutsceneState.CutsceneEvent>)statesMethod.Invoke(__instance, new object[] { }); | ||
| 109 | __result = true; | ||
| 110 | return false; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | [HarmonyPatch(typeof(Big_Key), "States")] | ||
| 115 | class BigKeyStatesPatch | ||
| 116 | { | ||
| 117 | static void Postfix(Big_Key __instance) | ||
| 118 | { | ||
| 119 | Type keyType = typeof(Big_Key); | ||
| 120 | FieldInfo presetField = keyType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 121 | EntityPreset preset = presetField.GetValue(__instance) as EntityPreset; | ||
| 122 | |||
| 123 | if (preset.Frame == 0) | ||
| 124 | { | ||
| 125 | ArchipelagoManager.SendLocation("Temple of the Seeing One - Green Key"); | ||
| 126 | } else if (preset.Frame == 1) | ||
| 127 | { | ||
| 128 | ArchipelagoManager.SendLocation("Red Grotto - Red Key"); | ||
| 129 | } else if (preset.Frame == 2) | ||
| 130 | { | ||
| 131 | ArchipelagoManager.SendLocation("Mountain Cavern - Blue Key"); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | [HarmonyPatch(typeof(HealthCicadaSentinel), nameof(HealthCicadaSentinel.Collided))] | ||
| 137 | class HealthCicadaInteractPatch | ||
| 138 | { | ||
| 139 | static void Prefix(TreasureChest __instance) | ||
| 140 | { | ||
| 141 | Type hcsType = typeof(HealthCicadaSentinel); | ||
| 142 | FieldInfo childField = hcsType.GetField("_child", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 143 | HealthCicada healthCicada = (HealthCicada)childField.GetValue(__instance); | ||
| 144 | |||
| 145 | Type cicadaType = typeof(HealthCicada); | ||
| 146 | FieldInfo presetField = cicadaType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 147 | EntityPreset preset = presetField.GetValue(healthCicada) as EntityPreset; | ||
| 148 | Plugin.Instance.Log.LogInfo($"Touched cicada: {preset.EntityID.ToString()}"); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | [HarmonyPatch(typeof(HealthCicada), nameof(HealthCicada.Update))] | ||
| 153 | class HealthCicadaUpdatePatch | ||
| 154 | { | ||
| 155 | static void Postfix(HealthCicada __instance) | ||
| 156 | { | ||
| 157 | Type cicadaType = typeof(HealthCicada); | ||
| 158 | FieldInfo chirpField = cicadaType.GetField("_chirp", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 159 | FieldInfo sentinelField = cicadaType.GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 160 | |||
| 161 | HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(__instance); | ||
| 162 | Type hcsType = typeof(HealthCicadaSentinel); | ||
| 163 | FieldInfo flyDistanceField = hcsType.GetField("_flyDistance", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 164 | float flyDistance = (float)flyDistanceField.GetValue(sentinel); | ||
| 165 | |||
| 166 | if (__instance.visible && !(bool)chirpField.GetValue(__instance) && flyDistance > 0) | ||
| 167 | { | ||
| 168 | flyDistanceField.SetValue(sentinel, 0f); | ||
| 169 | |||
| 170 | FieldInfo stateField = cicadaType.GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 171 | stateField.SetValue(__instance, StateLogic(__instance)); | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | static IEnumerator<string> StateLogic(HealthCicada healthCicada) | ||
| 176 | { | ||
| 177 | Type cicadaType = typeof(HealthCicada); | ||
| 178 | FieldInfo presetField = cicadaType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 179 | EntityPreset preset = presetField.GetValue(healthCicada) as EntityPreset; | ||
| 180 | |||
| 181 | while (!MathUtilities.MoveTo(ref healthCicada.opacity, 0.0f, 0.6f)) | ||
| 182 | yield return "FadingOut"; | ||
| 183 | preset.Alive = false; | ||
| 184 | |||
| 185 | FieldInfo sentinelField = cicadaType.GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance); | ||
| 186 | HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(healthCicada); | ||
| 187 | |||
| 188 | sentinel.exists = false; | ||
| 189 | |||
| 190 | if (Locations.LocationsByGuid.ContainsKey(preset.EntityID)) | ||
| 191 | { | ||
| 192 | ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 88 | } | 196 | } |
