about summary refs log tree commit diff stats
path: root/AnodyneArchipelago/Plugin.cs
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2024-05-23 09:21:25 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2024-05-23 09:21:25 -0400
commit5d33345b598e2107df3763f09af3a06a84d65a93 (patch)
tree305c833edfda0c2d12bd3ab4385dd995a848ca29 /AnodyneArchipelago/Plugin.cs
parent2cc9d3601164fa96c164a5d0484024b762cc32f1 (diff)
downloadanodyne-archipelago-5d33345b598e2107df3763f09af3a06a84d65a93.tar.gz
anodyne-archipelago-5d33345b598e2107df3763f09af3a06a84d65a93.tar.bz2
anodyne-archipelago-5d33345b598e2107df3763f09af3a06a84d65a93.zip
Organized patches
Diffstat (limited to 'AnodyneArchipelago/Plugin.cs')
-rw-r--r--AnodyneArchipelago/Plugin.cs258
1 files changed, 1 insertions, 257 deletions
diff --git a/AnodyneArchipelago/Plugin.cs b/AnodyneArchipelago/Plugin.cs index 26f1274..1f6e7ea 100644 --- a/AnodyneArchipelago/Plugin.cs +++ b/AnodyneArchipelago/Plugin.cs
@@ -1,21 +1,8 @@
1using AnodyneArchipelago.Patches; 1using AnodyneSharp.Entities;
2using AnodyneSharp;
3using AnodyneSharp.Entities;
4using AnodyneSharp.Entities.Events;
5using AnodyneSharp.Entities.Gadget;
6using AnodyneSharp.Entities.Gadget.Treasures;
7using AnodyneSharp.Entities.Interactive;
8using AnodyneSharp.Registry;
9using AnodyneSharp.States;
10using AnodyneSharp.Utilities;
11using BepInEx; 2using BepInEx;
12using BepInEx.NET.Common; 3using BepInEx.NET.Common;
13using HarmonyLib; 4using HarmonyLib;
14using HarmonyLib.Tools; 5using HarmonyLib.Tools;
15using Microsoft.Xna.Framework;
16using System;
17using System.Collections;
18using System.Collections.Generic;
19using System.Reflection; 6using System.Reflection;
20 7
21namespace AnodyneArchipelago 8namespace AnodyneArchipelago
@@ -40,247 +27,4 @@ namespace AnodyneArchipelago
40 Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly()); 27 Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly());
41 } 28 }
42 } 29 }
43
44 [HarmonyPatch(typeof(AnodyneGame), "Update")]
45 class GameUpdatePatch
46 {
47 static void Postfix()
48 {
49 ArchipelagoManager.Update();
50 }
51 }
52
53 [HarmonyPatch(typeof(PlayState), nameof(PlayState.Create))]
54 class PlayStateCreatePatch
55 {
56 static void Prefix(PlayState __instance)
57 {
58 // Get player for later access.
59 FieldInfo playerField = typeof(PlayState).GetField("_player", BindingFlags.NonPublic | BindingFlags.Instance);
60 Plugin.Player = (Player)playerField.GetValue(__instance);
61
62 // Handle Red Grotto stuff.
63 GlobalState.events.SetEvent("red_cave_l_ss", 999);
64 GlobalState.events.SetEvent("red_cave_n_ss", 999);
65 GlobalState.events.SetEvent("red_cave_r_ss", 999);
66
67 // Connect to archipelago.
68 Plugin.Instance.Log.LogInfo("Connecting to Archipelago!");
69
70 ArchipelagoManager.Connect("localhost:38281", "Anodyne", "");
71 }
72 }
73
74 [HarmonyPatch(typeof(TreasureChest), nameof(TreasureChest.PlayerInteraction))]
75 class ChestInteractPatch
76 {
77 static void Prefix(TreasureChest __instance)
78 {
79 string entityId = PatchHelper.GetEntityPreset(typeof(TreasureChest), __instance).EntityID.ToString();
80 Plugin.Instance.Log.LogInfo($"Touched chest: {entityId}");
81 }
82 }
83
84 [HarmonyPatch(typeof(TreasureChest), "SetTreasure")]
85 class ChestSetTreasurePatch
86 {
87 static bool Prefix(TreasureChest __instance)
88 {
89 Guid entityId = PatchHelper.GetEntityPreset(typeof(TreasureChest), __instance).EntityID;
90 if (Locations.LocationsByGuid.ContainsKey(entityId))
91 {
92 BaseTreasure treasure = new ArchipelagoTreasure(Locations.LocationsByGuid[entityId], __instance.Position);
93
94 FieldInfo treasureField = typeof(TreasureChest).GetField("_treasure", BindingFlags.NonPublic | BindingFlags.Instance);
95 treasureField.SetValue(__instance, treasure);
96
97 return false;
98 }
99
100 return true;
101 }
102 }
103
104 [HarmonyPatch(typeof(Big_Key), nameof(Big_Key.PlayerInteraction))]
105 class BigKeyTouchPatch
106 {
107 // We basically just rewrite this method, because we need to get rid of the part that adds the key to the inventory.
108 static bool Prefix(Big_Key __instance, ref bool __result)
109 {
110 MethodInfo statesMethod = typeof(Big_Key).GetMethod("States", BindingFlags.NonPublic | BindingFlags.Instance);
111
112 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(Big_Key), __instance);
113 preset.Alive = false;
114 __instance.Solid = false;
115 GlobalState.StartCutscene = (IEnumerator<AnodyneSharp.States.CutsceneState.CutsceneEvent>)statesMethod.Invoke(__instance, new object[] { });
116 __result = true;
117 return false;
118 }
119 }
120
121 [HarmonyPatch(typeof(Big_Key), "States")]
122 class BigKeyStatesPatch
123 {
124 static void Postfix(Big_Key __instance)
125 {
126 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(Big_Key), __instance);
127
128 if (preset.Frame == 0)
129 {
130 ArchipelagoManager.SendLocation("Temple of the Seeing One - Green Key");
131 }
132 else if (preset.Frame == 1)
133 {
134 ArchipelagoManager.SendLocation("Red Grotto - Red Key");
135 }
136 else if (preset.Frame == 2)
137 {
138 ArchipelagoManager.SendLocation("Mountain Cavern - Blue Key");
139 }
140 }
141 }
142
143 [HarmonyPatch(typeof(HealthCicadaSentinel), nameof(HealthCicadaSentinel.Collided))]
144 class HealthCicadaInteractPatch
145 {
146 static void Prefix(TreasureChest __instance)
147 {
148 Type hcsType = typeof(HealthCicadaSentinel);
149 FieldInfo childField = hcsType.GetField("_child", BindingFlags.NonPublic | BindingFlags.Instance);
150 HealthCicada healthCicada = (HealthCicada)childField.GetValue(__instance);
151
152 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(HealthCicada), healthCicada);
153 Plugin.Instance.Log.LogInfo($"Touched cicada: {preset.EntityID.ToString()}");
154 }
155 }
156
157 [HarmonyPatch(typeof(HealthCicada), nameof(HealthCicada.Update))]
158 class HealthCicadaUpdatePatch
159 {
160 static void Postfix(HealthCicada __instance)
161 {
162 Type cicadaType = typeof(HealthCicada);
163 FieldInfo chirpField = cicadaType.GetField("_chirp", BindingFlags.NonPublic | BindingFlags.Instance);
164 FieldInfo sentinelField = cicadaType.GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance);
165
166 HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(__instance);
167 Type hcsType = typeof(HealthCicadaSentinel);
168 FieldInfo flyDistanceField = hcsType.GetField("_flyDistance", BindingFlags.NonPublic | BindingFlags.Instance);
169 float flyDistance = (float)flyDistanceField.GetValue(sentinel);
170
171 if (__instance.visible && !(bool)chirpField.GetValue(__instance) && flyDistance > 0)
172 {
173 flyDistanceField.SetValue(sentinel, 0f);
174
175 FieldInfo stateField = cicadaType.GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance);
176 stateField.SetValue(__instance, StateLogic(__instance));
177 }
178 }
179
180 static IEnumerator<string> StateLogic(HealthCicada healthCicada)
181 {
182 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(HealthCicada), healthCicada);
183
184 while (!MathUtilities.MoveTo(ref healthCicada.opacity, 0.0f, 0.6f))
185 yield return "FadingOut";
186 preset.Alive = false;
187
188 FieldInfo sentinelField = typeof(HealthCicada).GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance);
189 HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(healthCicada);
190
191 sentinel.exists = false;
192
193 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID))
194 {
195 ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]);
196 }
197 }
198 }
199
200 [HarmonyPatch(typeof(EntityPreset), nameof(EntityPreset.Create))]
201 class EntityPresetCreatePatch
202 {
203 static void Postfix(EntityPreset __instance, Entity __result)
204 {
205 if (__instance.Type.FullName == "AnodyneSharp.Entities.Interactive.DungeonStatue")
206 {
207 __result.Position = __instance.Position + new Vector2(1f, 32f);
208
209 string eventName = "StatueMoved_";
210 Facing moveDir = Facing.RIGHT;
211 if (__instance.Frame == 0)
212 {
213 eventName += "Temple";
214 moveDir = Facing.UP;
215 }
216 else if (__instance.Frame == 1)
217 {
218 eventName += "Grotto";
219 }
220 else if (__instance.Frame == 2)
221 {
222 eventName += "Mountain";
223 }
224
225 if (GlobalState.events.GetEvent(eventName) > 0)
226 {
227 __result.Position += Entity.FacingDirection(moveDir) * 32f;
228 }
229 }
230 else if (__instance.Type.FullName.StartsWith("AnodyneSharp.Entities.Decorations.RedCave"))
231 {
232 string side = __instance.Type.FullName.Substring(41);
233 int requiredGrottos = 0;
234 if (side == "Left")
235 {
236 requiredGrottos = 1;
237 }
238 else if (side == "Right")
239 {
240 requiredGrottos = 2;
241 }
242 else if (side == "North")
243 {
244 requiredGrottos = 3;
245 }
246
247 if (GlobalState.events.GetEvent("ProgressiveRedGrotto") < requiredGrottos)
248 {
249 __result.exists = false;
250 GlobalState.SpawnEntity((Entity)new DoorToggle(__result.Position, __result.width, __result.height));
251 }
252 }
253 else if (__instance.Type.FullName == "AnodyneSharp.Entities.Interactive.Npc.MitraCliff")
254 {
255 // We want to get rid of this scene entirely.
256 __instance.Alive = false;
257 __result.exists = false;
258 }
259 }
260 }
261
262 [HarmonyPatch]
263 class BreakChainPatch
264 {
265 static MethodInfo TargetMethod()
266 {
267 return typeof(Red_Pillar).GetNestedType("Chain", BindingFlags.NonPublic).GetMethod("Collided");
268 }
269
270 static void Postfix(object __instance)
271 {
272 Type chainType = typeof(Red_Pillar).GetNestedType("Chain", BindingFlags.NonPublic);
273 FieldInfo parentField = chainType.GetField("_parent", BindingFlags.NonPublic | BindingFlags.Instance);
274
275 Red_Pillar redPillar = (Red_Pillar)parentField.GetValue(__instance);
276 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(Red_Pillar), redPillar);
277
278 Plugin.Instance.Log.LogInfo($"Broke red chain: {preset.EntityID.ToString()}");
279
280 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID))
281 {
282 ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]);
283 }
284 }
285 }
286} 30}