feat: add walkable Guangzong sortie camp
This commit is contained in:
@@ -36,6 +36,12 @@ try {
|
||||
const actionModule = await server.ssrLoadModule(
|
||||
'/src/game/state/thirdCampPreparationActions.ts'
|
||||
);
|
||||
const explorationDataModule = await server.ssrLoadModule(
|
||||
'/src/game/data/thirdCampExploration.ts'
|
||||
);
|
||||
const explorationActionModule = await server.ssrLoadModule(
|
||||
'/src/game/state/thirdCampExplorationActions.ts'
|
||||
);
|
||||
const campaignModule = await server.ssrLoadModule(
|
||||
'/src/game/state/campaignState.ts'
|
||||
);
|
||||
@@ -50,6 +56,8 @@ try {
|
||||
verifyGuardedPersistentOverwrite(
|
||||
dataModule,
|
||||
actionModule,
|
||||
explorationDataModule,
|
||||
explorationActionModule,
|
||||
campaignModule,
|
||||
battleScenarios
|
||||
);
|
||||
@@ -172,17 +180,29 @@ function verifyActivityGates(dataModule) {
|
||||
});
|
||||
availability =
|
||||
dataModule.resolveThirdCampPreparationAvailability(acknowledged);
|
||||
assert(
|
||||
availability.every(({ selectable }) => selectable === false),
|
||||
'Opening reward categories alone must not complete walkable-camp activities.'
|
||||
);
|
||||
|
||||
const explored = literalCampaign(dataModule, {
|
||||
completedActivities: ['information', 'equipment']
|
||||
});
|
||||
availability =
|
||||
dataModule.resolveThirdCampPreparationAvailability(explored);
|
||||
assert.equal(availability[0].selectable, true);
|
||||
assert.deepEqual(availability[0].evidence, {
|
||||
kind: 'victory-reward-category',
|
||||
kind: 'exploration-activity',
|
||||
battleId: dataModule.thirdCampPreparationSourceBattleId,
|
||||
category: 'unlocks'
|
||||
visitId: 'third-guangzong-sortie-camp',
|
||||
activityId: 'information'
|
||||
});
|
||||
assert.equal(availability[1].selectable, true);
|
||||
assert.deepEqual(availability[1].evidence, {
|
||||
kind: 'victory-reward-category',
|
||||
kind: 'exploration-activity',
|
||||
battleId: dataModule.thirdCampPreparationSourceBattleId,
|
||||
category: 'equipment'
|
||||
visitId: 'third-guangzong-sortie-camp',
|
||||
activityId: 'equipment'
|
||||
});
|
||||
assert.equal(availability[2].selectable, false);
|
||||
|
||||
@@ -198,6 +218,7 @@ function verifyActivityGates(dataModule) {
|
||||
assert.equal(availability[1].selectable, false);
|
||||
|
||||
const companion = literalCampaign(dataModule, {
|
||||
completedActivities: ['companion'],
|
||||
completePriorityDialogue: true
|
||||
});
|
||||
availability =
|
||||
@@ -208,7 +229,7 @@ function verifyActivityGates(dataModule) {
|
||||
assert.equal(companionAvailability?.selectable, true);
|
||||
assert.equal(
|
||||
companionAvailability?.evidence?.kind,
|
||||
'priority-return-dialogue'
|
||||
'exploration-activity'
|
||||
);
|
||||
assert.equal(
|
||||
companionAvailability?.evidence?.dialogueId,
|
||||
@@ -219,6 +240,18 @@ function verifyActivityGates(dataModule) {
|
||||
'guan-yu__zhang-fei'
|
||||
);
|
||||
|
||||
const legacyCompanion = literalCampaign(dataModule, {
|
||||
completePriorityDialogue: true
|
||||
});
|
||||
assert.equal(
|
||||
dataModule.resolveThirdCampPreparationAvailability(
|
||||
legacyCompanion
|
||||
).find(({ priority }) => priority.id === 'companion')
|
||||
?.evidence?.kind,
|
||||
'priority-return-dialogue',
|
||||
'An already completed result dialogue must remain valid for old saves.'
|
||||
);
|
||||
|
||||
const unrelatedDialogue = literalCampaign(dataModule);
|
||||
unrelatedDialogue.completedCampDialogues = [
|
||||
'liu-guan-after-guangzong-road'
|
||||
@@ -299,7 +332,7 @@ function verifyTargetBattleMemoryIsolation(dataModule) {
|
||||
);
|
||||
|
||||
const stale = eligibleLiteralCampaign(dataModule, 'information');
|
||||
stale.acknowledgedVictoryRewardCategories = {};
|
||||
stale.completedCampVisits = [];
|
||||
assert.equal(
|
||||
dataModule.resolveThirdCampPreparationMemory({
|
||||
campaign: stale,
|
||||
@@ -409,7 +442,7 @@ function verifyBattleLifecycleContract(dataModule) {
|
||||
memory.evidence.unitIds[0] = 'mutated';
|
||||
}
|
||||
assert.notEqual(fresh?.label, 'mutated');
|
||||
if (fresh?.evidence.kind === 'priority-return-dialogue') {
|
||||
if (fresh && 'unitIds' in fresh.evidence) {
|
||||
assert.notEqual(fresh.evidence.unitIds[0], 'mutated');
|
||||
}
|
||||
});
|
||||
@@ -418,6 +451,8 @@ function verifyBattleLifecycleContract(dataModule) {
|
||||
function verifyGuardedPersistentOverwrite(
|
||||
dataModule,
|
||||
actionModule,
|
||||
explorationDataModule,
|
||||
explorationActionModule,
|
||||
campaignModule,
|
||||
battleScenarios
|
||||
) {
|
||||
@@ -432,9 +467,16 @@ function verifyGuardedPersistentOverwrite(
|
||||
'activity-required'
|
||||
);
|
||||
|
||||
campaignModule.acknowledgeCampaignVictoryReward(
|
||||
dataModule.thirdCampPreparationSourceBattleId,
|
||||
['unlocks']
|
||||
const entry = explorationActionModule.enterThirdCampExploration();
|
||||
assert.equal(entry.ok, true);
|
||||
const informationActivity =
|
||||
explorationActionModule.recordThirdCampExplorationActivity(
|
||||
'information'
|
||||
);
|
||||
assert.equal(informationActivity.ok, true);
|
||||
assert.equal(
|
||||
actionModule.clearThirdCampPreparationPriority().ok,
|
||||
true
|
||||
);
|
||||
let result =
|
||||
actionModule.setThirdCampPreparationPriority('information');
|
||||
@@ -465,19 +507,35 @@ function verifyGuardedPersistentOverwrite(
|
||||
'A rejected replacement must preserve the previous valid priority.'
|
||||
);
|
||||
|
||||
campaignModule.acknowledgeCampaignVictoryReward(
|
||||
dataModule.thirdCampPreparationSourceBattleId,
|
||||
['equipment']
|
||||
const equipmentActivity =
|
||||
explorationActionModule.recordThirdCampExplorationActivity(
|
||||
'equipment'
|
||||
);
|
||||
assert.equal(equipmentActivity.ok, true);
|
||||
assert.equal(
|
||||
actionModule.clearThirdCampPreparationPriority().ok,
|
||||
true
|
||||
);
|
||||
result = actionModule.setThirdCampPreparationPriority('equipment');
|
||||
assert.equal(result.ok, true);
|
||||
assert.equal(result.changed, true);
|
||||
assert.equal(result.memory.priorityId, 'equipment');
|
||||
|
||||
completePriorityDialogue(
|
||||
dataModule,
|
||||
campaignModule,
|
||||
battleScenarios
|
||||
const explorationDefinition =
|
||||
explorationDataModule.resolveThirdCampExplorationDefinition(
|
||||
campaignModule.getCampaignState()
|
||||
);
|
||||
const companionChoiceId =
|
||||
explorationDefinition?.companionDialogue.choices[0]?.id;
|
||||
assert(companionChoiceId);
|
||||
const companionActivity =
|
||||
explorationActionModule.completeThirdCampCompanionActivity(
|
||||
companionChoiceId
|
||||
);
|
||||
assert.equal(companionActivity.ok, true);
|
||||
assert.equal(
|
||||
actionModule.clearThirdCampPreparationPriority().ok,
|
||||
true
|
||||
);
|
||||
result = actionModule.setThirdCampPreparationPriority('companion');
|
||||
assert.equal(result.ok, true);
|
||||
@@ -883,12 +941,7 @@ function priorityDialogueForCampaign(campaign, dataModule) {
|
||||
|
||||
function eligibleLiteralCampaign(dataModule, priorityId) {
|
||||
return literalCampaign(dataModule, {
|
||||
acknowledgedCategories:
|
||||
priorityId === 'information'
|
||||
? ['unlocks']
|
||||
: priorityId === 'equipment'
|
||||
? ['equipment']
|
||||
: [],
|
||||
completedActivities: [priorityId],
|
||||
completePriorityDialogue: priorityId === 'companion',
|
||||
selectedPriorityId: priorityId
|
||||
});
|
||||
@@ -898,6 +951,7 @@ function literalCampaign(
|
||||
dataModule,
|
||||
{
|
||||
acknowledgedCategories = [],
|
||||
completedActivities = [],
|
||||
completePriorityDialogue = false,
|
||||
selectedPriorityId,
|
||||
legacyReportOnly = false
|
||||
@@ -926,7 +980,10 @@ function literalCampaign(
|
||||
completedCampDialogues: completePriorityDialogue
|
||||
? ['guan-zhang-after-guangzong-road']
|
||||
: [],
|
||||
completedCampVisits: [],
|
||||
completedCampVisits: completedActivities.map(
|
||||
(activityId) =>
|
||||
`third-guangzong-sortie-camp:activity:${activityId}`
|
||||
),
|
||||
campVisitChoiceIds: {},
|
||||
...(selectedPriorityId
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user