Track the loaded cutscene filename and re-load it on restart
Adds CUTSCENE_SYSTEM.loadedFile, set by cutsceneSystemLoad and cleared by cutsceneSystemPrepare. cutsceneRestart now re-reads and re-parses that file via cutsceneSystemLoad instead of just rerunning whatever's still resident in loadedScene/loadedItems, so restarting a file-loaded cutscene always reflects its current on-disk contents - restart of a C-authored cutscene is unchanged. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -36,6 +36,7 @@ void cutsceneSystemDispose() {
|
||||
CUTSCENE_SYSTEM.textMiniLastCreated = CUTSCENE_TEXT_MINI_LAST_CREATED;
|
||||
CUTSCENE_SYSTEM.textCache[0] = '\0';
|
||||
CUTSCENE_SYSTEM.onComplete = NULL;
|
||||
CUTSCENE_SYSTEM.loadedFile[0] = '\0';
|
||||
|
||||
cutsceneLoadedSetDoc(NULL);
|
||||
}
|
||||
@@ -58,6 +59,7 @@ void cutsceneSystemPrepare(
|
||||
CUTSCENE_SYSTEM.textCache[0] = '\0';
|
||||
CUTSCENE_SYSTEM.currentItem = 0xFF;// Set to 0xFF so Next wraps to 0.
|
||||
CUTSCENE_SYSTEM.onComplete = NULL;
|
||||
CUTSCENE_SYSTEM.loadedFile[0] = '\0';
|
||||
}
|
||||
|
||||
void cutsceneSystemStartCutscene(cutscene_t *cutscene) {
|
||||
@@ -69,6 +71,12 @@ void cutsceneSystemStartCutsceneWith(
|
||||
entity_t *interact,
|
||||
entity_t *interacted
|
||||
) {
|
||||
assertNotNull(cutscene, "Cutscene cannot be NULL");
|
||||
assertTrue(
|
||||
cutscene->itemCount <= cutscene->itemsMax,
|
||||
"Cutscene itemCount exceeds itemsMax"
|
||||
);
|
||||
|
||||
cutsceneSystemPrepare(cutscene, interact, interacted);
|
||||
cutsceneSystemNext();
|
||||
}
|
||||
@@ -139,6 +147,7 @@ void cutsceneSystemLoad(const char_t *file) {
|
||||
|
||||
cutsceneLoadedSetDoc(doc);
|
||||
cutsceneSystemStartCutscene(&CUTSCENE_SYSTEM.loadedScene);
|
||||
stringCopy(CUTSCENE_SYSTEM.loadedFile, file, ASSET_FILE_NAME_MAX - 1);
|
||||
}
|
||||
|
||||
void cutsceneLoadedSetDoc(yyjson_doc *doc) {
|
||||
@@ -153,14 +162,30 @@ void cutsceneRestart(void) {
|
||||
|
||||
// A restart is the same logical run trying again (e.g. retrying a failed
|
||||
// save-device check), not a fresh unrelated start, so it should not
|
||||
// silently drop a completion callback the caller already armed.
|
||||
// silently drop a completion callback the caller already armed, or the
|
||||
// entities that triggered it - both cutsceneSystemStartCutsceneWith and
|
||||
// cutsceneSystemLoad (via cutsceneSystemPrepare) forget them.
|
||||
cutscenecallback_t onComplete = CUTSCENE_SYSTEM.onComplete;
|
||||
cutsceneSystemStartCutsceneWith(
|
||||
CUTSCENE_SYSTEM.scene,
|
||||
CUTSCENE_SYSTEM.entityInteract,
|
||||
CUTSCENE_SYSTEM.entityInteracted
|
||||
);
|
||||
entity_t *entityInteract = CUTSCENE_SYSTEM.entityInteract;
|
||||
entity_t *entityInteracted = CUTSCENE_SYSTEM.entityInteracted;
|
||||
|
||||
if(CUTSCENE_SYSTEM.loadedFile[0] != '\0') {
|
||||
// Came from a cutscene asset - re-read+re-parse it from scratch
|
||||
// rather than just rerunning whatever's still resident in
|
||||
// loadedScene/loadedItems, so a restart always reflects the file's
|
||||
// current contents.
|
||||
char_t file[ASSET_FILE_NAME_MAX];
|
||||
stringCopy(file, CUTSCENE_SYSTEM.loadedFile, ASSET_FILE_NAME_MAX - 1);
|
||||
cutsceneSystemLoad(file);
|
||||
} else {
|
||||
cutsceneSystemStartCutsceneWith(
|
||||
CUTSCENE_SYSTEM.scene, entityInteract, entityInteracted
|
||||
);
|
||||
}
|
||||
|
||||
CUTSCENE_SYSTEM.onComplete = onComplete;
|
||||
CUTSCENE_SYSTEM.entityInteract = entityInteract;
|
||||
CUTSCENE_SYSTEM.entityInteracted = entityInteracted;
|
||||
}
|
||||
|
||||
void cutsceneSystemSetOnComplete(cutscenecallback_t onComplete) {
|
||||
|
||||
@@ -52,6 +52,16 @@ typedef struct {
|
||||
|
||||
cutsceneitem_t loadedItems[CUTSCENE_LOADED_ITEMS_MAX];
|
||||
cutscene_t loadedScene;
|
||||
|
||||
// Filename last passed to cutsceneSystemLoad, e.g. "main_menu.jsonc" -
|
||||
// set right after it starts loadedScene running. Empty ("") for a
|
||||
// cutscene started directly via cutsceneSystemStartCutscene* instead
|
||||
// (a C-authored one, or loadedScene reused without going through
|
||||
// cutsceneSystemLoad again), and cleared by cutsceneSystemPrepare on
|
||||
// every fresh start so it never lingers from a previous file load. See
|
||||
// cutsceneRestart, which re-loads (rather than just rerunning) whatever
|
||||
// this names.
|
||||
char_t loadedFile[ASSET_FILE_NAME_MAX];
|
||||
} cutscenesystem_t;
|
||||
|
||||
extern cutscenesystem_t CUTSCENE_SYSTEM;
|
||||
@@ -153,7 +163,8 @@ void cutsceneSystemInsertCutscene(const cutscene_t *cutscene);
|
||||
* CUTSCENE_LOADED_ITEMS_MAX's doc comment for why), so it's always
|
||||
* re-read+re-parsed fresh, never assumed still resident from a previous
|
||||
* call. Opens the fatal error overlay (see uiFatalErrorOpen) instead of
|
||||
* starting anything if the asset fails to load.
|
||||
* starting anything if the asset fails to load. Records file into
|
||||
* CUTSCENE_SYSTEM.loadedFile once it starts running.
|
||||
*
|
||||
* @param file Cutscene file name (with .jsonc extension), relative to
|
||||
* assets/cutscenes/.
|
||||
@@ -174,8 +185,14 @@ void cutsceneLoadedSetDoc(yyjson_doc *doc);
|
||||
|
||||
/**
|
||||
* Restarts the currently running cutscene from its first item,
|
||||
* preserving whatever interact/interacted entities triggered it.
|
||||
* Asserts if no cutscene is running.
|
||||
* preserving whatever interact/interacted entities triggered it and
|
||||
* whatever completion callback was armed. If CUTSCENE_SYSTEM.loadedFile
|
||||
* is set (i.e. the running cutscene came from cutsceneSystemLoad), this
|
||||
* re-reads and re-parses that file via cutsceneSystemLoad rather than
|
||||
* just rerunning whatever's still resident in loadedScene/loadedItems, so
|
||||
* a restart always reflects the file's current contents - otherwise it's
|
||||
* just cutsceneSystemStartCutsceneWith on the same cutscene_t. Asserts if
|
||||
* no cutscene is running.
|
||||
*/
|
||||
void cutsceneRestart(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user