Apply per-officer reserve drill focus
This commit is contained in:
@@ -184,6 +184,33 @@ try {
|
||||
completedCampVisits: [],
|
||||
createdAt: '2026-07-03T09:00:00.000Z'
|
||||
};
|
||||
const reserveDrillTemplate = campaignRecruitUnits.find((unit) => unit.id === 'jian-yong');
|
||||
assert(reserveDrillTemplate, 'Expected Jian Yong recruit template to exist for reserve drill assignment checks');
|
||||
storage.clear();
|
||||
storage.set(
|
||||
campaignStorageKey,
|
||||
JSON.stringify({
|
||||
version: 1,
|
||||
updatedAt: '2026-07-03T12:10:00.000Z',
|
||||
step: 'first-camp',
|
||||
roster: [reserveDrillTemplate],
|
||||
reserveTrainingFocus: 'balanced',
|
||||
reserveTrainingAssignments: { [reserveDrillTemplate.id]: 'class-practice' }
|
||||
})
|
||||
);
|
||||
loadCampaignState();
|
||||
setFirstBattleReport(firstBattleReport);
|
||||
const individualizedReserveTraining = getCampaignState();
|
||||
const individualizedReserveAward = individualizedReserveTraining.battleHistory[firstScenario.id]?.reserveTraining?.find(
|
||||
(entry) => entry.unitId === reserveDrillTemplate.id
|
||||
);
|
||||
assert(
|
||||
individualizedReserveAward?.focusId === 'class-practice' &&
|
||||
individualizedReserveAward.expGained === 4 &&
|
||||
individualizedReserveAward.equipmentExpGained === 5,
|
||||
`Expected per-officer reserve drill assignments to override the global focus during battle settlement: ${JSON.stringify(individualizedReserveTraining)}`
|
||||
);
|
||||
resetCampaignState();
|
||||
setFirstBattleReport(firstBattleReport);
|
||||
setFirstBattleReport(firstBattleReport);
|
||||
const repeatedSettlement = getCampaignState();
|
||||
|
||||
@@ -710,7 +710,8 @@ export function setFirstBattleReport(report: FirstBattleReport) {
|
||||
state.roster,
|
||||
state.bonds,
|
||||
reportClone.units.filter((unit) => unit.faction === 'ally'),
|
||||
state.reserveTrainingFocus
|
||||
state.reserveTrainingFocus,
|
||||
state.reserveTrainingAssignments
|
||||
);
|
||||
if (!previousSettlement && reportClone.outcome === 'victory') {
|
||||
reportClone.bonds = state.bonds.map(cloneBondSnapshot);
|
||||
@@ -1624,31 +1625,39 @@ function applyReserveTrainingProgress(
|
||||
roster: UnitData[],
|
||||
bonds: CampBondSnapshot[],
|
||||
deployedUnits: UnitData[],
|
||||
focusId: CampaignReserveTrainingFocusId
|
||||
focusId: CampaignReserveTrainingFocusId,
|
||||
reserveTrainingAssignments: CampaignReserveTrainingAssignments = {}
|
||||
): CampaignReserveTrainingSnapshot[] {
|
||||
const focus = reserveTrainingFocusDefinition(focusId);
|
||||
const deployedIds = new Set(deployedUnits.map((unit) => unit.id));
|
||||
const reserveUnits = roster.filter((unit) => unit.faction === 'ally' && !deployedIds.has(unit.id));
|
||||
const reserveIds = new Set(reserveUnits.map((unit) => unit.id));
|
||||
const focusByUnitId = new Map(
|
||||
reserveUnits.map((unit) => [unit.id, reserveTrainingFocusDefinition(reserveTrainingAssignments[unit.id] ?? focus.id)])
|
||||
);
|
||||
const bondExpByUnit = new Map<string, number>();
|
||||
|
||||
if (focus.bondExpGained > 0 && reserveIds.size > 0) {
|
||||
if (reserveIds.size > 0) {
|
||||
bonds.forEach((bond) => {
|
||||
const reservePartners = bond.unitIds.filter((unitId) => reserveIds.has(unitId));
|
||||
const reservePartners = bond.unitIds
|
||||
.filter((unitId) => reserveIds.has(unitId))
|
||||
.map((unitId) => ({ unitId, bondExpGained: focusByUnitId.get(unitId)?.bondExpGained ?? 0 }))
|
||||
.filter((partner) => partner.bondExpGained > 0);
|
||||
if (reservePartners.length === 0) {
|
||||
return;
|
||||
}
|
||||
advanceBond(bond, focus.bondExpGained);
|
||||
reservePartners.forEach((unitId) => {
|
||||
bondExpByUnit.set(unitId, (bondExpByUnit.get(unitId) ?? 0) + focus.bondExpGained);
|
||||
advanceBond(bond, Math.max(...reservePartners.map((partner) => partner.bondExpGained)));
|
||||
reservePartners.forEach((partner) => {
|
||||
bondExpByUnit.set(partner.unitId, (bondExpByUnit.get(partner.unitId) ?? 0) + partner.bondExpGained);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return reserveUnits
|
||||
.map((unit) => {
|
||||
const expGained = focus.expGained;
|
||||
const equipmentExpGained = focus.equipmentExpGained;
|
||||
const unitFocus = focusByUnitId.get(unit.id) ?? focus;
|
||||
const expGained = unitFocus.expGained;
|
||||
const equipmentExpGained = unitFocus.equipmentExpGained;
|
||||
advanceUnitExp(unit, expGained);
|
||||
advanceReserveEquipment(unit, equipmentExpGained);
|
||||
return {
|
||||
@@ -1657,8 +1666,8 @@ function applyReserveTrainingProgress(
|
||||
expGained,
|
||||
equipmentExpGained,
|
||||
bondExpGained: bondExpByUnit.get(unit.id) ?? 0,
|
||||
focusId: focus.id,
|
||||
focusLabel: focus.label,
|
||||
focusId: unitFocus.id,
|
||||
focusLabel: unitFocus.label,
|
||||
level: unit.level,
|
||||
exp: unit.exp
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user