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