Prevent duplicate camp rewards

This commit is contained in:
2026-07-05 10:38:30 +09:00
parent 584965d455
commit f4ff01e917
3 changed files with 91 additions and 11 deletions

View File

@@ -677,11 +677,12 @@ export function applyCampBondExp(dialogueId: string, bondId: string, amount: num
return undefined;
}
if (!state.completedCampDialogues.includes(dialogueId)) {
state.completedCampDialogues.push(dialogueId);
}
if (!state.firstBattleReport.completedCampDialogues.includes(dialogueId)) {
state.firstBattleReport.completedCampDialogues.push(dialogueId);
if (hasCompletionFlag(state.completedCampDialogues, state.firstBattleReport.completedCampDialogues, dialogueId)) {
if (syncCompletionFlag(state.completedCampDialogues, state.firstBattleReport.completedCampDialogues, dialogueId)) {
state.updatedAt = new Date().toISOString();
persistCampaignState(state);
}
return cloneReport(state.firstBattleReport);
}
const campaignBond = state.bonds.find((candidate) => candidate.id === bondId);
@@ -690,6 +691,7 @@ export function applyCampBondExp(dialogueId: string, bondId: string, amount: num
return undefined;
}
syncCompletionFlag(state.completedCampDialogues, state.firstBattleReport.completedCampDialogues, dialogueId);
advanceBond(campaignBond, amount);
reportBond.level = campaignBond.level;
reportBond.exp = campaignBond.exp;
@@ -709,14 +711,15 @@ export function applyCampVisitReward(
return undefined;
}
if (state.completedCampVisits.includes(visitId)) {
if (hasCompletionFlag(state.completedCampVisits, state.firstBattleReport.completedCampVisits, visitId)) {
if (syncCompletionFlag(state.completedCampVisits, state.firstBattleReport.completedCampVisits, visitId)) {
state.updatedAt = new Date().toISOString();
persistCampaignState(state);
}
return cloneCampaignState(state);
}
state.completedCampVisits.push(visitId);
if (!state.firstBattleReport.completedCampVisits.includes(visitId)) {
state.firstBattleReport.completedCampVisits.push(visitId);
}
syncCompletionFlag(state.completedCampVisits, state.firstBattleReport.completedCampVisits, visitId);
if (reward.bondId && reward.bondExp && reward.bondExp > 0) {
const campaignBond = state.bonds.find((candidate) => candidate.id === reward.bondId);
@@ -744,6 +747,23 @@ export function applyCampVisitReward(
return cloneCampaignState(state);
}
function hasCompletionFlag(stateFlags: string[], reportFlags: string[], flagId: string) {
return stateFlags.includes(flagId) || reportFlags.includes(flagId);
}
function syncCompletionFlag(stateFlags: string[], reportFlags: string[], flagId: string) {
let changed = false;
if (!stateFlags.includes(flagId)) {
stateFlags.push(flagId);
changed = true;
}
if (!reportFlags.includes(flagId)) {
reportFlags.push(flagId);
changed = true;
}
return changed;
}
export function ensureCampaignRosterUnits(units: UnitData[], bonds: BattleBond[] = []) {
const state = ensureCampaignState();
let changed = false;
@@ -1451,6 +1471,7 @@ function cloneCampaignState(state: CampaignState): CampaignState {
function cloneReport(report: FirstBattleReport): FirstBattleReport {
const cloned = JSON.parse(JSON.stringify(report)) as FirstBattleReport;
cloned.completedCampDialogues = [...new Set(cloned.completedCampDialogues ?? [])];
cloned.completedCampVisits = [...new Set(cloned.completedCampVisits ?? [])];
if (cloned.campaignRewards) {
cloned.campaignRewards = cloneCampaignRewardSnapshot(cloned.campaignRewards);