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.textMiniLastCreated = CUTSCENE_TEXT_MINI_LAST_CREATED;
|
||||||
CUTSCENE_SYSTEM.textCache[0] = '\0';
|
CUTSCENE_SYSTEM.textCache[0] = '\0';
|
||||||
CUTSCENE_SYSTEM.onComplete = NULL;
|
CUTSCENE_SYSTEM.onComplete = NULL;
|
||||||
|
CUTSCENE_SYSTEM.loadedFile[0] = '\0';
|
||||||
|
|
||||||
cutsceneLoadedSetDoc(NULL);
|
cutsceneLoadedSetDoc(NULL);
|
||||||
}
|
}
|
||||||
@@ -58,6 +59,7 @@ void cutsceneSystemPrepare(
|
|||||||
CUTSCENE_SYSTEM.textCache[0] = '\0';
|
CUTSCENE_SYSTEM.textCache[0] = '\0';
|
||||||
CUTSCENE_SYSTEM.currentItem = 0xFF;// Set to 0xFF so Next wraps to 0.
|
CUTSCENE_SYSTEM.currentItem = 0xFF;// Set to 0xFF so Next wraps to 0.
|
||||||
CUTSCENE_SYSTEM.onComplete = NULL;
|
CUTSCENE_SYSTEM.onComplete = NULL;
|
||||||
|
CUTSCENE_SYSTEM.loadedFile[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void cutsceneSystemStartCutscene(cutscene_t *cutscene) {
|
void cutsceneSystemStartCutscene(cutscene_t *cutscene) {
|
||||||
@@ -69,6 +71,12 @@ void cutsceneSystemStartCutsceneWith(
|
|||||||
entity_t *interact,
|
entity_t *interact,
|
||||||
entity_t *interacted
|
entity_t *interacted
|
||||||
) {
|
) {
|
||||||
|
assertNotNull(cutscene, "Cutscene cannot be NULL");
|
||||||
|
assertTrue(
|
||||||
|
cutscene->itemCount <= cutscene->itemsMax,
|
||||||
|
"Cutscene itemCount exceeds itemsMax"
|
||||||
|
);
|
||||||
|
|
||||||
cutsceneSystemPrepare(cutscene, interact, interacted);
|
cutsceneSystemPrepare(cutscene, interact, interacted);
|
||||||
cutsceneSystemNext();
|
cutsceneSystemNext();
|
||||||
}
|
}
|
||||||
@@ -139,6 +147,7 @@ void cutsceneSystemLoad(const char_t *file) {
|
|||||||
|
|
||||||
cutsceneLoadedSetDoc(doc);
|
cutsceneLoadedSetDoc(doc);
|
||||||
cutsceneSystemStartCutscene(&CUTSCENE_SYSTEM.loadedScene);
|
cutsceneSystemStartCutscene(&CUTSCENE_SYSTEM.loadedScene);
|
||||||
|
stringCopy(CUTSCENE_SYSTEM.loadedFile, file, ASSET_FILE_NAME_MAX - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cutsceneLoadedSetDoc(yyjson_doc *doc) {
|
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
|
// 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
|
// 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;
|
cutscenecallback_t onComplete = CUTSCENE_SYSTEM.onComplete;
|
||||||
|
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(
|
cutsceneSystemStartCutsceneWith(
|
||||||
CUTSCENE_SYSTEM.scene,
|
CUTSCENE_SYSTEM.scene, entityInteract, entityInteracted
|
||||||
CUTSCENE_SYSTEM.entityInteract,
|
|
||||||
CUTSCENE_SYSTEM.entityInteracted
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
CUTSCENE_SYSTEM.onComplete = onComplete;
|
CUTSCENE_SYSTEM.onComplete = onComplete;
|
||||||
|
CUTSCENE_SYSTEM.entityInteract = entityInteract;
|
||||||
|
CUTSCENE_SYSTEM.entityInteracted = entityInteracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cutsceneSystemSetOnComplete(cutscenecallback_t onComplete) {
|
void cutsceneSystemSetOnComplete(cutscenecallback_t onComplete) {
|
||||||
|
|||||||
@@ -52,6 +52,16 @@ typedef struct {
|
|||||||
|
|
||||||
cutsceneitem_t loadedItems[CUTSCENE_LOADED_ITEMS_MAX];
|
cutsceneitem_t loadedItems[CUTSCENE_LOADED_ITEMS_MAX];
|
||||||
cutscene_t loadedScene;
|
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;
|
} cutscenesystem_t;
|
||||||
|
|
||||||
extern cutscenesystem_t CUTSCENE_SYSTEM;
|
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
|
* 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
|
* re-read+re-parsed fresh, never assumed still resident from a previous
|
||||||
* call. Opens the fatal error overlay (see uiFatalErrorOpen) instead of
|
* 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
|
* @param file Cutscene file name (with .jsonc extension), relative to
|
||||||
* assets/cutscenes/.
|
* assets/cutscenes/.
|
||||||
@@ -174,8 +185,14 @@ void cutsceneLoadedSetDoc(yyjson_doc *doc);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Restarts the currently running cutscene from its first item,
|
* Restarts the currently running cutscene from its first item,
|
||||||
* preserving whatever interact/interacted entities triggered it.
|
* preserving whatever interact/interacted entities triggered it and
|
||||||
* Asserts if no cutscene is running.
|
* 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);
|
void cutsceneRestart(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user