Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 47 additions & 29 deletions Code/FLCC/TempleGateAllSwitches.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using Celeste;
using Celeste.Mod.Entities;
using Celeste.Mod.Helpers;
using Microsoft.Xna.Framework;
using Mono.Cecil.Cil;
using Monocle;
using MonoMod.Cil;
using System.Collections.Generic;
using System.Linq;

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

public static void Load() {
On.Celeste.DashSwitch.Awake += DashSwitch_Awake;
private static void HookOnDashCollide(DashSwitch dashSwitch) {
DashCollision orig_OnDashCollide = dashSwitch.OnDashCollide;

dashSwitch.OnDashCollide = (player, direction) => {
DashCollisionResults result = orig_OnDashCollide(player, direction);
if (!dashSwitch.pressed || dashSwitch.Scene.Entities.Any(entity => entity is DashSwitch { pressed: false }))
return result;

foreach (TempleGateAllSwitches gate in dashSwitch.Scene.Tracker.GetEntities<TempleGateAllSwitches>().Cast<TempleGateAllSwitches>())
gate.Open();

return result;
};
}

#region Hooks

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

private static void DashSwitch_Awake(On.Celeste.DashSwitch.orig_Awake orig, DashSwitch self, Scene scene) {
orig(self, scene);
DashCollision orig_OnDashCollide = self.OnDashCollide;
self.OnDashCollide = (Player player, Vector2 direction) => {
DashCollisionResults result = orig_OnDashCollide(player, direction);
bool finalswitch = true;
if (self.pressed) {
foreach (Solid solid in self.SceneAs<Level>().Tracker.GetEntities<Solid>()) {
if (solid is DashSwitch dashSwitch) {
if (!dashSwitch.pressed) {
finalswitch = false;
break;
}
}
}
} else {
finalswitch = false;
}
if (finalswitch) {
foreach (TempleGateAllSwitches gate in self.SceneAs<Level>().Tracker.GetEntities<TempleGateAllSwitches>()) {
gate.Open();
}
}
return result;
};
internal static void Unload() {
IL.Monocle.EntityList.UpdateLists -= EntityList_UpdateLists;
}

private static void EntityList_UpdateLists(ILContext il) {
ILCursor cursor = new(il);

if (!cursor.TryGotoNextBestFit(MoveType.After,
instr => instr.MatchLdloc(5),
instr => instr.MatchLdarg0(),
instr => instr.MatchCallvirt<EntityList>("get_Scene"),
instr => instr.MatchCallvirt<Entity>("Awake")))
return;

cursor.EmitLdloc(5);
cursor.EmitDelegate(ProcessDashSwitch);

return;

static void ProcessDashSwitch(Entity entity) {
if (entity is DashSwitch dashSwitch)
HookOnDashCollide(dashSwitch);
}
}

#endregion
}
}
Loading