11using Celeste ;
22using Celeste . Mod . Entities ;
3+ using Celeste . Mod . Helpers ;
34using Microsoft . Xna . Framework ;
5+ using Mono . Cecil . Cil ;
46using Monocle ;
7+ using MonoMod . Cil ;
8+ using System . Collections . Generic ;
9+ using System . Linq ;
510
611namespace 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