Skip to content

Commit ababeae

Browse files
authored
Merge pull request #99 from aonkeeper4/temple-gate-all-switches-fix
fix temple gate all switches not working sometimes due to modded switches not calling `base.Awake`
2 parents 83009fb + e30e63a commit ababeae

1 file changed

Lines changed: 47 additions & 29 deletions

File tree

Code/FLCC/TempleGateAllSwitches.cs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
using Celeste;
22
using Celeste.Mod.Entities;
3+
using Celeste.Mod.Helpers;
34
using Microsoft.Xna.Framework;
5+
using Mono.Cecil.Cil;
46
using Monocle;
7+
using MonoMod.Cil;
8+
using System.Collections.Generic;
9+
using System.Linq;
510

611
namespace vitmod {
712
[Tracked()]
@@ -11,39 +16,52 @@ public TempleGateAllSwitches(EntityData data, Vector2 offset) : base(data.Positi
1116
ClaimedByASwitch = true;
1217
}
1318

14-
public static void Load() {
15-
On.Celeste.DashSwitch.Awake += DashSwitch_Awake;
19+
private static void HookOnDashCollide(DashSwitch dashSwitch) {
20+
DashCollision orig_OnDashCollide = dashSwitch.OnDashCollide;
21+
22+
dashSwitch.OnDashCollide = (player, direction) => {
23+
DashCollisionResults result = orig_OnDashCollide(player, direction);
24+
if (!dashSwitch.pressed || dashSwitch.Scene.Entities.Any(entity => entity is DashSwitch { pressed: false }))
25+
return result;
26+
27+
foreach (TempleGateAllSwitches gate in dashSwitch.Scene.Tracker.GetEntities<TempleGateAllSwitches>().Cast<TempleGateAllSwitches>())
28+
gate.Open();
29+
30+
return result;
31+
};
1632
}
33+
34+
#region Hooks
1735

18-
public static void Unload() {
19-
On.Celeste.DashSwitch.Awake -= DashSwitch_Awake;
36+
internal static void Load() {
37+
IL.Monocle.EntityList.UpdateLists += EntityList_UpdateLists;
2038
}
2139

22-
private static void DashSwitch_Awake(On.Celeste.DashSwitch.orig_Awake orig, DashSwitch self, Scene scene) {
23-
orig(self, scene);
24-
DashCollision orig_OnDashCollide = self.OnDashCollide;
25-
self.OnDashCollide = (Player player, Vector2 direction) => {
26-
DashCollisionResults result = orig_OnDashCollide(player, direction);
27-
bool finalswitch = true;
28-
if (self.pressed) {
29-
foreach (Solid solid in self.SceneAs<Level>().Tracker.GetEntities<Solid>()) {
30-
if (solid is DashSwitch dashSwitch) {
31-
if (!dashSwitch.pressed) {
32-
finalswitch = false;
33-
break;
34-
}
35-
}
36-
}
37-
} else {
38-
finalswitch = false;
39-
}
40-
if (finalswitch) {
41-
foreach (TempleGateAllSwitches gate in self.SceneAs<Level>().Tracker.GetEntities<TempleGateAllSwitches>()) {
42-
gate.Open();
43-
}
44-
}
45-
return result;
46-
};
40+
internal static void Unload() {
41+
IL.Monocle.EntityList.UpdateLists -= EntityList_UpdateLists;
42+
}
43+
44+
private static void EntityList_UpdateLists(ILContext il) {
45+
ILCursor cursor = new(il);
46+
47+
if (!cursor.TryGotoNextBestFit(MoveType.After,
48+
instr => instr.MatchLdloc(5),
49+
instr => instr.MatchLdarg0(),
50+
instr => instr.MatchCallvirt<EntityList>("get_Scene"),
51+
instr => instr.MatchCallvirt<Entity>("Awake")))
52+
return;
53+
54+
cursor.EmitLdloc(5);
55+
cursor.EmitDelegate(ProcessDashSwitch);
56+
57+
return;
58+
59+
static void ProcessDashSwitch(Entity entity) {
60+
if (entity is DashSwitch dashSwitch)
61+
HookOnDashCollide(dashSwitch);
62+
}
4763
}
64+
65+
#endregion
4866
}
4967
}

0 commit comments

Comments
 (0)