Add Liu Biao camp visit events
This commit is contained in:
@@ -33,6 +33,7 @@ export type FirstBattleReport = {
|
||||
mvp?: CampMvpSnapshot;
|
||||
itemRewards: string[];
|
||||
completedCampDialogues: string[];
|
||||
completedCampVisits: string[];
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
@@ -114,6 +115,7 @@ export type CampaignState = {
|
||||
inventory: Record<string, number>;
|
||||
selectedSortieUnitIds: string[];
|
||||
completedCampDialogues: string[];
|
||||
completedCampVisits: string[];
|
||||
battleHistory: Record<string, CampaignBattleSettlement>;
|
||||
latestBattleId?: string;
|
||||
firstBattleReport?: FirstBattleReport;
|
||||
@@ -164,6 +166,7 @@ export function createInitialCampaignState(): CampaignState {
|
||||
inventory: {},
|
||||
selectedSortieUnitIds: [],
|
||||
completedCampDialogues: [],
|
||||
completedCampVisits: [],
|
||||
battleHistory: {}
|
||||
};
|
||||
}
|
||||
@@ -244,8 +247,11 @@ export function setFirstBattleReport(report: FirstBattleReport) {
|
||||
const previousSettlement = state.battleHistory[battleId];
|
||||
const completedCampDialogues =
|
||||
battleId === 'first-battle-zhuo-commandery' ? [...reportClone.completedCampDialogues] : [...state.completedCampDialogues];
|
||||
const completedCampVisits =
|
||||
battleId === 'first-battle-zhuo-commandery' ? [...(reportClone.completedCampVisits ?? [])] : [...state.completedCampVisits];
|
||||
|
||||
reportClone.completedCampDialogues = completedCampDialogues;
|
||||
reportClone.completedCampVisits = completedCampVisits;
|
||||
state.firstBattleReport = reportClone;
|
||||
const stepRule = campaignBattleSteps[battleId] ?? campaignBattleSteps['first-battle-zhuo-commandery'];
|
||||
const victoryStep: CampaignStep = stepRule.victory;
|
||||
@@ -255,6 +261,7 @@ export function setFirstBattleReport(report: FirstBattleReport) {
|
||||
state.roster = mergeRosterProgress(state.roster, reportClone.units.filter((unit) => unit.faction === 'ally'));
|
||||
state.bonds = reportClone.bonds.map(cloneBondSnapshot);
|
||||
state.completedCampDialogues = completedCampDialogues;
|
||||
state.completedCampVisits = completedCampVisits;
|
||||
state.inventory = applyRewardDelta(state.inventory, previousSettlement?.itemRewards ?? [], -1);
|
||||
state.inventory = applyRewardDelta(state.inventory, reportClone.itemRewards, 1);
|
||||
state.battleHistory[battleId] = createBattleSettlement(reportClone);
|
||||
@@ -298,6 +305,50 @@ export function applyCampBondExp(dialogueId: string, bondId: string, amount: num
|
||||
return cloneReport(state.firstBattleReport);
|
||||
}
|
||||
|
||||
export function applyCampVisitReward(
|
||||
visitId: string,
|
||||
reward: { bondId?: string; bondExp?: number; gold?: number; itemRewards?: string[] }
|
||||
) {
|
||||
const state = ensureCampaignState();
|
||||
if (!state.firstBattleReport) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (state.completedCampVisits.includes(visitId)) {
|
||||
return cloneCampaignState(state);
|
||||
}
|
||||
|
||||
state.completedCampVisits.push(visitId);
|
||||
if (!state.firstBattleReport.completedCampVisits.includes(visitId)) {
|
||||
state.firstBattleReport.completedCampVisits.push(visitId);
|
||||
}
|
||||
|
||||
if (reward.bondId && reward.bondExp && reward.bondExp > 0) {
|
||||
const campaignBond = state.bonds.find((candidate) => candidate.id === reward.bondId);
|
||||
const reportBond = state.firstBattleReport.bonds.find((candidate) => candidate.id === reward.bondId);
|
||||
if (campaignBond) {
|
||||
advanceBond(campaignBond, reward.bondExp);
|
||||
if (reportBond) {
|
||||
reportBond.level = campaignBond.level;
|
||||
reportBond.exp = campaignBond.exp;
|
||||
reportBond.battleExp = campaignBond.battleExp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reward.gold && reward.gold > 0) {
|
||||
state.gold += reward.gold;
|
||||
}
|
||||
|
||||
if (reward.itemRewards?.length) {
|
||||
state.inventory = applyRewardDelta(state.inventory, reward.itemRewards, 1);
|
||||
}
|
||||
|
||||
state.updatedAt = new Date().toISOString();
|
||||
persistCampaignState(state);
|
||||
return cloneCampaignState(state);
|
||||
}
|
||||
|
||||
export function ensureCampaignRosterUnits(units: UnitData[], bonds: BattleBond[] = []) {
|
||||
const state = ensureCampaignState();
|
||||
let changed = false;
|
||||
@@ -368,6 +419,7 @@ function normalizeCampaignState(state: CampaignState): CampaignState {
|
||||
normalized.roster = (normalized.roster ?? []).map(cloneUnit);
|
||||
normalized.bonds = (normalized.bonds ?? []).map(cloneBondSnapshot);
|
||||
normalized.completedCampDialogues = [...new Set(normalized.completedCampDialogues ?? [])];
|
||||
normalized.completedCampVisits = [...new Set(normalized.completedCampVisits ?? [])];
|
||||
normalized.inventory = { ...(normalized.inventory ?? {}) };
|
||||
normalized.selectedSortieUnitIds = [...new Set(normalized.selectedSortieUnitIds ?? [])];
|
||||
normalized.battleHistory = normalized.battleHistory ?? {};
|
||||
@@ -501,7 +553,9 @@ function cloneCampaignState(state: CampaignState): CampaignState {
|
||||
}
|
||||
|
||||
function cloneReport(report: FirstBattleReport): FirstBattleReport {
|
||||
return JSON.parse(JSON.stringify(report)) as FirstBattleReport;
|
||||
const cloned = JSON.parse(JSON.stringify(report)) as FirstBattleReport;
|
||||
cloned.completedCampVisits = [...new Set(cloned.completedCampVisits ?? [])];
|
||||
return cloned;
|
||||
}
|
||||
|
||||
function cloneUnit(unit: UnitData): UnitData {
|
||||
|
||||
Reference in New Issue
Block a user