Apply per-officer reserve drill focus
This commit is contained in:
@@ -184,6 +184,33 @@ try {
|
|||||||
completedCampVisits: [],
|
completedCampVisits: [],
|
||||||
createdAt: '2026-07-03T09:00:00.000Z'
|
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);
|
||||||
setFirstBattleReport(firstBattleReport);
|
setFirstBattleReport(firstBattleReport);
|
||||||
const repeatedSettlement = getCampaignState();
|
const repeatedSettlement = getCampaignState();
|
||||||
|
|||||||
@@ -710,7 +710,8 @@ export function setFirstBattleReport(report: FirstBattleReport) {
|
|||||||
state.roster,
|
state.roster,
|
||||||
state.bonds,
|
state.bonds,
|
||||||
reportClone.units.filter((unit) => unit.faction === 'ally'),
|
reportClone.units.filter((unit) => unit.faction === 'ally'),
|
||||||
state.reserveTrainingFocus
|
state.reserveTrainingFocus,
|
||||||
|
state.reserveTrainingAssignments
|
||||||
);
|
);
|
||||||
if (!previousSettlement && reportClone.outcome === 'victory') {
|
if (!previousSettlement && reportClone.outcome === 'victory') {
|
||||||
reportClone.bonds = state.bonds.map(cloneBondSnapshot);
|
reportClone.bonds = state.bonds.map(cloneBondSnapshot);
|
||||||
@@ -1624,31 +1625,39 @@ function applyReserveTrainingProgress(
|
|||||||
roster: UnitData[],
|
roster: UnitData[],
|
||||||
bonds: CampBondSnapshot[],
|
bonds: CampBondSnapshot[],
|
||||||
deployedUnits: UnitData[],
|
deployedUnits: UnitData[],
|
||||||
focusId: CampaignReserveTrainingFocusId
|
focusId: CampaignReserveTrainingFocusId,
|
||||||
|
reserveTrainingAssignments: CampaignReserveTrainingAssignments = {}
|
||||||
): CampaignReserveTrainingSnapshot[] {
|
): CampaignReserveTrainingSnapshot[] {
|
||||||
const focus = reserveTrainingFocusDefinition(focusId);
|
const focus = reserveTrainingFocusDefinition(focusId);
|
||||||
const deployedIds = new Set(deployedUnits.map((unit) => unit.id));
|
const deployedIds = new Set(deployedUnits.map((unit) => unit.id));
|
||||||
const reserveUnits = roster.filter((unit) => unit.faction === 'ally' && !deployedIds.has(unit.id));
|
const reserveUnits = roster.filter((unit) => unit.faction === 'ally' && !deployedIds.has(unit.id));
|
||||||
const reserveIds = new Set(reserveUnits.map((unit) => 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>();
|
const bondExpByUnit = new Map<string, number>();
|
||||||
|
|
||||||
if (focus.bondExpGained > 0 && reserveIds.size > 0) {
|
if (reserveIds.size > 0) {
|
||||||
bonds.forEach((bond) => {
|
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) {
|
if (reservePartners.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
advanceBond(bond, focus.bondExpGained);
|
advanceBond(bond, Math.max(...reservePartners.map((partner) => partner.bondExpGained)));
|
||||||
reservePartners.forEach((unitId) => {
|
reservePartners.forEach((partner) => {
|
||||||
bondExpByUnit.set(unitId, (bondExpByUnit.get(unitId) ?? 0) + focus.bondExpGained);
|
bondExpByUnit.set(partner.unitId, (bondExpByUnit.get(partner.unitId) ?? 0) + partner.bondExpGained);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return reserveUnits
|
return reserveUnits
|
||||||
.map((unit) => {
|
.map((unit) => {
|
||||||
const expGained = focus.expGained;
|
const unitFocus = focusByUnitId.get(unit.id) ?? focus;
|
||||||
const equipmentExpGained = focus.equipmentExpGained;
|
const expGained = unitFocus.expGained;
|
||||||
|
const equipmentExpGained = unitFocus.equipmentExpGained;
|
||||||
advanceUnitExp(unit, expGained);
|
advanceUnitExp(unit, expGained);
|
||||||
advanceReserveEquipment(unit, equipmentExpGained);
|
advanceReserveEquipment(unit, equipmentExpGained);
|
||||||
return {
|
return {
|
||||||
@@ -1657,8 +1666,8 @@ function applyReserveTrainingProgress(
|
|||||||
expGained,
|
expGained,
|
||||||
equipmentExpGained,
|
equipmentExpGained,
|
||||||
bondExpGained: bondExpByUnit.get(unit.id) ?? 0,
|
bondExpGained: bondExpByUnit.get(unit.id) ?? 0,
|
||||||
focusId: focus.id,
|
focusId: unitFocus.id,
|
||||||
focusLabel: focus.label,
|
focusLabel: unitFocus.label,
|
||||||
level: unit.level,
|
level: unit.level,
|
||||||
exp: unit.exp
|
exp: unit.exp
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user