diff --git a/BaboonAPI/BaboonAPI.fsproj b/BaboonAPI/BaboonAPI.fsproj
index 4830a45..4bf4293 100644
--- a/BaboonAPI/BaboonAPI.fsproj
+++ b/BaboonAPI/BaboonAPI.fsproj
@@ -69,7 +69,7 @@
-
+
diff --git a/BaboonAPI/Library.fs b/BaboonAPI/Library.fs
index e1e7a18..db8f06d 100644
--- a/BaboonAPI/Library.fs
+++ b/BaboonAPI/Library.fs
@@ -46,6 +46,7 @@ type BaboonPlugin() =
typeof
typeof
typeof
+ typeof
typeof
typeof
] |> List.iter harmony.PatchAll
diff --git a/BaboonAPI/api/TrackRegistry.fs b/BaboonAPI/api/TrackRegistry.fs
index 7d6585e..7c0c843 100644
--- a/BaboonAPI/api/TrackRegistry.fs
+++ b/BaboonAPI/api/TrackRegistry.fs
@@ -60,6 +60,23 @@ type public TromboneTrack =
/// Whether this track is visible in the track selector
abstract IsVisible: unit -> bool
+///
+/// LoadedTromboneTrack extension for pause/resume functionality
+///
+///
+/// Implementing this class allows you to react to the pause and resume
+///
+type public PauseAware =
+ /// Can this track be resumed after a pause?
+ /// If false, the curtains will close on pause.
+ abstract CanResume: bool
+
+ /// Called when this track is paused. Use this to pause backgrounds or other features.
+ abstract OnPause: unit -> unit
+
+ /// Called when this track is resumed (after the countdown).
+ abstract OnResume: unit -> unit
+
///
/// Event-based API for registering new tracks.
///
diff --git a/BaboonAPI/patch/BaseTracksLoaderPatch.fs b/BaboonAPI/patch/BaseTracksLoaderPatch.fs
index e94f1fb..17087ee 100644
--- a/BaboonAPI/patch/BaseTracksLoaderPatch.fs
+++ b/BaboonAPI/patch/BaseTracksLoaderPatch.fs
@@ -25,6 +25,13 @@ type internal BaseGameLoadedTrack(trackref: string, bundle: AssetBundle) =
()
member this.trackref = trackref
+
+ interface PauseAware with
+ member this.CanResume = true
+
+ member this.OnPause() = ()
+
+ member this.OnResume() = ()
type internal BaseGameTrack(data: string[]) =
interface TromboneTrack with
diff --git a/BaboonAPI/patch/GameControllerPatch.fs b/BaboonAPI/patch/GameControllerPatch.fs
index cd250d3..c7f4854 100644
--- a/BaboonAPI/patch/GameControllerPatch.fs
+++ b/BaboonAPI/patch/GameControllerPatch.fs
@@ -57,6 +57,12 @@ type private GameControllerExtension() =
// Start background task next frame
instance.StartCoroutine("loadAssetBundleResources") |> ignore
+ // Set up pause/resume functionality
+ instance.track_is_pausable <-
+ match l with
+ | :? PauseAware as pauseable -> pauseable.CanResume // `track_is_pausable` actually controls resuming
+ | _ -> false
+
// Usually this should be cleaned up by Unload, but let's just make sure...
match loadedTrack with
| Some prev ->
@@ -70,6 +76,18 @@ type private GameControllerExtension() =
static member LoadChart(trackref: string): SavedLevel =
(TrackAccessor.fetchTrack trackref).LoadChart()
+
+ static member PauseTrack() =
+ match loadedTrack with
+ | Some (:? PauseAware as pa) ->
+ pa.OnPause()
+ | _ -> ()
+
+ static member ResumeTrack() =
+ match loadedTrack with
+ | Some (:? PauseAware as pa) ->
+ pa.OnResume()
+ | _ -> ()
static member Unload() =
match loadedTrack with
@@ -150,3 +168,17 @@ type GameControllerPatch() =
___mySoundAssetBundle <- null
false
+
+[]
+type PausePatches() =
+ []
+ [, "showPausePanel")>]
+ static member PausePostfix(__instance: PauseCanvasController) =
+ GameControllerExtension.PauseTrack()
+ ()
+
+ []
+ [, "resumeFromPause")>]
+ static member ResumePostfix(__instance: PauseCanvasController) =
+ GameControllerExtension.ResumeTrack()
+ ()