Tune early objective routing

This commit is contained in:
2026-07-05 22:29:02 +09:00
parent 6b8ffb4762
commit dab61d90c7
2 changed files with 45 additions and 17 deletions

View File

@@ -109,14 +109,14 @@ const earlyCampaignBattles = [
no: 6,
id: 'sixth-battle-jieqiao-relief',
selected: coreBrothers,
targets: ['jieqiao-leader-qu-yi'],
targets: ['jieqiao-guard-a', 'jieqiao-guard-b', 'jieqiao-archer-c', 'jieqiao-leader-qu-yi'],
protected: ['liu-bei']
},
{
no: 7,
id: 'seventh-battle-xuzhou-rescue',
selected: coreBrothers,
targets: ['xuzhou-leader-xiahou-dun'],
targets: ['xuzhou-guard-a', 'xuzhou-guard-b', 'xuzhou-archer-c', 'xuzhou-leader-xiahou-dun'],
protected: ['liu-bei']
},
{
@@ -1060,6 +1060,21 @@ async function playBattleWithoutDebugVictory(page, battle) {
scene.updateMiniMap?.();
};
const resolveOutcome = () => scene.resolveBattleOutcomeIfNeeded?.();
const activeSecureObjectives = () =>
(state().objectives ?? []).filter((objective) => {
return objective.category === 'bonus' && objective.status !== 'done' && objective.targetTile && objective.id !== 'quick';
});
const objectiveDistance = (unitOrTile, objective) =>
Math.abs(unitOrTile.x - objective.targetTile.x) + Math.abs(unitOrTile.y - objective.targetTile.y);
const objectiveRadius = (objective) => objective.targetTile.radius ?? 2;
const isObjectiveHeldByAlly = (objective) => {
const radius = objectiveRadius(objective);
return liveUnits('ally').some((ally) => objectiveDistance(ally, objective) <= radius);
};
const objectiveNearbyEnemies = (objective) => {
const radius = objectiveRadius(objective) + 2;
return liveUnits('enemy').filter((enemy) => objectiveDistance(enemy, objective) <= radius);
};
function withUnitAt(unit, tile, callback) {
const original = { x: unit.x, y: unit.y };
@@ -1074,19 +1089,21 @@ async function playBattleWithoutDebugVictory(page, battle) {
}
function priorityForTarget(enemy) {
const objective = activeSecureObjectives()[0];
const objectivePriority = objective && objectiveDistance(enemy, objective) <= objectiveRadius(objective) + 2 ? 1800 : 0;
if (enemy.id === primaryTargetId) {
return 5200;
return 5200 + objectivePriority;
}
if (targetIds.has(enemy.id)) {
return 3400;
return 3400 + objectivePriority;
}
if (enemy.id.includes('leader')) {
return 1200;
return 1200 + objectivePriority;
}
if (enemy.id.includes('officer')) {
return 720;
return 720 + objectivePriority;
}
return 0;
return objectivePriority;
}
function focusTarget(unit) {
@@ -1100,6 +1117,17 @@ async function playBattleWithoutDebugVictory(page, battle) {
};
const progressEnemies = enemies.filter(canProgressTo);
const nearestEnemy = progressEnemies.sort((a, b) => distance(unit, a) - distance(unit, b) || priorityForTarget(b) - priorityForTarget(a))[0];
const objective = activeSecureObjectives()[0];
if (objective) {
const objectiveEnemies = objectiveNearbyEnemies(objective).filter(canProgressTo);
if (objectiveEnemies.length > 0) {
return objectiveEnemies.sort((a, b) => {
const aLeaderPenalty = a.id === primaryTargetId ? 4 : 0;
const bLeaderPenalty = b.id === primaryTargetId ? 4 : 0;
return objectiveDistance(a, objective) + aLeaderPenalty - (objectiveDistance(b, objective) + bLeaderPenalty) || distance(unit, a) - distance(unit, b);
})[0];
}
}
const aliveTargets = targets.map((targetId) => unitRef(targetId)).filter((target) => target && target.hp > 0);
if (aliveTargets.length > 0) {
const reachableTargets = aliveTargets.filter(canProgressTo);