generated from nhcarrigan/template
fix: patch quest and boss rewards on sync to restore unlock conditions
This commit is contained in:
@@ -566,6 +566,63 @@ const injectMissingExplorationAreas = (state: GameState): number => {
|
|||||||
return added;
|
return added;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patches rewards on existing quests whose reward lists have grown since the
|
||||||
|
* save was created (e.g. A new upgrade added as a reward to an old quest).
|
||||||
|
* @param state - The player's current game state (mutated in place).
|
||||||
|
* @returns The total number of individual rewards that were added.
|
||||||
|
*/
|
||||||
|
const patchQuestRewards = (state: GameState): number => {
|
||||||
|
const defaultQuestMap = new Map(defaultQuests.map((quest) => {
|
||||||
|
return [ quest.id, quest ] as const;
|
||||||
|
}));
|
||||||
|
let added = 0;
|
||||||
|
for (const savedQuest of state.quests) {
|
||||||
|
const defaultQuest = defaultQuestMap.get(savedQuest.id);
|
||||||
|
if (defaultQuest === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const existingKeys = new Set(savedQuest.rewards.map((reward) => {
|
||||||
|
return `${reward.type}:${String(reward.targetId ?? reward.amount ?? "")}`;
|
||||||
|
}));
|
||||||
|
for (const reward of defaultQuest.rewards) {
|
||||||
|
const key = `${reward.type}:${String(reward.targetId ?? reward.amount ?? "")}`;
|
||||||
|
if (!existingKeys.has(key)) {
|
||||||
|
savedQuest.rewards.push(structuredClone(reward));
|
||||||
|
added = added + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return added;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patches upgradeRewards on existing bosses whose reward lists have grown
|
||||||
|
* since the save was created.
|
||||||
|
* @param state - The player's current game state (mutated in place).
|
||||||
|
* @returns The total number of upgrade reward IDs that were added.
|
||||||
|
*/
|
||||||
|
const patchBossUpgradeRewards = (state: GameState): number => {
|
||||||
|
const defaultBossMap = new Map(defaultBosses.map((boss) => {
|
||||||
|
return [ boss.id, boss ] as const;
|
||||||
|
}));
|
||||||
|
let added = 0;
|
||||||
|
for (const savedBoss of state.bosses) {
|
||||||
|
const defaultBoss = defaultBossMap.get(savedBoss.id);
|
||||||
|
if (defaultBoss === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const existingIds = new Set(savedBoss.upgradeRewards);
|
||||||
|
for (const upgradeId of defaultBoss.upgradeRewards) {
|
||||||
|
if (!existingIds.has(upgradeId)) {
|
||||||
|
savedBoss.upgradeRewards.push(upgradeId);
|
||||||
|
added = added + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return added;
|
||||||
|
};
|
||||||
|
|
||||||
/* eslint-disable stylistic/max-len -- Long function call lines cannot be shortened without losing alignment */
|
/* eslint-disable stylistic/max-len -- Long function call lines cannot be shortened without losing alignment */
|
||||||
/**
|
/**
|
||||||
* Syncs a player's save with the current game data, injecting any content
|
* Syncs a player's save with the current game data, injecting any content
|
||||||
@@ -579,8 +636,10 @@ const syncNewContent = (
|
|||||||
achievementsAdded: number;
|
achievementsAdded: number;
|
||||||
adventurersAdded: number;
|
adventurersAdded: number;
|
||||||
bossesAdded: number;
|
bossesAdded: number;
|
||||||
|
bossRewardsPatched: number;
|
||||||
equipmentAdded: number;
|
equipmentAdded: number;
|
||||||
explorationAreasAdded: number;
|
explorationAreasAdded: number;
|
||||||
|
questRewardsPatched: number;
|
||||||
questsAdded: number;
|
questsAdded: number;
|
||||||
upgradesAdded: number;
|
upgradesAdded: number;
|
||||||
zonesAdded: number;
|
zonesAdded: number;
|
||||||
@@ -588,9 +647,11 @@ const syncNewContent = (
|
|||||||
return {
|
return {
|
||||||
achievementsAdded: injectMissingEntries(state.achievements, defaultAchievements),
|
achievementsAdded: injectMissingEntries(state.achievements, defaultAchievements),
|
||||||
adventurersAdded: injectMissingEntries(state.adventurers, defaultAdventurers),
|
adventurersAdded: injectMissingEntries(state.adventurers, defaultAdventurers),
|
||||||
|
bossRewardsPatched: patchBossUpgradeRewards(state),
|
||||||
bossesAdded: injectMissingEntries(state.bosses, defaultBosses),
|
bossesAdded: injectMissingEntries(state.bosses, defaultBosses),
|
||||||
equipmentAdded: injectMissingEntries(state.equipment, defaultEquipment),
|
equipmentAdded: injectMissingEntries(state.equipment, defaultEquipment),
|
||||||
explorationAreasAdded: injectMissingExplorationAreas(state),
|
explorationAreasAdded: injectMissingExplorationAreas(state),
|
||||||
|
questRewardsPatched: patchQuestRewards(state),
|
||||||
questsAdded: injectMissingEntries(state.quests, defaultQuests),
|
questsAdded: injectMissingEntries(state.quests, defaultQuests),
|
||||||
upgradesAdded: injectMissingEntries(state.upgrades, defaultUpgrades),
|
upgradesAdded: injectMissingEntries(state.upgrades, defaultUpgrades),
|
||||||
zonesAdded: injectMissingEntries(state.zones, defaultZones),
|
zonesAdded: injectMissingEntries(state.zones, defaultZones),
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ interface SyncNewContentResult {
|
|||||||
achievementsAdded: number;
|
achievementsAdded: number;
|
||||||
adventurersAdded: number;
|
adventurersAdded: number;
|
||||||
bossesAdded: number;
|
bossesAdded: number;
|
||||||
|
bossRewardsPatched: number;
|
||||||
equipmentAdded: number;
|
equipmentAdded: number;
|
||||||
explorationAreasAdded: number;
|
explorationAreasAdded: number;
|
||||||
|
questRewardsPatched: number;
|
||||||
questsAdded: number;
|
questsAdded: number;
|
||||||
upgradesAdded: number;
|
upgradesAdded: number;
|
||||||
zonesAdded: number;
|
zonesAdded: number;
|
||||||
@@ -32,7 +34,9 @@ const buildSyncNewContentMessage = (result: SyncNewContentResult): string => {
|
|||||||
const entries: Array<[ number, string ]> = [
|
const entries: Array<[ number, string ]> = [
|
||||||
[ result.zonesAdded, "zone(s)" ],
|
[ result.zonesAdded, "zone(s)" ],
|
||||||
[ result.questsAdded, "quest(s)" ],
|
[ result.questsAdded, "quest(s)" ],
|
||||||
|
[ result.questRewardsPatched, "quest reward(s) patched" ],
|
||||||
[ result.bossesAdded, "boss(es)" ],
|
[ result.bossesAdded, "boss(es)" ],
|
||||||
|
[ result.bossRewardsPatched, "boss reward(s) patched" ],
|
||||||
[ result.explorationAreasAdded, "exploration area(s)" ],
|
[ result.explorationAreasAdded, "exploration area(s)" ],
|
||||||
[ result.adventurersAdded, "adventurer tier(s)" ],
|
[ result.adventurersAdded, "adventurer tier(s)" ],
|
||||||
[ result.upgradesAdded, "upgrade(s)" ],
|
[ result.upgradesAdded, "upgrade(s)" ],
|
||||||
@@ -52,7 +56,7 @@ const buildSyncNewContentMessage = (result: SyncNewContentResult): string => {
|
|||||||
const total = entries.reduce((sum, [ count ]) => {
|
const total = entries.reduce((sum, [ count ]) => {
|
||||||
return sum + count;
|
return sum + count;
|
||||||
}, 0);
|
}, 0);
|
||||||
return `Added ${String(total)} new item(s) to your save: ${parts.join(", ")}.`;
|
return `Synced ${String(total)} item(s): ${parts.join(", ")}.`;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ForceUnlocksResult {
|
interface ForceUnlocksResult {
|
||||||
|
|||||||
@@ -583,8 +583,10 @@ interface GameContextValue {
|
|||||||
achievementsAdded: number;
|
achievementsAdded: number;
|
||||||
adventurersAdded: number;
|
adventurersAdded: number;
|
||||||
bossesAdded: number;
|
bossesAdded: number;
|
||||||
|
bossRewardsPatched: number;
|
||||||
equipmentAdded: number;
|
equipmentAdded: number;
|
||||||
explorationAreasAdded: number;
|
explorationAreasAdded: number;
|
||||||
|
questRewardsPatched: number;
|
||||||
questsAdded: number;
|
questsAdded: number;
|
||||||
upgradesAdded: number;
|
upgradesAdded: number;
|
||||||
zonesAdded: number;
|
zonesAdded: number;
|
||||||
@@ -2178,9 +2180,11 @@ export const GameProvider = ({
|
|||||||
return {
|
return {
|
||||||
achievementsAdded: data.achievementsAdded,
|
achievementsAdded: data.achievementsAdded,
|
||||||
adventurersAdded: data.adventurersAdded,
|
adventurersAdded: data.adventurersAdded,
|
||||||
|
bossRewardsPatched: data.bossRewardsPatched,
|
||||||
bossesAdded: data.bossesAdded,
|
bossesAdded: data.bossesAdded,
|
||||||
equipmentAdded: data.equipmentAdded,
|
equipmentAdded: data.equipmentAdded,
|
||||||
explorationAreasAdded: data.explorationAreasAdded,
|
explorationAreasAdded: data.explorationAreasAdded,
|
||||||
|
questRewardsPatched: data.questRewardsPatched,
|
||||||
questsAdded: data.questsAdded,
|
questsAdded: data.questsAdded,
|
||||||
upgradesAdded: data.upgradesAdded,
|
upgradesAdded: data.upgradesAdded,
|
||||||
zonesAdded: data.zonesAdded,
|
zonesAdded: data.zonesAdded,
|
||||||
@@ -2194,9 +2198,11 @@ export const GameProvider = ({
|
|||||||
return {
|
return {
|
||||||
achievementsAdded: 0,
|
achievementsAdded: 0,
|
||||||
adventurersAdded: 0,
|
adventurersAdded: 0,
|
||||||
|
bossRewardsPatched: 0,
|
||||||
bossesAdded: 0,
|
bossesAdded: 0,
|
||||||
equipmentAdded: 0,
|
equipmentAdded: 0,
|
||||||
explorationAreasAdded: 0,
|
explorationAreasAdded: 0,
|
||||||
|
questRewardsPatched: 0,
|
||||||
questsAdded: 0,
|
questsAdded: 0,
|
||||||
upgradesAdded: 0,
|
upgradesAdded: 0,
|
||||||
zonesAdded: 0,
|
zonesAdded: 0,
|
||||||
|
|||||||
@@ -468,6 +468,11 @@ interface SyncNewContentResponse {
|
|||||||
*/
|
*/
|
||||||
upgradesAdded: number;
|
upgradesAdded: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of rewards patched onto existing quests.
|
||||||
|
*/
|
||||||
|
questRewardsPatched: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of quests added to the save.
|
* Number of quests added to the save.
|
||||||
*/
|
*/
|
||||||
@@ -478,6 +483,11 @@ interface SyncNewContentResponse {
|
|||||||
*/
|
*/
|
||||||
bossesAdded: number;
|
bossesAdded: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of upgrade reward IDs patched onto existing bosses.
|
||||||
|
*/
|
||||||
|
bossRewardsPatched: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of equipment items added to the save.
|
* Number of equipment items added to the save.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user