isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
106 lines (105 loc) • 5.57 kB
JavaScript
;
// The save data manager has a feature where certain variables will automatically be rolled back
// when the Glowing Hourglass is used.
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeGlowingHourGlassBackup = makeGlowingHourGlassBackup;
exports.restoreGlowingHourGlassBackup = restoreGlowingHourGlassBackup;
const SaveDataKey_1 = require("../../../../enums/SaveDataKey");
const SerializationType_1 = require("../../../../enums/SerializationType");
const deepCopy_1 = require("../../../../functions/deepCopy");
const merge_1 = require("../../../../functions/merge");
const table_1 = require("../../../../functions/table");
const constants_1 = require("./constants");
/**
* When the Glowing Hourglass is used, certain save data keys will automatically be restored to a
* backup.
*/
const GLOWING_HOUR_GLASS_BACKUP_KEYS = [
SaveDataKey_1.SaveDataKey.RUN,
SaveDataKey_1.SaveDataKey.LEVEL,
];
const IGNORE_GLOWING_HOUR_GLASS_KEY = "__ignoreGlowingHourGlass";
const REWIND_WITH_GLOWING_HOUR_GLASS_KEY = "__rewindWithGlowingHourGlass";
function makeGlowingHourGlassBackup(saveDataMap, saveDataConditionalFuncMap, saveDataGlowingHourGlassMap) {
(0, table_1.iterateTableInOrder)(saveDataMap, (subscriberName, saveData) => {
// We make the Glowing Hourglass backup using `SerializationType.SERIALIZE`, which means that
// we cannot operate on unserializable data, such as functions. Save data that utilizes
// unserializable data will typically be marked using a conditional function that evaluates to
// false, so we skip all save data that matches this criteria.
const conditionalFunc = saveDataConditionalFuncMap.get(subscriberName);
if (conditionalFunc !== undefined) {
const shouldSave = conditionalFunc();
if (!shouldSave) {
return;
}
}
for (const saveDataKey of getKeysToBackup(saveData)) {
const childTable = saveData[saveDataKey];
if (childTable === undefined) {
// This feature does not happen to store any variables on this particular child table.
continue;
}
// Ignore child tables that the end-user has explicitly annotated.
const childTableLuaMap = childTable;
if (childTableLuaMap.has(IGNORE_GLOWING_HOUR_GLASS_KEY)) {
continue;
}
let saveDataGlowingHourGlass = saveDataGlowingHourGlassMap.get(subscriberName);
if (saveDataGlowingHourGlass === undefined) {
saveDataGlowingHourGlass = new LuaMap();
saveDataGlowingHourGlassMap.set(subscriberName, saveDataGlowingHourGlass);
}
// We serialize the table so that we can use the `merge` function later on with no other
// modifications.
const copiedChildTable = (0, deepCopy_1.deepCopy)(childTable, SerializationType_1.SerializationType.SERIALIZE);
saveDataGlowingHourGlass[saveDataKey] = copiedChildTable;
}
}, constants_1.SAVE_DATA_MANAGER_DEBUG);
}
function restoreGlowingHourGlassBackup(saveDataMap, saveDataConditionalFuncMap, saveDataGlowingHourGlassMap, classConstructors) {
(0, table_1.iterateTableInOrder)(saveDataMap, (subscriberName, saveData) => {
// We make the Glowing Hourglass backup using `SerializationType.SERIALIZE`, which means that
// we cannot operate on unserializable data, such as functions. Save data that utilizes
// unserializable data will typically be marked using a conditional function that evaluates to
// false, so we skip all save data that matches this criteria.
const conditionalFunc = saveDataConditionalFuncMap.get(subscriberName);
if (conditionalFunc !== undefined) {
const shouldSave = conditionalFunc();
if (!shouldSave) {
return;
}
}
for (const saveDataKey of getKeysToBackup(saveData)) {
const childTable = saveData[saveDataKey];
if (childTable === undefined) {
// This feature does not happen to store any variables on this particular child table.
continue;
}
// Ignore child tables that the end-user has explicitly annotated.
const childTableLuaMap = childTable;
if (childTableLuaMap.has(IGNORE_GLOWING_HOUR_GLASS_KEY)) {
continue;
}
const saveDataGlowingHourGlass = saveDataGlowingHourGlassMap.get(subscriberName);
if (saveDataGlowingHourGlass === undefined) {
// This should never happen.
continue;
}
const childTableBackup = saveDataGlowingHourGlass[saveDataKey];
if (childTableBackup === undefined) {
// This should never happen.
continue;
}
(0, merge_1.merge)(childTable, childTableBackup,
// Append an arbitrary suffix for better error messages.
`${subscriberName}__glowingHourGlass`, classConstructors);
}
}, constants_1.SAVE_DATA_MANAGER_DEBUG);
}
function getKeysToBackup(saveData) {
const shouldBackupPersistentObject = saveData.persistent !== undefined
&& saveData.persistent.has(REWIND_WITH_GLOWING_HOUR_GLASS_KEY);
return shouldBackupPersistentObject
? [...GLOWING_HOUR_GLASS_BACKUP_KEYS, SaveDataKey_1.SaveDataKey.PERSISTENT]
: GLOWING_HOUR_GLASS_BACKUP_KEYS;
}