From 46d21da81f3ae12c7f22800514aebc539a4c45b6 Mon Sep 17 00:00:00 2001 From: Gregory Hess Date: Wed, 27 Aug 2025 11:02:12 -0700 Subject: [PATCH 1/3] Upgrade to dotnet 8 --- Code/vitmod.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/vitmod.csproj b/Code/vitmod.csproj index ad71ea1..761a6c3 100644 --- a/Code/vitmod.csproj +++ b/Code/vitmod.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 vitmod vitmod latest From 71ccc847267b6ed7657351f2919e1c21e68013ee Mon Sep 17 00:00:00 2001 From: Gregory Hess Date: Thu, 28 Aug 2025 13:36:08 -0700 Subject: [PATCH 2/3] Make timecrystals not loose time during unpause --- Code/VitModule.cs | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/Code/VitModule.cs b/Code/VitModule.cs index 70c7a65..1979649 100644 --- a/Code/VitModule.cs +++ b/Code/VitModule.cs @@ -334,7 +334,7 @@ private static void HookedKeyIceInit() private void Level_Update(On.Celeste.Level.orig_Update orig, Level self) { //timestop crystal - if (!self.Paused) + if (!(self.FrozenOrPaused || self.unpauseTimer>0)) { if (TimeCrystal.stopTimer > 0f) { @@ -376,11 +376,9 @@ private void Level_Update(On.Celeste.Level.orig_Update orig, Level self) } } } - } + - if (TimeCrystal.stopStage > 0) - { - if (!self.Paused) + if (TimeCrystal.stopStage > 0) { if (TimeCrystal.timeScaleToSet < 1) { @@ -390,34 +388,33 @@ private void Level_Update(On.Celeste.Level.orig_Update orig, Level self) { timeStopScaleTimer -= Engine.DeltaTime; } - } - float timestop_delta_mult = 1; - if (TimeCrystal.stopStage == 1) - { - timestop_delta_mult = Math.Max(TimeCrystal.timeScaleToSet, 1 - (timeStopScaleTimer / 0.5f)); - } - else if (TimeCrystal.stopStage == 2) - { - timestop_delta_mult = Math.Min(1, timeStopScaleTimer / 0.5f); - } + float timestop_delta_mult = 1; + if (TimeCrystal.stopStage == 1) + { + timestop_delta_mult = Math.Max(TimeCrystal.timeScaleToSet, 1 - (timeStopScaleTimer / 0.5f)); + } + else if (TimeCrystal.stopStage == 2) + { + timestop_delta_mult = Math.Min(1, timeStopScaleTimer / 0.5f); + } - if (timestop_delta_mult != 1) - { - useTimeStopDelta = true; - timeStopDelta = Engine.DeltaTime * timestop_delta_mult; - timeStopRawDelta = Engine.RawDeltaTime * timestop_delta_mult; + if (timestop_delta_mult != 1) + { + useTimeStopDelta = true; + timeStopDelta = Engine.DeltaTime * timestop_delta_mult; + timeStopRawDelta = Engine.RawDeltaTime * timestop_delta_mult; + } + else + { + useTimeStopDelta = false; + } } else { useTimeStopDelta = false; } } - else - { - useTimeStopDelta = false; - } - //no move trigger if (NoMoveTrigger.stopTimer > 0f && !self.Paused) { From 52d0ca736dad5834971d7f2a6b87ad3b57fd40df Mon Sep 17 00:00:00 2001 From: Gregory Hess Date: Thu, 28 Aug 2025 14:16:34 -0700 Subject: [PATCH 3/3] Make timecrystals handle the first frame of a pause correctly --- Code/TimeCrystal.cs | 4 ++++ Code/VitModule.cs | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Code/TimeCrystal.cs b/Code/TimeCrystal.cs index 4841b3e..ca44ab4 100644 --- a/Code/TimeCrystal.cs +++ b/Code/TimeCrystal.cs @@ -259,8 +259,12 @@ private static void LightningRenderer_Update(On.Celeste.LightningRenderer.orig_U public static float stopTimer; + public static float prevTimer; + public static int stopStage; + public static int prevStage; + private Sprite sprite; private Sprite flash; diff --git a/Code/VitModule.cs b/Code/VitModule.cs index 1979649..02de32e 100644 --- a/Code/VitModule.cs +++ b/Code/VitModule.cs @@ -333,9 +333,18 @@ private static void HookedKeyIceInit() private void Level_Update(On.Celeste.Level.orig_Update orig, Level self) { - //timestop crystal + //time crstal + if (self.Paused) { + //jank because the level becomes "paused" after this update runs, so it's easier to just revert any changes + //that might have happened on the next frame (and we are garunteed to have at least one frame with self.Paused=true) + TimeCrystal.stopStage = TimeCrystal.prevStage; + TimeCrystal.stopTimer = TimeCrystal.prevTimer; + } if (!(self.FrozenOrPaused || self.unpauseTimer>0)) { + //enable stupid first frame pause reversion + TimeCrystal.prevTimer = TimeCrystal.stopTimer; + TimeCrystal.prevStage = TimeCrystal.stopStage; if (TimeCrystal.stopTimer > 0f) { TimeCrystal.stopTimer -= Engine.DeltaTime;