Add campaign battle rewards

This commit is contained in:
2026-07-03 23:21:30 +09:00
parent aafe210977
commit 0c4e358284
5 changed files with 265 additions and 13 deletions

View File

@@ -21,6 +21,21 @@ export type CampMvpSnapshot = {
defeats: number;
};
export type CampaignRewardSnapshot = {
supplies: string[];
equipment: string[];
reputation: string[];
recruits: {
unitId: string;
name: string;
}[];
unlocks: {
battleId: string;
title: string;
}[];
note?: string;
};
export type FirstBattleReport = {
battleId: string;
battleTitle: string;
@@ -34,6 +49,7 @@ export type FirstBattleReport = {
bonds: CampBondSnapshot[];
mvp?: CampMvpSnapshot;
itemRewards: string[];
campaignRewards?: CampaignRewardSnapshot;
completedCampDialogues: string[];
completedCampVisits: string[];
createdAt: string;
@@ -263,6 +279,7 @@ export type CampaignBattleSettlement = {
outcome: FirstBattleReport['outcome'];
rewardGold: number;
itemRewards: string[];
campaignRewards?: CampaignRewardSnapshot;
objectives: BattleObjectiveSnapshot[];
units: CampaignUnitProgressSnapshot[];
bonds: CampaignBondProgressSnapshot[];
@@ -494,7 +511,10 @@ export function setFirstBattleReport(report: FirstBattleReport) {
state.step = victoryStep;
state.gold = Math.max(0, state.gold - (previousSettlement?.rewardGold ?? 0) + reportClone.rewardGold);
state.roster = mergeRosterProgress(state.roster, reportClone.units.filter((unit) => unit.faction === 'ally'));
const alliedReportUnits = reportClone.units.filter((unit) => unit.faction === 'ally');
const recruitUnitIds = new Set(reportClone.campaignRewards?.recruits.map((recruit) => recruit.unitId) ?? []);
const recruitedUnits = reportClone.units.filter((unit) => unit.faction === 'ally' && recruitUnitIds.has(unit.id));
state.roster = mergeRosterProgress(state.roster, [...alliedReportUnits, ...recruitedUnits]);
state.bonds = reportClone.bonds.map(cloneBondSnapshot);
const reserveTraining = previousSettlement || reportClone.outcome !== 'victory'
? previousSettlement?.reserveTraining ?? []
@@ -753,6 +773,7 @@ function createBattleSettlement(report: FirstBattleReport, reserveTraining: Camp
outcome: report.outcome,
rewardGold: report.rewardGold,
itemRewards: [...report.itemRewards],
campaignRewards: cloneCampaignRewardSnapshot(report.campaignRewards),
objectives: report.objectives.map((objective) => ({ ...objective })),
units: report.units
.filter((unit) => unit.faction === 'ally')
@@ -887,9 +908,27 @@ function cloneCampaignState(state: CampaignState): CampaignState {
function cloneReport(report: FirstBattleReport): FirstBattleReport {
const cloned = JSON.parse(JSON.stringify(report)) as FirstBattleReport;
cloned.completedCampVisits = [...new Set(cloned.completedCampVisits ?? [])];
if (cloned.campaignRewards) {
cloned.campaignRewards = cloneCampaignRewardSnapshot(cloned.campaignRewards);
}
return cloned;
}
function cloneCampaignRewardSnapshot(rewards?: CampaignRewardSnapshot): CampaignRewardSnapshot | undefined {
if (!rewards) {
return undefined;
}
return {
supplies: [...(rewards.supplies ?? [])],
equipment: [...(rewards.equipment ?? [])],
reputation: [...(rewards.reputation ?? [])],
recruits: (rewards.recruits ?? []).map((recruit) => ({ ...recruit })),
unlocks: (rewards.unlocks ?? []).map((unlock) => ({ ...unlock })),
note: rewards.note
};
}
function cloneUnit(unit: UnitData): UnitData {
return JSON.parse(JSON.stringify(unit)) as UnitData;
}