about summary refs log tree commit diff stats
path: root/AnodyneArchipelago
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2024-05-22 13:57:28 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2024-05-22 13:57:28 -0400
commitf6bf7b8576a6c2a7d89d463b4998c44324d6d370 (patch)
treead8a8aab9c659ade37bdf5cb6e686d7e2fc6efd6 /AnodyneArchipelago
parentf717a556a909b831cb6965bcd2f8e057053e5161 (diff)
downloadanodyne-archipelago-f6bf7b8576a6c2a7d89d463b4998c44324d6d370.tar.gz
anodyne-archipelago-f6bf7b8576a6c2a7d89d463b4998c44324d6d370.tar.bz2
anodyne-archipelago-f6bf7b8576a6c2a7d89d463b4998c44324d6d370.zip
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.
Diffstat (limited to 'AnodyneArchipelago')
-rw-r--r--AnodyneArchipelago/ArchipelagoManager.cs11
-rw-r--r--AnodyneArchipelago/ArchipelagoTreasure.cs22
-rw-r--r--AnodyneArchipelago/Locations.cs4
-rw-r--r--AnodyneArchipelago/Plugin.cs108
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 @@
1using AnodyneSharp.Entities.Gadget.Treasures; 1using AnodyneSharp.Entities;
2using AnodyneSharp.Entities.Gadget.Treasures;
3using AnodyneSharp.Registry;
2using Microsoft.Xna.Framework; 4using Microsoft.Xna.Framework;
3 5
4namespace AnodyneArchipelago 6namespace 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 @@
2using AnodyneSharp.Entities; 2using AnodyneSharp.Entities;
3using AnodyneSharp.Entities.Gadget; 3using AnodyneSharp.Entities.Gadget;
4using AnodyneSharp.Entities.Gadget.Treasures; 4using AnodyneSharp.Entities.Gadget.Treasures;
5using AnodyneSharp.Entities.Interactive;
6using AnodyneSharp.Registry;
7using AnodyneSharp.Utilities;
5using BepInEx; 8using BepInEx;
6using BepInEx.NET.Common; 9using BepInEx.NET.Common;
7using HarmonyLib; 10using HarmonyLib;
8using HarmonyLib.Tools; 11using HarmonyLib.Tools;
9using System; 12using System;
13using System.Collections;
14using System.Collections.Generic;
10using System.Reflection; 15using System.Reflection;
11 16
12namespace AnodyneArchipelago 17namespace 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}