feat: resume exploration exactly and harden campaign saves
This commit is contained in:
@@ -887,6 +887,10 @@ try {
|
||||
preJianYongSave.battleHistory[firstScenario.id].bonds = preJianYongSave.battleHistory[firstScenario.id].bonds.filter((bond) => bond.id !== 'liu-bei__jian-yong');
|
||||
preJianYongSave.battleHistory[firstScenario.id].campaignRewards.recruits = preJianYongSave.battleHistory[firstScenario.id].campaignRewards.recruits.filter((recruit) => recruit.unitId !== 'jian-yong');
|
||||
storage.set(campaignStorageKey, JSON.stringify(preJianYongSave));
|
||||
storage.set(
|
||||
`${campaignStorageKey}:slot-${preJianYongSave.activeSaveSlot}`,
|
||||
JSON.stringify(preJianYongSave)
|
||||
);
|
||||
const repairedEarlyChoiceSave = loadCampaignState();
|
||||
const persistedEarlyChoiceSave = saveCampaignState(repairedEarlyChoiceSave);
|
||||
assert(
|
||||
@@ -1152,6 +1156,10 @@ try {
|
||||
'unknown-battle'
|
||||
);
|
||||
storage.set(campaignStorageKey, JSON.stringify(corruptedFutureAcknowledgementSave));
|
||||
storage.set(
|
||||
`${campaignStorageKey}:slot-${corruptedFutureAcknowledgementSave.activeSaveSlot}`,
|
||||
JSON.stringify(corruptedFutureAcknowledgementSave)
|
||||
);
|
||||
const normalizedFutureAcknowledgementSave = loadCampaignState();
|
||||
assert(
|
||||
normalizedFutureAcknowledgementSave.acknowledgedVictoryRewardBattleIds.includes(firstScenario.id) &&
|
||||
@@ -1167,19 +1175,19 @@ try {
|
||||
});
|
||||
const revisedSettlement = getCampaignState();
|
||||
assert(
|
||||
revisedSettlement.gold === 140 &&
|
||||
revisedSettlement.inventory.Bean === 3 &&
|
||||
revisedSettlement.inventory.Wine === 1 &&
|
||||
revisedSettlement.inventory['Iron Sword'] === undefined &&
|
||||
revisedSettlement.inventory['Iron Armor'] === 1,
|
||||
`Expected revised battle report settlement to replace previous rewards instead of stacking: ${JSON.stringify(revisedSettlement)}`
|
||||
revisedSettlement.gold === 100 &&
|
||||
revisedSettlement.inventory.Bean === 2 &&
|
||||
revisedSettlement.inventory.Wine === undefined &&
|
||||
revisedSettlement.inventory['Iron Sword'] === 1 &&
|
||||
revisedSettlement.inventory['Iron Armor'] === undefined,
|
||||
`Expected a revised settled report to update history without replacing or resurrecting the already-committed economy: ${JSON.stringify(revisedSettlement)}`
|
||||
);
|
||||
applyCampVisitReward('repeat-visit', { gold: 10, itemRewards: ['Bean x2'] }, 'repeat-visit-left');
|
||||
applyCampVisitReward('repeat-visit', { gold: 10, itemRewards: ['Bean x2'] }, 'repeat-visit-right');
|
||||
const repeatedVisit = getCampaignState();
|
||||
assert(
|
||||
repeatedVisit.gold === 150 &&
|
||||
repeatedVisit.inventory.Bean === 5 &&
|
||||
repeatedVisit.gold === 110 &&
|
||||
repeatedVisit.inventory.Bean === 4 &&
|
||||
repeatedVisit.completedCampVisits.includes('repeat-visit') &&
|
||||
repeatedVisit.firstBattleReport?.completedCampVisits.includes('repeat-visit') &&
|
||||
repeatedVisit.campVisitChoiceIds['repeat-visit'] === 'repeat-visit-left' &&
|
||||
@@ -1198,8 +1206,8 @@ try {
|
||||
applyCampVisitReward('repeat-visit', { gold: 10, itemRewards: ['Bean x2'] });
|
||||
const visitResynced = getCampaignState();
|
||||
assert(
|
||||
visitResynced.gold === 150 &&
|
||||
visitResynced.inventory.Bean === 5 &&
|
||||
visitResynced.gold === 110 &&
|
||||
visitResynced.inventory.Bean === 4 &&
|
||||
visitResynced.completedCampVisits.includes('repeat-visit') &&
|
||||
visitResynced.firstBattleReport?.completedCampVisits.includes('repeat-visit'),
|
||||
`Expected report-only camp visit completion to resync without duplicate rewards: ${JSON.stringify(visitResynced)}`
|
||||
@@ -1207,7 +1215,7 @@ try {
|
||||
applyCampVisitReward('dirty-reward-visit', { itemRewards: ['', ' ', 'Bean -2', 'Bean +0', 'Bean x2'] });
|
||||
const dirtyRewardVisit = getCampaignState();
|
||||
assert(
|
||||
dirtyRewardVisit.inventory.Bean === 7 &&
|
||||
dirtyRewardVisit.inventory.Bean === 6 &&
|
||||
dirtyRewardVisit.inventory[''] === undefined &&
|
||||
dirtyRewardVisit.inventory['Bean -'] === undefined &&
|
||||
dirtyRewardVisit.completedCampVisits.includes('dirty-reward-visit'),
|
||||
@@ -1495,6 +1503,10 @@ try {
|
||||
corruptedContextualCommandState.battleHistory[firstScenario.id].sortieOrder.command.role = 'support';
|
||||
corruptedContextualCommandState.sortieOrderHistory[firstScenario.id].elite.command.usedTurn = orderBattleReport.turnNumber + 1;
|
||||
storage.set(campaignStorageKey, JSON.stringify(corruptedContextualCommandState));
|
||||
storage.set(
|
||||
`${campaignStorageKey}:slot-1`,
|
||||
JSON.stringify(corruptedContextualCommandState)
|
||||
);
|
||||
const normalizedContextualCommandState = loadCampaignState();
|
||||
assert(
|
||||
normalizedContextualCommandState.firstBattleReport?.sortieOrder?.command === undefined &&
|
||||
@@ -1506,6 +1518,10 @@ try {
|
||||
`Expected contextual normalization to remove ghost actors, role mismatches, and future command turns without dropping their order results: ${JSON.stringify(normalizedContextualCommandState)}`
|
||||
);
|
||||
storage.set(campaignStorageKey, validContextualCommandStateRaw);
|
||||
storage.set(
|
||||
`${campaignStorageKey}:slot-1`,
|
||||
validContextualCommandStateRaw
|
||||
);
|
||||
loadCampaignState();
|
||||
|
||||
orderBattleReport.sortieOrder.progress[0].achieved = false;
|
||||
@@ -1556,14 +1572,14 @@ try {
|
||||
setFirstBattleReport(revisedOrderReport);
|
||||
const revisedOrderSettlement = getCampaignState();
|
||||
assert(
|
||||
revisedOrderSettlement.gold === 320 &&
|
||||
revisedOrderSettlement.inventory.Bean === 3 &&
|
||||
revisedOrderSettlement.inventory.Wine === 1 &&
|
||||
revisedOrderSettlement.inventory['Iron Sword'] === undefined &&
|
||||
revisedOrderSettlement.inventory['Iron Armor'] === 1 &&
|
||||
revisedOrderSettlement.gold === 280 &&
|
||||
revisedOrderSettlement.inventory.Bean === 2 &&
|
||||
revisedOrderSettlement.inventory.Wine === undefined &&
|
||||
revisedOrderSettlement.inventory['Iron Sword'] === 1 &&
|
||||
revisedOrderSettlement.inventory['Iron Armor'] === undefined &&
|
||||
revisedOrderSettlement.inventory['상처약'] === 1 &&
|
||||
revisedOrderSettlement.claimedSortieOrderRewardIds.length === 1,
|
||||
`Expected ordinary reward replacement to preserve the separately claimed sortie-order reward: ${JSON.stringify(revisedOrderSettlement)}`
|
||||
`Expected revised ordinary reward metadata to preserve the already-committed economy and separately claimed sortie-order reward: ${JSON.stringify(revisedOrderSettlement)}`
|
||||
);
|
||||
|
||||
setFirstBattleReport({
|
||||
@@ -1573,7 +1589,7 @@ try {
|
||||
});
|
||||
const secondOrderSameBattle = getCampaignState();
|
||||
assert(
|
||||
secondOrderSameBattle.gold === 480 &&
|
||||
secondOrderSameBattle.gold === 440 &&
|
||||
secondOrderSameBattle.inventory['상처약'] === 1 &&
|
||||
secondOrderSameBattle.inventory['탁주'] === 1 &&
|
||||
secondOrderSameBattle.claimedSortieOrderRewardIds.includes(`${firstScenario.id}:elite`) &&
|
||||
@@ -1597,7 +1613,7 @@ try {
|
||||
});
|
||||
const failedEliteReplay = getCampaignState();
|
||||
assert(
|
||||
failedEliteReplay.gold === 480 &&
|
||||
failedEliteReplay.gold === 440 &&
|
||||
failedEliteReplay.inventory['상처약'] === 1 &&
|
||||
failedEliteReplay.claimedSortieOrderRewardIds.includes(`${firstScenario.id}:elite`) &&
|
||||
failedEliteReplay.firstBattleReport?.sortieOrder?.achieved === false &&
|
||||
@@ -1624,7 +1640,7 @@ try {
|
||||
});
|
||||
const sameOrderDifferentBattle = getCampaignState();
|
||||
assert(
|
||||
sameOrderDifferentBattle.gold === 780 &&
|
||||
sameOrderDifferentBattle.gold === 740 &&
|
||||
sameOrderDifferentBattle.inventory['상처약'] === 2 &&
|
||||
sameOrderDifferentBattle.claimedSortieOrderRewardIds.includes(`${secondScenario.id}:elite`) &&
|
||||
sameOrderDifferentBattle.claimedSortieOrderRewardIds.length === 3 &&
|
||||
@@ -1654,7 +1670,7 @@ try {
|
||||
const spentRewardReplay = getCampaignState();
|
||||
assert(
|
||||
spentRewardReplay.gold === 160 &&
|
||||
spentRewardReplay.inventory['탁주'] === 2 &&
|
||||
spentRewardReplay.inventory['탁주'] === 1 &&
|
||||
spentRewardReplay.claimedSortieOrderRewardIds.includes(`${firstScenario.id}:mobile`) &&
|
||||
spentRewardReplay.firstBattleReport?.sortieOrder?.rewardGranted === true,
|
||||
`Expected a first order reward to remain intact even when previously settled ordinary gold/items were already spent: ${JSON.stringify(spentRewardReplay)}`
|
||||
|
||||
Reference in New Issue
Block a user