public override void Load() { IL.Celeste.BounceBlock.ShakeOffPlayer += onJumpGraceTimerReset; IL.Celeste.Player.DreamDashEnd += modCoyoteTime; hookOrigUpdate = new ILHook(typeof(Player).GetMethod("orig_Update"), modCoyoteTime); }
public static void Load() { using (new DetourContext { Before = { "*" } }) { // these don't always call the orig methods, better apply them first. // fix general actor/platform behavior to make them comply with jumpthrus. On.Celeste.Actor.MoveVExact += onActorMoveVExact; On.Celeste.Platform.MoveVExactCollideSolids += onPlatformMoveVExactCollideSolids; } using (new DetourContext { After = { "*" } }) { // fix player specific behavior allowing them to go through upside-down jumpthrus. On.Celeste.Player.ctor += onPlayerConstructor; } using (new DetourContext()) { // block player if they try to climb past an upside-down jumpthru. IL.Celeste.Player.ClimbUpdate += patchPlayerClimbUpdate; // ignore upside-down jumpthrus in select places. playerOrigUpdateHook = new ILHook(typeof(Player).GetMethod("orig_Update"), filterOutJumpThrusFromCollideChecks); IL.Celeste.Player.DashUpdate += filterOutJumpThrusFromCollideChecks; IL.Celeste.Player.RedDashUpdate += filterOutJumpThrusFromCollideChecks; // listen for the player unducking, to knock the player down before they would go through upside down jumpthrus. On.Celeste.Player.Update += onPlayerUpdate; } }
public override void Load() { Everest.Events.MainMenu.OnCreateButtons += CreateMainMenuButtons; Everest.Events.Level.OnCreatePauseMenuButtons += CreatePauseMenuButtons; nluaAssemblyGetTypesHook = new ILHook(typeof(Lua).Assembly.GetType("NLua.Extensions.TypeExtensions").GetMethod("GetExtensionMethods"), patchNLuaAssemblyGetTypes); if (Everest.Flags.IsMobile) { // It shouldn't look that bad on mobile screens... Environment.SetEnvironmentVariable("FNA_OPENGL_BACKBUFFER_SCALE_NEAREST", "1"); } foreach (KeyValuePair <string, LogLevel> logLevel in Settings.LogLevels) { Logger.SetLogLevelFromYaml(logLevel.Key, logLevel.Value); } if (Directory.Exists("LogHistory")) { int historyToKeep = Math.Max(Settings.LogHistoryCountToKeep, 0); // just in case someone tries to set the value to -42 List <string> files = Directory.GetFiles("LogHistory", "log_*.txt").ToList(); files.Sort(new LogRotationHelper.OldestFirst()); int historyToDelete = files.Count - historyToKeep; foreach (string file in files.Take(historyToDelete)) { Logger.Log("core", $"log.txt history: keeping {historyToKeep} file(s) of history, deleting {file}"); File.Delete(file); } } }
public override void Unload() { Everest.Events.MainMenu.OnCreateButtons -= CreateMainMenuButtons; Everest.Events.Level.OnCreatePauseMenuButtons -= CreatePauseMenuButtons; nluaAssemblyGetTypesHook?.Dispose(); nluaAssemblyGetTypesHook = null; }
public static void activateHooksNoJungleHelper() { if (hooksActiveNoJungleHelper) { return; } hooksActiveNoJungleHelper = true; Logger.Log(LogLevel.Debug, "MaxHelpingHand/SidewaysJumpThru", "=== Activating non Jungle Helper sideways jumpthru hooks"); // implement the basic collision between actors/platforms and sideways jumpthrus. using (new DetourContext { Before = { "*" } }) { // these don't always call the orig methods, better apply them first. On.Celeste.Actor.MoveHExact += onActorMoveHExact; } using (new DetourContext { Before = { "*" } }) { // let's take over Spring Collab 2020, we can break it, this is not a collab map! // mod collide checks to include sideways jumpthrus, so that the player behaves with them like with walls. IL.Celeste.Player.ClimbCheck += modCollideChecks; // allow player to climb on them IL.Celeste.Player.ClimbBegin += modCollideChecks; // if not applied, the player will clip through jumpthrus if trying to climb on them IL.Celeste.Player.ClimbUpdate += modCollideChecks; // when climbing, jumpthrus are handled like walls IL.Celeste.Player.SlipCheck += modCollideChecks; // make climbing on jumpthrus not slippery IL.Celeste.Player.OnCollideH += modCollideChecks; // handle dashes against jumpthrus properly, without "shifting" down // have the push animation when Madeline runs against a jumpthru for example hookOnUpdateSprite = new ILHook(typeof(Player).GetMethod("orig_UpdateSprite", BindingFlags.NonPublic | BindingFlags.Instance), modCollideChecks); } }
internal static void Load() { IL.Celeste.Refill.Update += Refill_Update; IL.Celeste.Refill.Respawn += Refill_Respawn; hook_Refill_RefillRoutine = new ILHook(m_Refill_RefillRoutine.GetStateMachineTarget(), Refill_RefillRoutine); }
public override void Initialize() { Type T = typeof(HeroController).GetNestedTypes(BindingFlags.NonPublic | BindingFlags.Instance).First(t => t.Name == "<EnterScene>c__Iterator0"); MethodBase M = T.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.Public); fasterTransitionHook = new ILHook(M, RemoveTransitionWaits); }
public static void OnLoad() { origLoadLevelHook = new ILHook(typeof(Level).GetMethod("orig_LoadLevel"), ModOrigLoadLevel); loadCustomEntityHook = new ILHook(typeof(Level).GetMethod("LoadCustomEntity"), ModLoadCustomEntity); On.Monocle.Entity.Added += EntityOnAdded; CustomEntityId2Utils.OnLoad(); }
public override void Unload() { On.Celeste.Player.Jump -= OnPlayerJump; On.Celeste.Player.DashBegin -= OnPlayerDashBegin; On.Celeste.Player.Die -= OnPlayerDie; On.Celeste.PlayerSprite.ctor -= OnPlayerSprite_ctor; On.Celeste.Distort.Render -= OnDistortRender; On.Celeste.Player.Update -= OnPlayerUpdate; On.Celeste.Level.LoadLevel -= OnLevelLoadLevel; On.Celeste.Strawberry.OnCollect -= OnStrawberryOnCollect; On.Celeste.Key.OnPlayer -= OnKeyOnPlayer; On.Celeste.Key.RegisterUsed -= OnKeyRegisterUsed; On.Celeste.Player.Duck -= OnPlayerDuck; On.Celeste.Level.CompleteArea_bool_bool_bool -= OnLevelCompleteArea; On.Celeste.HeartGem.Collect -= OnHeartGemCollect; On.Celeste.Player.UseRefill -= OnPlayerUseRefill; On.Celeste.Spring.OnCollide -= OnSpringOnCollide; On.Celeste.Player.DreamDashBegin -= OnPlayerDreamDashBegin; On.Celeste.CutsceneEntity.Start -= OnCutsceneEntityStart; IL.Monocle.Engine.Update -= ILEngineUpdate; IL.Celeste.Bumper.OnPlayer -= ILBumperOnPlayer; ILPlayer_orig_Update.Dispose(); ILPlayer_orig_Update = null; ILPlayerStarFlyCoroutine.Dispose(); ILPlayerStarFlyCoroutine = null; }
public override void Load() { On.Celeste.Player.Jump += OnPlayerJump; On.Celeste.Player.DashBegin += OnPlayerDashBegin; On.Celeste.Player.Die += OnPlayerDie; On.Celeste.PlayerSprite.ctor += OnPlayerSprite_ctor; On.Celeste.Distort.Render += OnDistortRender; On.Celeste.Player.Update += OnPlayerUpdate; On.Celeste.Level.LoadLevel += OnLevelLoadLevel; On.Celeste.Strawberry.OnCollect += OnStrawberryOnCollect; On.Celeste.Key.OnPlayer += OnKeyOnPlayer; On.Celeste.Key.RegisterUsed += OnKeyRegisterUsed; On.Celeste.Player.Duck += OnPlayerDuck; On.Celeste.Level.CompleteArea_bool_bool_bool += OnLevelCompleteArea; On.Celeste.HeartGem.Collect += OnHeartGemCollect; On.Celeste.Player.UseRefill += OnPlayerUseRefill; On.Celeste.Player.StartStarFly += OnPlayerStartStarFly; On.Celeste.Spring.OnCollide += OnSpringOnCollide; On.Celeste.Player.DreamDashBegin += OnPlayerDreamDashBegin; On.Celeste.CutsceneEntity.Start += OnCutsceneEntityStart; IL.Monocle.Engine.Update += ILEngineUpdate; IL.Celeste.Bumper.OnPlayer += ILBumperOnPlayer; ILPlayer_orig_Update = new ILHook(typeof(Celeste.Player).GetMethod("orig_Update", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance), ILPlayerUpdate); ILPlayerStarFlyCoroutine = new ILHook(typeof(Celeste.Player).GetMethod("StarFlyCoroutine", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetStateMachineTarget(), ILPlayerStarFlyCoroutine_Actual); }
public override void Load() { IL.Celeste.Player.Jump += modJump; IL.Celeste.Player.SuperJump += modSuperJump; IL.Celeste.Player.SuperWallJump += modSuperWallJump; wallJumpHook = new ILHook(typeof(Player).GetMethod("orig_WallJump", BindingFlags.Instance | BindingFlags.NonPublic), modWallJump); }
public static void Load() { On.Celeste.SwapBlock.ctor_EntityData_Vector2 += onSwapBlockConstruct; IL.Celeste.SwapBlock.ctor_Vector2_float_float_Vector2_Themes += modSwapBlockTexturesInConstructor; hookOnPathRendererConstructor = new ILHook(pathRendererType.GetConstructor(new Type[] { typeof(SwapBlock) }), modSwapBlockTexturesInPathRenderer); }
internal static void ApplyFieldSets() { foreach (MethodInfo method in Reflection.GetMethodsWithAttribute <FieldSetAttribute>()) { if (method.ReturnType != typeof(void)) { throw new LibvaxyException($"The FieldSet method '{method.FullMemberName()}' must have a return type of void"); } if (method.GetCustomAttribute <ExtensionAttribute>() == null) { throw new LibvaxyException($"The FieldSet method '{method.FullMemberName()} must be an extension method targetting the type with the specified field"); } ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length != 2) { throw new LibvaxyException($"The FieldSet method '{method.FullMemberName()}' must have a second parameter whose type matches the specified field's type"); } Type targetType = parameters[0].ParameterType; FieldSetAttribute attribute = method.GetCustomAttribute <FieldSetAttribute>(); if (!Reflection.HasField(targetType, attribute.fieldName)) { throw new LibvaxyException($"The FieldSet method '{method.FullMemberName()}' targets field '{attribute.fieldName}' which does not exist in type '{targetType.FullName}'"); } FieldInfo targetFieldInfo = Reflection.GetFieldInfo(targetType, attribute.fieldName); ParameterInfo valueParameter = parameters[1]; if (valueParameter.ParameterType != targetFieldInfo.FieldType) { throw new LibvaxyException($"The setter parameter '{valueParameter.Name}' in the FieldSet method '{method.FullMemberName()}' does not have a type matching the target field '{attribute.fieldName}'"); } ILHook hook = new ILHook(method, il => { il.Body.Instructions.Clear(); ILCursor cursor = new ILCursor(il); cursor.Emit(OpCodes.Ldarg_1); if (targetFieldInfo.IsStatic) { cursor.Emit(OpCodes.Stsfld, targetFieldInfo); } else { cursor.Emit(OpCodes.Ldarg_0); cursor.Emit(OpCodes.Stfld, targetFieldInfo); } cursor.Emit(OpCodes.Ret); }); LibvaxyMod.DisposeOnUnload(hook); } }
internal static void Load() { hookOnHeartCount = new Hook(typeof(HeartGemDoor).GetMethod("get_HeartGems"), typeof(MiniHeartDoor).GetMethod(nameof(getCollectedHeartGems), BindingFlags.NonPublic | BindingFlags.Static)); hookOnDoorRoutine = HookHelper.HookCoroutine("Celeste.HeartGemDoor", "Routine", modDoorRoutine); IL.Celeste.HeartGemDoor.DrawInterior += modDoorColor; }
public static void Unload() { IL.Celeste.NorthernLights.ctor -= hookConstructor; IL.Celeste.NorthernLights.BeforeRender -= hookBeforeRender; strandILHook?.Dispose(); strandILHook = null; }
public static void Load() { string updateSpriteMethodToPatch = Everest.Loader.DependencyLoaded(new EverestModuleMetadata { Name = "Everest", Version = new Version(1, 1432) }) ? "orig_UpdateSprite" : "UpdateSprite"; // implement the basic collision between actors/platforms and sideways jumpthrus. using (new DetourContext { Before = { "*" } }) { // these don't always call the orig methods, better apply them first. On.Celeste.Actor.MoveHExact += onActorMoveHExact; On.Celeste.Platform.MoveHExactCollideSolids += onPlatformMoveHExactCollideSolids; } // block "climb hopping" on top of sideways jumpthrus, because this just looks weird. On.Celeste.Player.ClimbHopBlockedCheck += onPlayerClimbHopBlockedCheck; using (new DetourContext()) { // mod collide checks to include sideways jumpthrus, so that the player behaves with them like with walls. IL.Celeste.Player.WallJumpCheck += modCollideChecks; // allow player to walljump off them IL.Celeste.Player.ClimbCheck += modCollideChecks; // allow player to climb on them IL.Celeste.Player.ClimbBegin += modCollideChecks; // if not applied, the player will clip through jumpthrus if trying to climb on them IL.Celeste.Player.ClimbUpdate += modCollideChecks; // when climbing, jumpthrus are handled like walls IL.Celeste.Player.SlipCheck += modCollideChecks; // make climbing on jumpthrus not slippery IL.Celeste.Player.NormalUpdate += modCollideChecks; // get the wall slide effect IL.Celeste.Player.OnCollideH += modCollideChecks; // handle dashes against jumpthrus properly, without "shifting" down // have the push animation when Madeline runs against a jumpthru for example hookOnUpdateSprite = new ILHook(typeof(Player).GetMethod(updateSpriteMethodToPatch, BindingFlags.NonPublic | BindingFlags.Instance), modCollideChecks); } // one extra hook that kills the player momentum when hitting a jumpthru so that they don't get "stuck" on them. On.Celeste.Player.NormalUpdate += onPlayerNormalUpdate; }
public void Load() { // Optional: Various graphical simplifications to cut down on visual noise. On.Celeste.LightingRenderer.Render += LightingRenderer_Render; On.Monocle.Particle.Render += Particle_Render; IL.Celeste.BackdropRenderer.Render += BackdropRenderer_Render; On.Celeste.CrystalStaticSpinner.CreateSprites += CrystalStaticSpinner_CreateSprites; On.Celeste.DustStyles.Get_Session += DustStyles_Get_Session; On.Celeste.LavaRect.Wave += LavaRect_Wave; On.Celeste.DreamBlock.Lerp += DreamBlock_Lerp; On.Celeste.FloatingDebris.ctor_Vector2 += FloatingDebris_ctor; On.Celeste.MoonCreature.ctor_Vector2 += MoonCreature_ctor; On.Celeste.LightningRenderer.Render += LightningRenderer_Render; IL.Celeste.LightningRenderer.Render += LightningRenderer_RenderIL; On.Celeste.LightningRenderer.Bolt.Render += Bolt_Render; On.Celeste.Decal.Render += Decal_Render; On.Celeste.SummitCloud.Render += SummitCloudOnRender; // Hide screen wipe when beginning level if simple graphic is enabled On.Celeste.Level.Begin += Level_Begin; if (Type.GetType("FrostHelper.CustomSpinner, FrostTempleHelper") is Type customSpinnerType) { customSpinnerHook = new ILHook(customSpinnerType.GetConstructors()[0], modCustomSpinnerColor); } if (Type.GetType("Celeste.Mod.MaxHelpingHand.Entities.RainbowSpinnerColorController, MaxHelpingHand") is Type rainbowSpinnerType) { rainbowSpinnerColorControllerHook = new ILHook(rainbowSpinnerType.GetConstructors()[0], modRainbowSpinnerColor); } }
internal static void Load() { // timer pausing when returning to lobby On.Celeste.Level.LoadLevel += onLoadLevel; On.Celeste.Player.Update += onPlayerUpdate; // hiding collab maps from chapter select hookOnLevelSetSwitch = HookHelper.HookCoroutine(typeof(OuiHelper_ChapterSelect_LevelSet).FullName, "Enter", modLevelSetSwitch); IL.Celeste.Mod.UI.OuiMapSearch.ReloadItems += modMapSearch; IL.Celeste.Mod.UI.OuiMapList.ReloadItems += modMapListReloadItems; IL.Celeste.Mod.UI.OuiMapList.CreateMenu += modMapListCreateMenu; IL.Celeste.Mod.UI.OuiFileSelectSlotLevelSetPicker.changeStartingLevelSet += modFileSelectChangeStartingLevelSet; On.Celeste.SaveData.RegisterHeartGem += onRegisterHeartGem; On.Celeste.SaveData.RegisterPoemEntry += onRegisterPoemEntry; On.Celeste.SaveData.RegisterCompletion += onRegisterCompletion; On.Celeste.SaveData.AfterInitialize += onSaveDataAfterInitialize; On.Celeste.OuiChapterSelectIcon.AssistModeUnlockRoutine += onAssistUnlockRoutine; Everest.Events.Journal.OnEnter += onJournalEnter; On.Celeste.OuiFileSelectSlot.Show += onOuiFileSelectSlotShow; hookOnOuiFileSelectRenderDisplayName = new ILHook(typeof(OuiFileSelectSlot).GetMethod("orig_Render"), modSelectSlotLevelSetDisplayName); hookOnOuiFileSelectRenderStrawberryStamp = new ILHook(typeof(OuiFileSelectSlot).GetMethod("orig_Render"), modSelectSlotCollectedStrawberries); hookOnOuiJournalPoemLines = new ILHook(typeof(OuiJournalPoem).GetNestedType("PoemLine", BindingFlags.NonPublic).GetMethod("Render"), modJournalPoemHeartColors); hookOnOuiFileSelectSlotGolden = new ILHook(typeof(OuiFileSelectSlot).GetMethod("get_Golden", BindingFlags.NonPublic | BindingFlags.Instance), modSelectSlotCollectedStrawberries); hookOnOuiFileSelectSlotRender = new ILHook(typeof(OuiFileSelectSlot).GetMethod("orig_Render"), modOuiFileSelectSlotRender); }
public void ILThenOn() { hIL = new ILHook( typeof(OnIL).GetMethod("DoNothing"), il => { ILCursor c = new ILCursor(il); c.EmitDelegate <Action>(() => { hILRun = true; }); }, new ILHookConfig { ManualApply = false } ); h1 = new Hook( typeof(OnIL).GetMethod("DoNothing"), new Action <Action <OnIL>, OnIL>((orig, self) => { orig(self); h1Run = true; }), new HookConfig { ManualApply = false } ); h1Run = false; hILRun = false; DoNothing(); Assert.True(h1Run); Assert.True(hILRun); h1.Dispose(); hIL.Dispose(); }
public void HookStuff() { if (stuffIsHooked) { return; } Logger.Log("ExtendedVariantMode/ExtendedVariantsModule", $"Loading variant common methods..."); On.Celeste.AreaComplete.VersionNumberAndVariants += modVersionNumberAndVariants; Everest.Events.Level.OnExit += onLevelExit; On.Celeste.BadelineBoost.BoostRoutine += modBadelineBoostRoutine; On.Celeste.CS00_Ending.OnBegin += onPrologueEndingCutsceneBegin; Everest.Events.Level.OnCreatePauseMenuButtons += onCreatePauseMenuButtons; hookOnVersionNumberAndVariants = new ILHook(typeof(AreaComplete).GetMethod("orig_VersionNumberAndVariants"), ilModVersionNumberAndVariants); On.Celeste.Level.LoadLevel += onLoadLevel; On.Celeste.Level.EndPauseEffects += onUnpause; On.Celeste.Level.End += onLevelEnd; Logger.Log("ExtendedVariantMode/ExtendedVariantsModule", $"Loading variant randomizer..."); Randomizer.Load(); foreach (Variant variant in VariantHandlers.Keys) { Logger.Log("ExtendedVariantMode/ExtendedVariantsModule", $"Loading variant {variant}..."); VariantHandlers[variant].Load(); } LeakPreventionHack.Load(); Logger.Log(LogLevel.Info, "ExtendedVariantMode/ExtendedVariantsModule", "Done hooking stuff."); stuffIsHooked = true; }
public static void Load() { Assembly collabUtils = typeof(CollabUtils2.CollabModule).Assembly; hookIsHeartSide = new Hook( collabUtils.GetType("Celeste.Mod.CollabUtils2.LobbyHelper").GetMethod("IsHeartSide"), typeof(GrandmasterHeartSideHelper).GetMethod("modIsHeartSide", BindingFlags.NonPublic | BindingFlags.Static)); hookOverworldJournal = new ILHook( collabUtils.GetType("Celeste.Mod.CollabUtils2.UI.OuiJournalCollabProgressInOverworld").GetConstructor(new Type[] { typeof(OuiJournal) }), modOverworldJournal); hookLobbyJournal = new ILHook( collabUtils.GetType("Celeste.Mod.CollabUtils2.UI.OuiJournalCollabProgressInLobby").GetMethod("GeneratePages"), modLobbyJournal); IL.Celeste.Level.CompleteArea_bool_bool_bool += modLevelComplete; IL.Celeste.OuiChapterPanel.Render += renderOldGMHSCompletionStamp; // we are looking for a lambda in Celeste.Mod.CollabUtils2.LobbyHelper.modJournalPoemHeartColors... // except it is located in Celeste.Mod.CollabUtils2.LobbyHelper.<>c.<modJournalPoemHeartColors>b__{someRandomNumber}_0. // find it by bruteforcing it a bit. Type innerType = collabUtils.GetType("Celeste.Mod.CollabUtils2.LobbyHelper").GetNestedType("<>c", BindingFlags.NonPublic); for (int i = 0; i < 100; i++) { MethodInfo innerMethod = innerType.GetMethod($"<modJournalPoemHeartColors>b__{i}_0", BindingFlags.NonPublic | BindingFlags.Instance); if (innerMethod != null) { // found it! hookPoemColors = new ILHook(innerMethod, modifyGMHSeartColor); break; } } }
public override void Unload() { IL.Celeste.BounceBlock.ShakeOffPlayer -= onJumpGraceTimerReset; IL.Celeste.Player.DreamDashEnd -= modCoyoteTime; hookOrigUpdate?.Dispose(); hookOrigUpdate = null; }
private static void Load() { On.Monocle.Engine.Update += EngineOnUpdate; On.Monocle.Scene.AfterUpdate += SceneOnAfterUpdate; Everest.Events.Level.OnTransitionTo += LevelOnOnTransitionTo; On.Celeste.Level.Update += LevelOnUpdate; dashCoroutineIlHook = new ILHook(typeof(Player).GetMethodInfo("DashCoroutine").GetStateMachineTarget(), PlayerOnDashCoroutine); }
public override void Unload() { dashCoroutineHook?.Dispose(); redDashCoroutineHook?.Dispose(); dashCoroutineHook = null; redDashCoroutineHook = null; }
public static void Unload() { On.Celeste.SwapBlock.ctor_EntityData_Vector2 -= onSwapBlockConstruct; IL.Celeste.SwapBlock.ctor_Vector2_float_float_Vector2_Themes -= modSwapBlockTexturesInConstructor; hookOnPathRendererConstructor?.Dispose(); hookOnPathRendererConstructor = null; }
public override void Load() { // we cannot hook ExplodeLaunch because of https://github.com/EverestAPI/Everest/issues/66 // so we'll wrap each call of it instead. IL.Celeste.Bumper.OnPlayer += wrapExplodeLaunchCall; IL.Celeste.Puffer.Explode += wrapExplodeLaunchCall; IL.Celeste.TempleBigEyeball.OnPlayer += wrapExplodeLaunchCall; seekerRegenerateHook = new ILHook(typeof(Seeker).GetMethod("RegenerateCoroutine", BindingFlags.NonPublic | BindingFlags.Instance).GetStateMachineTarget(), wrapExplodeLaunchCall); }
public override void Load() { bool isUpdateSpritePatched = Everest.Loader.DependencyLoaded(new EverestModuleMetadata { Name = "Everest", Version = new Version(1, 1432) }); IL.Celeste.Player.NormalUpdate += modNormalUpdate; hookUpdateSprite = new ILHook(typeof(Player).GetMethod(isUpdateSpritePatched ? "orig_UpdateSprite" : "UpdateSprite", BindingFlags.NonPublic | BindingFlags.Instance), modUpdateSprite); }
public override void Load() { On.Celeste.Player.DashBegin += modDashBegin; MethodInfo dashCoroutine = typeof(Player).GetMethod("DashCoroutine", BindingFlags.NonPublic | BindingFlags.Instance).GetStateMachineTarget(); dashCoroutineHookForTimer = new ILHook(dashCoroutine, modDashLength); dashCoroutineHookForCounter = new ILHook(dashCoroutine, modDashTrailCounter); }
private static void Unload() { On.Monocle.Engine.Update -= EngineOnUpdate; On.Monocle.Scene.AfterUpdate -= SceneOnAfterUpdate; Everest.Events.Level.OnTransitionTo -= LevelOnOnTransitionTo; On.Celeste.Level.Update -= LevelOnUpdate; dashCoroutineIlHook?.Dispose(); dashCoroutineIlHook = null; }
public static void Load() { using (new DetourContext() { After = { "*" } }) { // be sure to be applied after Spring Collab 2020 because we don't want to break it playerOrigUpdateHook = new ILHook(typeof(Player).GetMethod("orig_Update"), modPlayerOrigUpdate); } }