diff options
Diffstat (limited to 'AnodyneArchipelago')
-rw-r--r-- | AnodyneArchipelago/Patches/GameplayPatches.cs | 228 | ||||
-rw-r--r-- | AnodyneArchipelago/Patches/StatePatches.cs | 39 | ||||
-rw-r--r-- | AnodyneArchipelago/Plugin.cs | 258 |
3 files changed, 268 insertions, 257 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 | } | ||
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 @@ | |||
1 | using AnodyneArchipelago.Patches; | 1 | using AnodyneSharp.Entities; |
2 | using AnodyneSharp; | ||
3 | using AnodyneSharp.Entities; | ||
4 | using AnodyneSharp.Entities.Events; | ||
5 | using AnodyneSharp.Entities.Gadget; | ||
6 | using AnodyneSharp.Entities.Gadget.Treasures; | ||
7 | using AnodyneSharp.Entities.Interactive; | ||
8 | using AnodyneSharp.Registry; | ||
9 | using AnodyneSharp.States; | ||
10 | using AnodyneSharp.Utilities; | ||
11 | using BepInEx; | 2 | using BepInEx; |
12 | using BepInEx.NET.Common; | 3 | using BepInEx.NET.Common; |
13 | using HarmonyLib; | 4 | using HarmonyLib; |
14 | using HarmonyLib.Tools; | 5 | using HarmonyLib.Tools; |
15 | using Microsoft.Xna.Framework; | ||
16 | using System; | ||
17 | using System.Collections; | ||
18 | using System.Collections.Generic; | ||
19 | using System.Reflection; | 6 | using System.Reflection; |
20 | 7 | ||
21 | namespace AnodyneArchipelago | 8 | namespace 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 | } |