about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--AnodyneArchipelago/Locations.cs8
-rw-r--r--AnodyneArchipelago/Patches/PatchHelper.cs15
-rw-r--r--AnodyneArchipelago/Plugin.cs68
3 files changed, 59 insertions, 32 deletions
diff --git a/AnodyneArchipelago/Locations.cs b/AnodyneArchipelago/Locations.cs index 56701a5..dba2379 100644 --- a/AnodyneArchipelago/Locations.cs +++ b/AnodyneArchipelago/Locations.cs
@@ -72,15 +72,15 @@ namespace AnodyneArchipelago
72 {new Guid("5ffe5efb-6e92-da36-302a-7b75d3e72085"), "Red Grotto - Widen Upgrade Chest" }, 72 {new Guid("5ffe5efb-6e92-da36-302a-7b75d3e72085"), "Red Grotto - Widen Upgrade Chest" },
73 {new Guid("ae87f1d5-57e0-1749-7e1e-1d0bcc1bcab4"), "Red Grotto - Middle Cave Left Chest" }, 73 {new Guid("ae87f1d5-57e0-1749-7e1e-1d0bcc1bcab4"), "Red Grotto - Middle Cave Left Chest" },
74 {new Guid("72bad10e-598f-f238-0103-60e1b36f6240"), "Red Grotto - Middle Cave Right Chest" }, 74 {new Guid("72bad10e-598f-f238-0103-60e1b36f6240"), "Red Grotto - Middle Cave Right Chest" },
75 // Middle Left Tentacle 75 {new Guid("09241266-9657-6152-bb37-5ff0a7fddcf9"), "Red Grotto - Middle Cave Left Tentacle" },
76 // Middle Right Tentacle 76 {new Guid("95d6cf28-66df-54a5-0aec-6b54f56a2edc"), "Red Grotto - Middle Cave Right Tentacle" },
77 {new Guid("ed7d4d0f-c29d-d5aa-289a-b6c6ab8a041e"), "Red Grotto - Middle Cave Middle Chest" }, 77 {new Guid("ed7d4d0f-c29d-d5aa-289a-b6c6ab8a041e"), "Red Grotto - Middle Cave Middle Chest" },
78 {new Guid("4a9dc50d-8739-9ad8-2cb1-82ece29d3b6f"), "Red Grotto - Left Cave Rapids Chest" }, 78 {new Guid("4a9dc50d-8739-9ad8-2cb1-82ece29d3b6f"), "Red Grotto - Left Cave Rapids Chest" },
79 {new Guid("cda1ff45-0f88-4855-b0ec-a9b42376c33f"), "Red Grotto - Left Cave Sticky Chest" }, 79 {new Guid("cda1ff45-0f88-4855-b0ec-a9b42376c33f"), "Red Grotto - Left Cave Sticky Chest" },
80 // Left Tentacle 80 {new Guid("a0b1ccc8-849a-b61d-7742-bfaf11013b2a"), "Red Grotto - Left Cave Tentacle" },
81 {new Guid("83286bfb-ffda-237e-ba57-ca2e532e1dc7"), "Red Grotto - Right Cave Four Shooter Chest" }, 81 {new Guid("83286bfb-ffda-237e-ba57-ca2e532e1dc7"), "Red Grotto - Right Cave Four Shooter Chest" },
82 {new Guid("a7672339-f3fb-c49e-33ce-42a49d7e4533"), "Red Grotto - Right Cave Slasher Chest" }, 82 {new Guid("a7672339-f3fb-c49e-33ce-42a49d7e4533"), "Red Grotto - Right Cave Slasher Chest" },
83 // Right Tentacle 83 {new Guid("ed3b58c5-9191-013c-6935-777766e39a65"), "Red Grotto - Right Cave Tentacle" },
84 {new Guid("0504f29a-042a-bbc7-9fd4-5559e8ec64d0"), "Red Grotto - Top Cave Slasher Chest" }, 84 {new Guid("0504f29a-042a-bbc7-9fd4-5559e8ec64d0"), "Red Grotto - Top Cave Slasher Chest" },
85 {new Guid("082409e1-1d7e-3a22-9059-d5d9d0626fb1"), "Red Grotto - Health Cicada" }, 85 {new Guid("082409e1-1d7e-3a22-9059-d5d9d0626fb1"), "Red Grotto - Health Cicada" },
86 {new Guid("622180eb-bc49-c327-d598-af9714b5ecb3"), "Red Grotto - Boss Chest" }, 86 {new Guid("622180eb-bc49-c327-d598-af9714b5ecb3"), "Red Grotto - Boss Chest" },
diff --git a/AnodyneArchipelago/Patches/PatchHelper.cs b/AnodyneArchipelago/Patches/PatchHelper.cs new file mode 100644 index 0000000..6b6d532 --- /dev/null +++ b/AnodyneArchipelago/Patches/PatchHelper.cs
@@ -0,0 +1,15 @@
1using AnodyneSharp.Entities;
2using System;
3using System.Reflection;
4
5namespace AnodyneArchipelago.Patches
6{
7 internal class PatchHelper
8 {
9 public static EntityPreset GetEntityPreset(Type type, object instance)
10 {
11 FieldInfo presetField = type.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance);
12 return presetField.GetValue(instance) as EntityPreset;
13 }
14 }
15}
diff --git a/AnodyneArchipelago/Plugin.cs b/AnodyneArchipelago/Plugin.cs index 0bc372b..0fb7b60 100644 --- a/AnodyneArchipelago/Plugin.cs +++ b/AnodyneArchipelago/Plugin.cs
@@ -1,4 +1,5 @@
1using AnodyneSharp; 1using AnodyneArchipelago.Patches;
2using AnodyneSharp;
2using AnodyneSharp.Entities; 3using AnodyneSharp.Entities;
3using AnodyneSharp.Entities.Events; 4using AnodyneSharp.Entities.Events;
4using AnodyneSharp.Entities.Gadget; 5using AnodyneSharp.Entities.Gadget;
@@ -69,10 +70,8 @@ namespace AnodyneArchipelago
69 { 70 {
70 static void Prefix(TreasureChest __instance) 71 static void Prefix(TreasureChest __instance)
71 { 72 {
72 Type chestType = typeof(TreasureChest); 73 string entityId = PatchHelper.GetEntityPreset(typeof(TreasureChest), __instance).EntityID.ToString();
73 FieldInfo presetField = chestType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); 74 Plugin.Instance.Log.LogInfo($"Touched chest: {entityId}");
74 EntityPreset preset = presetField.GetValue(__instance) as EntityPreset;
75 Plugin.Instance.Log.LogInfo($"Touched chest: {preset.EntityID.ToString()}");
76 } 75 }
77 } 76 }
78 77
@@ -81,15 +80,12 @@ namespace AnodyneArchipelago
81 { 80 {
82 static bool Prefix(TreasureChest __instance) 81 static bool Prefix(TreasureChest __instance)
83 { 82 {
84 Type chestType = typeof(TreasureChest); 83 Guid entityId = PatchHelper.GetEntityPreset(typeof(TreasureChest), __instance).EntityID;
85 FieldInfo presetField = chestType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance); 84 if (Locations.LocationsByGuid.ContainsKey(entityId))
86 EntityPreset preset = presetField.GetValue(__instance) as EntityPreset;
87
88 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID))
89 { 85 {
90 BaseTreasure treasure = new ArchipelagoTreasure(Locations.LocationsByGuid[preset.EntityID], __instance.Position); 86 BaseTreasure treasure = new ArchipelagoTreasure(Locations.LocationsByGuid[entityId], __instance.Position);
91 87
92 FieldInfo treasureField = chestType.GetField("_treasure", BindingFlags.NonPublic | BindingFlags.Instance); 88 FieldInfo treasureField = typeof(TreasureChest).GetField("_treasure", BindingFlags.NonPublic | BindingFlags.Instance);
93 treasureField.SetValue(__instance, treasure); 89 treasureField.SetValue(__instance, treasure);
94 90
95 return false; 91 return false;
@@ -105,15 +101,12 @@ namespace AnodyneArchipelago
105 // We basically just rewrite this method, because we need to get rid of the part that adds the key to the inventory. 101 // We basically just rewrite this method, because we need to get rid of the part that adds the key to the inventory.
106 static bool Prefix(Big_Key __instance, ref bool __result) 102 static bool Prefix(Big_Key __instance, ref bool __result)
107 { 103 {
108 Type keyType = typeof(Big_Key); 104 MethodInfo statesMethod = typeof(Big_Key).GetMethod("States", BindingFlags.NonPublic | BindingFlags.Instance);
109 FieldInfo presetField = keyType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance);
110 EntityPreset preset = presetField.GetValue(__instance) as EntityPreset;
111
112 MethodInfo statesMethod = keyType.GetMethod("States", BindingFlags.NonPublic | BindingFlags.Instance);
113 105
106 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(Big_Key), __instance);
114 preset.Alive = false; 107 preset.Alive = false;
115 __instance.Solid = false; 108 __instance.Solid = false;
116 GlobalState.StartCutscene = (System.Collections.Generic.IEnumerator<AnodyneSharp.States.CutsceneState.CutsceneEvent>)statesMethod.Invoke(__instance, new object[] { }); 109 GlobalState.StartCutscene = (IEnumerator<AnodyneSharp.States.CutsceneState.CutsceneEvent>)statesMethod.Invoke(__instance, new object[] { });
117 __result = true; 110 __result = true;
118 return false; 111 return false;
119 } 112 }
@@ -124,9 +117,7 @@ namespace AnodyneArchipelago
124 { 117 {
125 static void Postfix(Big_Key __instance) 118 static void Postfix(Big_Key __instance)
126 { 119 {
127 Type keyType = typeof(Big_Key); 120 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(Big_Key), __instance);
128 FieldInfo presetField = keyType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance);
129 EntityPreset preset = presetField.GetValue(__instance) as EntityPreset;
130 121
131 if (preset.Frame == 0) 122 if (preset.Frame == 0)
132 { 123 {
@@ -152,9 +143,7 @@ namespace AnodyneArchipelago
152 FieldInfo childField = hcsType.GetField("_child", BindingFlags.NonPublic | BindingFlags.Instance); 143 FieldInfo childField = hcsType.GetField("_child", BindingFlags.NonPublic | BindingFlags.Instance);
153 HealthCicada healthCicada = (HealthCicada)childField.GetValue(__instance); 144 HealthCicada healthCicada = (HealthCicada)childField.GetValue(__instance);
154 145
155 Type cicadaType = typeof(HealthCicada); 146 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(HealthCicada), healthCicada);
156 FieldInfo presetField = cicadaType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance);
157 EntityPreset preset = presetField.GetValue(healthCicada) as EntityPreset;
158 Plugin.Instance.Log.LogInfo($"Touched cicada: {preset.EntityID.ToString()}"); 147 Plugin.Instance.Log.LogInfo($"Touched cicada: {preset.EntityID.ToString()}");
159 } 148 }
160 } 149 }
@@ -184,15 +173,13 @@ namespace AnodyneArchipelago
184 173
185 static IEnumerator<string> StateLogic(HealthCicada healthCicada) 174 static IEnumerator<string> StateLogic(HealthCicada healthCicada)
186 { 175 {
187 Type cicadaType = typeof(HealthCicada); 176 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(HealthCicada), healthCicada);
188 FieldInfo presetField = cicadaType.GetField("_preset", BindingFlags.NonPublic | BindingFlags.Instance);
189 EntityPreset preset = presetField.GetValue(healthCicada) as EntityPreset;
190 177
191 while (!MathUtilities.MoveTo(ref healthCicada.opacity, 0.0f, 0.6f)) 178 while (!MathUtilities.MoveTo(ref healthCicada.opacity, 0.0f, 0.6f))
192 yield return "FadingOut"; 179 yield return "FadingOut";
193 preset.Alive = false; 180 preset.Alive = false;
194 181
195 FieldInfo sentinelField = cicadaType.GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance); 182 FieldInfo sentinelField = typeof(HealthCicada).GetField("_sentinel", BindingFlags.NonPublic | BindingFlags.Instance);
196 HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(healthCicada); 183 HealthCicadaSentinel sentinel = (HealthCicadaSentinel)sentinelField.GetValue(healthCicada);
197 184
198 sentinel.exists = false; 185 sentinel.exists = false;
@@ -261,4 +248,29 @@ namespace AnodyneArchipelago
261 } 248 }
262 } 249 }
263 } 250 }
251
252 [HarmonyPatch]
253 class BreakChainPatch
254 {
255 static MethodInfo TargetMethod()
256 {
257 return typeof(Red_Pillar).GetNestedType("Chain", BindingFlags.NonPublic).GetMethod("Collided");
258 }
259
260 static void Postfix(object __instance)
261 {
262 Type chainType = typeof(Red_Pillar).GetNestedType("Chain", BindingFlags.NonPublic);
263 FieldInfo parentField = chainType.GetField("_parent", BindingFlags.NonPublic | BindingFlags.Instance);
264
265 Red_Pillar redPillar = (Red_Pillar)parentField.GetValue(__instance);
266 EntityPreset preset = PatchHelper.GetEntityPreset(typeof(Red_Pillar), redPillar);
267
268 Plugin.Instance.Log.LogInfo($"Broke red chain: {preset.EntityID.ToString()}");
269
270 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID))
271 {
272 ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]);
273 }
274 }
275 }
264} 276}