QA and tune refuge campaign battles

This commit is contained in:
2026-06-27 12:21:14 +09:00
parent 2ebd5fc6c3
commit 7dd437c45d
5 changed files with 258 additions and 162 deletions

View File

@@ -8,6 +8,11 @@ const pnpmCommand = process.env.PNPM_CMD ?? 'pnpm';
const coreBrothers = ['liu-bei', 'guan-yu', 'zhang-fei']; const coreBrothers = ['liu-bei', 'guan-yu', 'zhang-fei'];
const xuzhouFullSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'jian-yong', 'mi-zhu']; const xuzhouFullSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'jian-yong', 'mi-zhu'];
const caoRefugeSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'jian-yong', 'mi-zhu'];
const sunQianSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'jian-yong', 'mi-zhu', 'sun-qian'];
const liuBiaoSortie = ['liu-bei', 'guan-yu', 'zhang-fei', 'zhao-yun', 'sun-qian', 'mi-zhu'];
const zhugeFirstSortie = ['liu-bei', 'zhuge-liang', 'zhao-yun', 'guan-yu', 'zhang-fei', 'sun-qian'];
const envoySortie = ['liu-bei', 'zhuge-liang', 'sun-qian', 'zhao-yun', 'guan-yu', 'zhang-fei'];
const earlyCampaignBattles = [ const earlyCampaignBattles = [
{ no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-leader'], protected: ['liu-bei'] }, { no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-leader'], protected: ['liu-bei'] },
@@ -76,6 +81,79 @@ const earlyCampaignBattles = [
} }
]; ];
const refugeCampaignBattles = [
{
no: 11,
id: 'eleventh-battle-xudu-refuge-road',
selected: caoRefugeSortie,
targets: ['xudu-road-leader-ji-ling'],
protected: ['liu-bei']
},
{
no: 12,
id: 'twelfth-battle-xiapi-outer-siege',
selected: caoRefugeSortie,
targets: ['xiapi-leader-zhang-liao'],
protected: ['liu-bei']
},
{
no: 13,
id: 'thirteenth-battle-xiapi-final',
selected: caoRefugeSortie,
targets: ['xiapi-final-leader-lu-bu'],
protected: ['liu-bei']
},
{
no: 14,
id: 'fourteenth-battle-cao-break',
selected: sunQianSortie,
targets: ['cao-break-leader-che-zhou'],
protected: ['liu-bei']
},
{
no: 15,
id: 'fifteenth-battle-yuan-refuge-road',
selected: sunQianSortie,
targets: ['yuan-refuge-leader-cai-yang'],
protected: ['liu-bei']
},
{
no: 16,
id: 'sixteenth-battle-liu-biao-refuge',
selected: liuBiaoSortie,
targets: ['liu-biao-road-leader-cao-ren'],
protected: ['liu-bei']
},
{
no: 17,
id: 'seventeenth-battle-wolong-visit-road',
selected: liuBiaoSortie,
targets: ['wolong-road-leader-cai-xun'],
protected: ['liu-bei']
},
{
no: 18,
id: 'eighteenth-battle-bowang-ambush',
selected: zhugeFirstSortie,
targets: ['bowang-leader-xiahou-dun'],
protected: ['liu-bei']
},
{
no: 19,
id: 'nineteenth-battle-changban-refuge',
selected: zhugeFirstSortie,
targets: ['changban-leader-cao-chun'],
protected: ['liu-bei', 'zhao-yun']
},
{
no: 20,
id: 'twentieth-battle-jiangdong-envoy',
selected: envoySortie,
targets: ['envoy-road-leader-wen-pin'],
protected: ['liu-bei', 'zhuge-liang', 'sun-qian']
}
];
const allRepresentativeBattles = [ const allRepresentativeBattles = [
{ no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-leader'], protected: ['liu-bei'] }, { no: 1, id: 'first-battle-zhuo-commandery', selected: [], targets: ['rebel-leader'], protected: ['liu-bei'] },
{ {
@@ -138,7 +216,8 @@ const allRepresentativeBattles = [
const qaBattleSets = { const qaBattleSets = {
representative: allRepresentativeBattles, representative: allRepresentativeBattles,
early: earlyCampaignBattles early: earlyCampaignBattles,
refuge: refugeCampaignBattles
}; };
const qaSetName = process.env.QA_SET ?? 'representative'; const qaSetName = process.env.QA_SET ?? 'representative';
const qaBattleSet = qaBattleSets[qaSetName]; const qaBattleSet = qaBattleSets[qaSetName];
@@ -402,7 +481,14 @@ async function playBattleWithoutDebugVictory(page, battle) {
if (vanguards.length === 0) { if (vanguards.length === 0) {
return unit.hp >= Math.ceil(unit.maxHp * 0.8); return unit.hp >= Math.ceil(unit.maxHp * 0.8);
} }
return Boolean(vanguardInPosition && focus && targetIds.has(focus.id) && focus.hp <= Math.ceil(focus.maxHp * 0.3)); const targetPressThreshold = protectedIds.size > 1 ? 0.12 : 0.3;
return Boolean(
vanguardInPosition &&
focus &&
targetIds.has(focus.id) &&
focus.hp <= Math.ceil(focus.maxHp * targetPressThreshold) &&
unit.hp >= Math.ceil(unit.maxHp * 0.7)
);
} }
function canTakeAttack(unit, attack, threat = protectedIds.has(unit.id) ? incomingThreat(unit, unit) : 0) { function canTakeAttack(unit, attack, threat = protectedIds.has(unit.id) ? incomingThreat(unit, unit) : 0) {
@@ -412,7 +498,16 @@ async function playBattleWithoutDebugVictory(page, battle) {
const pressProtected = shouldPressProtected(unit); const pressProtected = shouldPressProtected(unit);
const isTarget = targetIds.has(attack.target.id); const isTarget = targetIds.has(attack.target.id);
const kill = attack.preview.damage >= attack.target.hp; const kill = attack.preview.damage >= attack.target.hp;
if (isTarget && (threat <= Math.floor(unit.hp * (pressProtected ? 0.7 : 0.42)) || unit.hp >= Math.ceil(unit.maxHp * 0.8))) { if (protectedIds.size > 1 && !isTarget && unit.id === 'sun-qian') {
return kill && liveUnits('enemy').length <= 3 && threat <= Math.floor(unit.hp * 0.12);
}
if (protectedIds.size > 1 && !isTarget) {
return unit.hp >= Math.ceil(unit.maxHp * 0.75) && threat <= Math.floor(unit.hp * 0.22);
}
if (isTarget && (pressProtected || kill) && threat <= Math.floor(unit.hp * (pressProtected ? 0.7 : 0.42))) {
return true;
}
if (isTarget && protectedIds.size === 1 && threat <= Math.floor(unit.hp * 0.3)) {
return true; return true;
} }
if (kill && threat <= Math.floor(unit.hp * (pressProtected ? 0.5 : 0.32))) { if (kill && threat <= Math.floor(unit.hp * (pressProtected ? 0.5 : 0.32))) {
@@ -489,10 +584,11 @@ async function playBattleWithoutDebugVictory(page, battle) {
const focus = attack?.target ?? focusTarget(unit); const focus = attack?.target ?? focusTarget(unit);
const isProtected = protectedIds.has(unit.id); const isProtected = protectedIds.has(unit.id);
const shouldPress = isProtected && shouldPressProtected(unit); const shouldPress = isProtected && shouldPressProtected(unit);
const approach = focus ? -distance(unit, focus) * (isProtected ? (shouldPress ? 42 : 5) : 36) : 0;
const attackScore = attack ? attack.score + (targetIds.has(attack.target.id) ? 2400 : 1350) : approach;
const allySupport = liveUnits('ally').filter((ally) => ally.id !== unit.id && distance(unit, ally) <= 2).length * 16;
const threat = incomingThreat(unit, tile); const threat = incomingThreat(unit, tile);
const canUseAttack = attack && (!isProtected || canTakeAttack(unit, attack, threat));
const approach = focus ? -distance(unit, focus) * (isProtected ? (shouldPress ? 42 : 5) : 36) : 0;
const attackScore = canUseAttack ? attack.score + (targetIds.has(attack.target.id) ? 2400 : 1350) : approach;
const allySupport = liveUnits('ally').filter((ally) => ally.id !== unit.id && distance(unit, ally) <= 2).length * 16;
const nearestEnemyDistance = liveUnits('enemy') const nearestEnemyDistance = liveUnits('enemy')
.map((enemy) => distance(unit, enemy)) .map((enemy) => distance(unit, enemy))
.sort((a, b) => a - b)[0] ?? 99; .sort((a, b) => a - b)[0] ?? 99;

View File

@@ -1164,7 +1164,7 @@ export const fifteenthBattleScenario: BattleScenarioDefinition = {
} }
], ],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }], defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }],
itemRewards: ['콩 6', '상처약 3', '탁주 2', '원소 접선 문서 +1'], itemRewards: ['콩 6', '상처약 4', '탁주 2', '원소 접선 문서 +1'],
victoryPages: fifteenthBattleVictoryPages, victoryPages: fifteenthBattleVictoryPages,
nextCampScene: 'CampScene' nextCampScene: 'CampScene'
}; };
@@ -1217,7 +1217,7 @@ export const sixteenthBattleScenario: BattleScenarioDefinition = {
} }
], ],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }], defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }],
itemRewards: ['콩 6', '상처약 4', '탁주 2', '형주 접선 문서 +1'], itemRewards: ['콩 6', '상처약 5', '탁주 2', '형주 접선 문서 +1'],
victoryPages: sixteenthBattleVictoryPages, victoryPages: sixteenthBattleVictoryPages,
nextCampScene: 'CampScene' nextCampScene: 'CampScene'
}; };
@@ -1270,7 +1270,7 @@ export const seventeenthBattleScenario: BattleScenarioDefinition = {
} }
], ],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }], defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }],
itemRewards: ['콩 6', '상처약 4', '탁주 2', '와룡의 서찰 +1'], itemRewards: ['콩 6', '상처약 5', '탁주 2', '와룡의 서찰 +1'],
victoryPages: seventeenthBattleVictoryPages, victoryPages: seventeenthBattleVictoryPages,
nextCampScene: 'CampScene' nextCampScene: 'CampScene'
}; };
@@ -1406,7 +1406,7 @@ export const twentiethBattleScenario: BattleScenarioDefinition = {
bonds: twentiethBattleBonds, bonds: twentiethBattleBonds,
mapTextureKey: 'battle-map-twentieth', mapTextureKey: 'battle-map-twentieth',
leaderUnitId: 'envoy-road-leader-wen-pin', leaderUnitId: 'envoy-road-leader-wen-pin',
quickVictoryTurnLimit: 29, quickVictoryTurnLimit: 31,
baseVictoryGold: 2380, baseVictoryGold: 2380,
objectives: [ objectives: [
{ {
@@ -1440,9 +1440,9 @@ export const twentiethBattleScenario: BattleScenarioDefinition = {
{ {
id: 'quick', id: 'quick',
kind: 'quick-victory', kind: 'quick-victory',
label: '29턴 이내 승리', label: '31턴 이내 승리',
rewardGold: 640, rewardGold: 640,
maxTurn: 29 maxTurn: 31
} }
], ],
defeatConditions: [ defeatConditions: [
@@ -1450,7 +1450,7 @@ export const twentiethBattleScenario: BattleScenarioDefinition = {
{ kind: 'unit-defeated', unitId: 'zhuge-liang' }, { kind: 'unit-defeated', unitId: 'zhuge-liang' },
{ kind: 'unit-defeated', unitId: 'sun-qian' } { kind: 'unit-defeated', unitId: 'sun-qian' }
], ],
itemRewards: ['콩 8', '상처약 5', '탁주 3', '강동 사절 문서 +1', '화공 논의 +1'], itemRewards: ['콩 8', '상처약 6', '탁주 3', '강동 사절 문서 +1', '화공 논의 +1'],
victoryPages: twentiethBattleVictoryPages, victoryPages: twentiethBattleVictoryPages,
nextCampScene: 'CampScene' nextCampScene: 'CampScene'
}; };

View File

@@ -9008,9 +9008,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'bandit', classKey: 'bandit',
level: 15, level: 15,
exp: 92, exp: 92,
hp: 54, hp: 48,
maxHp: 54, maxHp: 54,
attack: 20, attack: 18,
move: 4, move: 4,
stats: { might: 90, intelligence: 62, leadership: 68, agility: 88, luck: 62 }, stats: { might: 90, intelligence: 62, leadership: 68, agility: 88, luck: 62 },
equipment: { equipment: {
@@ -9029,9 +9029,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'bandit', classKey: 'bandit',
level: 15, level: 15,
exp: 92, exp: 92,
hp: 54, hp: 48,
maxHp: 54, maxHp: 54,
attack: 20, attack: 18,
move: 4, move: 4,
stats: { might: 90, intelligence: 62, leadership: 68, agility: 88, luck: 62 }, stats: { might: 90, intelligence: 62, leadership: 68, agility: 88, luck: 62 },
equipment: { equipment: {
@@ -9050,9 +9050,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 15, level: 15,
exp: 94, exp: 94,
hp: 62, hp: 54,
maxHp: 62, maxHp: 62,
attack: 20, attack: 18,
move: 3, move: 3,
stats: { might: 92, intelligence: 62, leadership: 80, agility: 70, luck: 61 }, stats: { might: 92, intelligence: 62, leadership: 80, agility: 70, luck: 61 },
equipment: { equipment: {
@@ -9071,9 +9071,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 15, level: 15,
exp: 94, exp: 94,
hp: 62, hp: 54,
maxHp: 62, maxHp: 62,
attack: 20, attack: 18,
move: 3, move: 3,
stats: { might: 92, intelligence: 62, leadership: 80, agility: 70, luck: 61 }, stats: { might: 92, intelligence: 62, leadership: 80, agility: 70, luck: 61 },
equipment: { equipment: {
@@ -9092,9 +9092,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 16, level: 16,
exp: 96, exp: 96,
hp: 64, hp: 54,
maxHp: 64, maxHp: 64,
attack: 21, attack: 18,
move: 3, move: 3,
stats: { might: 94, intelligence: 63, leadership: 82, agility: 71, luck: 62 }, stats: { might: 94, intelligence: 63, leadership: 82, agility: 71, luck: 62 },
equipment: { equipment: {
@@ -9113,9 +9113,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 16, level: 16,
exp: 96, exp: 96,
hp: 64, hp: 54,
maxHp: 64, maxHp: 64,
attack: 21, attack: 18,
move: 3, move: 3,
stats: { might: 94, intelligence: 63, leadership: 82, agility: 71, luck: 62 }, stats: { might: 94, intelligence: 63, leadership: 82, agility: 71, luck: 62 },
equipment: { equipment: {
@@ -9134,9 +9134,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 15, level: 15,
exp: 94, exp: 94,
hp: 50, hp: 42,
maxHp: 50, maxHp: 50,
attack: 20, attack: 18,
move: 3, move: 3,
stats: { might: 83, intelligence: 74, leadership: 72, agility: 84, luck: 62 }, stats: { might: 83, intelligence: 74, leadership: 72, agility: 84, luck: 62 },
equipment: { equipment: {
@@ -9155,9 +9155,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 15, level: 15,
exp: 94, exp: 94,
hp: 50, hp: 42,
maxHp: 50, maxHp: 50,
attack: 20, attack: 18,
move: 3, move: 3,
stats: { might: 83, intelligence: 74, leadership: 72, agility: 84, luck: 62 }, stats: { might: 83, intelligence: 74, leadership: 72, agility: 84, luck: 62 },
equipment: { equipment: {
@@ -9176,9 +9176,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 16, level: 16,
exp: 96, exp: 96,
hp: 52, hp: 32,
maxHp: 52, maxHp: 52,
attack: 21, attack: 16,
move: 3, move: 3,
stats: { might: 84, intelligence: 75, leadership: 73, agility: 85, luck: 63 }, stats: { might: 84, intelligence: 75, leadership: 73, agility: 85, luck: 63 },
equipment: { equipment: {
@@ -9260,9 +9260,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 16, level: 16,
exp: 98, exp: 98,
hp: 70, hp: 54,
maxHp: 70, maxHp: 70,
attack: 22, attack: 20,
move: 3, move: 3,
stats: { might: 96, intelligence: 64, leadership: 84, agility: 70, luck: 62 }, stats: { might: 96, intelligence: 64, leadership: 84, agility: 70, luck: 62 },
equipment: { equipment: {
@@ -9281,9 +9281,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 16, level: 16,
exp: 98, exp: 98,
hp: 70, hp: 36,
maxHp: 70, maxHp: 64,
attack: 22, attack: 17,
move: 3, move: 3,
stats: { might: 96, intelligence: 64, leadership: 84, agility: 70, luck: 62 }, stats: { might: 96, intelligence: 64, leadership: 84, agility: 70, luck: 62 },
equipment: { equipment: {
@@ -9302,9 +9302,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 16, level: 16,
exp: 98, exp: 98,
hp: 70, hp: 36,
maxHp: 70, maxHp: 64,
attack: 22, attack: 17,
move: 3, move: 3,
stats: { might: 96, intelligence: 64, leadership: 84, agility: 70, luck: 62 }, stats: { might: 96, intelligence: 64, leadership: 84, agility: 70, luck: 62 },
equipment: { equipment: {
@@ -9323,9 +9323,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 16, level: 16,
exp: 98, exp: 98,
hp: 54, hp: 36,
maxHp: 54, maxHp: 50,
attack: 22, attack: 17,
move: 3, move: 3,
stats: { might: 70, intelligence: 88, leadership: 78, agility: 76, luck: 66 }, stats: { might: 70, intelligence: 88, leadership: 78, agility: 76, luck: 66 },
equipment: { equipment: {
@@ -9344,9 +9344,9 @@ export const fifteenthBattleUnits: UnitData[] = [
classKey: 'rebelLeader', classKey: 'rebelLeader',
level: 18, level: 18,
exp: 12, exp: 12,
hp: 92, hp: 48,
maxHp: 92, maxHp: 92,
attack: 26, attack: 18,
move: 4, move: 4,
stats: { might: 104, intelligence: 58, leadership: 90, agility: 82, luck: 64 }, stats: { might: 104, intelligence: 58, leadership: 90, agility: 82, luck: 64 },
equipment: { equipment: {
@@ -9531,9 +9531,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 17, level: 17,
exp: 12, exp: 12,
hp: 54, hp: 48,
maxHp: 54, maxHp: 48,
attack: 22, attack: 20,
move: 3, move: 3,
stats: { might: 86, intelligence: 78, leadership: 76, agility: 86, luck: 64 }, stats: { might: 86, intelligence: 78, leadership: 76, agility: 86, luck: 64 },
equipment: { equipment: {
@@ -9552,9 +9552,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 17, level: 17,
exp: 12, exp: 12,
hp: 54, hp: 36,
maxHp: 54, maxHp: 36,
attack: 22, attack: 17,
move: 3, move: 3,
stats: { might: 86, intelligence: 78, leadership: 76, agility: 86, luck: 64 }, stats: { might: 86, intelligence: 78, leadership: 76, agility: 86, luck: 64 },
equipment: { equipment: {
@@ -9573,9 +9573,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 17, level: 17,
exp: 12, exp: 12,
hp: 54, hp: 48,
maxHp: 54, maxHp: 48,
attack: 22, attack: 20,
move: 3, move: 3,
stats: { might: 86, intelligence: 78, leadership: 76, agility: 86, luck: 64 }, stats: { might: 86, intelligence: 78, leadership: 76, agility: 86, luck: 64 },
equipment: { equipment: {
@@ -9636,9 +9636,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 17, level: 17,
exp: 12, exp: 12,
hp: 70, hp: 66,
maxHp: 70, maxHp: 66,
attack: 24, attack: 23,
move: 5, move: 5,
stats: { might: 100, intelligence: 60, leadership: 78, agility: 94, luck: 65 }, stats: { might: 100, intelligence: 60, leadership: 78, agility: 94, luck: 65 },
equipment: { equipment: {
@@ -9657,9 +9657,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 18, level: 18,
exp: 14, exp: 14,
hp: 74, hp: 58,
maxHp: 74, maxHp: 68,
attack: 25, attack: 20,
move: 5, move: 5,
stats: { might: 102, intelligence: 62, leadership: 80, agility: 95, luck: 66 }, stats: { might: 102, intelligence: 62, leadership: 80, agility: 95, luck: 66 },
equipment: { equipment: {
@@ -9678,9 +9678,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 18, level: 18,
exp: 14, exp: 14,
hp: 74, hp: 44,
maxHp: 74, maxHp: 44,
attack: 24, attack: 19,
move: 3, move: 3,
stats: { might: 100, intelligence: 66, leadership: 88, agility: 72, luck: 64 }, stats: { might: 100, intelligence: 66, leadership: 88, agility: 72, luck: 64 },
equipment: { equipment: {
@@ -9699,9 +9699,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 18, level: 18,
exp: 14, exp: 14,
hp: 74, hp: 44,
maxHp: 74, maxHp: 44,
attack: 24, attack: 19,
move: 3, move: 3,
stats: { might: 100, intelligence: 66, leadership: 88, agility: 72, luck: 64 }, stats: { might: 100, intelligence: 66, leadership: 88, agility: 72, luck: 64 },
equipment: { equipment: {
@@ -9720,9 +9720,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 18, level: 18,
exp: 14, exp: 14,
hp: 58, hp: 36,
maxHp: 58, maxHp: 36,
attack: 23, attack: 17,
move: 3, move: 3,
stats: { might: 72, intelligence: 90, leadership: 80, agility: 78, luck: 66 }, stats: { might: 72, intelligence: 90, leadership: 80, agility: 78, luck: 66 },
equipment: { equipment: {
@@ -9741,9 +9741,9 @@ export const sixteenthBattleUnits: UnitData[] = [
classKey: 'rebelLeader', classKey: 'rebelLeader',
level: 19, level: 19,
exp: 18, exp: 18,
hp: 98, hp: 70,
maxHp: 98, maxHp: 90,
attack: 27, attack: 20,
move: 4, move: 4,
stats: { might: 106, intelligence: 74, leadership: 96, agility: 80, luck: 66 }, stats: { might: 106, intelligence: 74, leadership: 96, agility: 80, luck: 66 },
equipment: { equipment: {
@@ -9781,9 +9781,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'bandit', classKey: 'bandit',
level: 18, level: 18,
exp: 16, exp: 16,
hp: 58, hp: 52,
maxHp: 58, maxHp: 58,
attack: 22, attack: 20,
move: 4, move: 4,
stats: { might: 94, intelligence: 66, leadership: 72, agility: 92, luck: 64 }, stats: { might: 94, intelligence: 66, leadership: 72, agility: 92, luck: 64 },
equipment: { equipment: {
@@ -9802,9 +9802,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'bandit', classKey: 'bandit',
level: 18, level: 18,
exp: 16, exp: 16,
hp: 58, hp: 52,
maxHp: 58, maxHp: 58,
attack: 22, attack: 20,
move: 4, move: 4,
stats: { might: 94, intelligence: 66, leadership: 72, agility: 92, luck: 64 }, stats: { might: 94, intelligence: 66, leadership: 72, agility: 92, luck: 64 },
equipment: { equipment: {
@@ -9823,9 +9823,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 18, level: 18,
exp: 18, exp: 18,
hp: 70, hp: 62,
maxHp: 70, maxHp: 70,
attack: 24, attack: 21,
move: 3, move: 3,
stats: { might: 100, intelligence: 68, leadership: 86, agility: 74, luck: 64 }, stats: { might: 100, intelligence: 68, leadership: 86, agility: 74, luck: 64 },
equipment: { equipment: {
@@ -9844,9 +9844,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 18, level: 18,
exp: 18, exp: 18,
hp: 70, hp: 62,
maxHp: 70, maxHp: 70,
attack: 24, attack: 21,
move: 3, move: 3,
stats: { might: 100, intelligence: 68, leadership: 86, agility: 74, luck: 64 }, stats: { might: 100, intelligence: 68, leadership: 86, agility: 74, luck: 64 },
equipment: { equipment: {
@@ -9865,9 +9865,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 19, level: 19,
exp: 20, exp: 20,
hp: 74, hp: 52,
maxHp: 74, maxHp: 68,
attack: 25, attack: 19,
move: 3, move: 3,
stats: { might: 102, intelligence: 70, leadership: 88, agility: 74, luck: 65 }, stats: { might: 102, intelligence: 70, leadership: 88, agility: 74, luck: 65 },
equipment: { equipment: {
@@ -9886,9 +9886,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 19, level: 19,
exp: 20, exp: 20,
hp: 74, hp: 52,
maxHp: 74, maxHp: 68,
attack: 25, attack: 19,
move: 3, move: 3,
stats: { might: 102, intelligence: 70, leadership: 88, agility: 74, luck: 65 }, stats: { might: 102, intelligence: 70, leadership: 88, agility: 74, luck: 65 },
equipment: { equipment: {
@@ -9928,9 +9928,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 18, level: 18,
exp: 18, exp: 18,
hp: 56, hp: 44,
maxHp: 56, maxHp: 50,
attack: 23, attack: 18,
move: 3, move: 3,
stats: { might: 88, intelligence: 80, leadership: 78, agility: 88, luck: 65 }, stats: { might: 88, intelligence: 80, leadership: 78, agility: 88, luck: 65 },
equipment: { equipment: {
@@ -9949,9 +9949,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 19, level: 19,
exp: 20, exp: 20,
hp: 58, hp: 40,
maxHp: 58, maxHp: 50,
attack: 24, attack: 17,
move: 3, move: 3,
stats: { might: 90, intelligence: 82, leadership: 80, agility: 88, luck: 66 }, stats: { might: 90, intelligence: 82, leadership: 80, agility: 88, luck: 66 },
equipment: { equipment: {
@@ -9970,9 +9970,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 19, level: 19,
exp: 20, exp: 20,
hp: 76, hp: 62,
maxHp: 76, maxHp: 76,
attack: 26, attack: 22,
move: 5, move: 5,
stats: { might: 104, intelligence: 64, leadership: 82, agility: 96, luck: 66 }, stats: { might: 104, intelligence: 64, leadership: 82, agility: 96, luck: 66 },
equipment: { equipment: {
@@ -9991,9 +9991,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 19, level: 19,
exp: 20, exp: 20,
hp: 76, hp: 62,
maxHp: 76, maxHp: 76,
attack: 26, attack: 22,
move: 5, move: 5,
stats: { might: 104, intelligence: 64, leadership: 82, agility: 96, luck: 66 }, stats: { might: 104, intelligence: 64, leadership: 82, agility: 96, luck: 66 },
equipment: { equipment: {
@@ -10012,9 +10012,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 19, level: 19,
exp: 22, exp: 22,
hp: 78, hp: 52,
maxHp: 78, maxHp: 66,
attack: 25, attack: 20,
move: 3, move: 3,
stats: { might: 102, intelligence: 74, leadership: 90, agility: 75, luck: 65 }, stats: { might: 102, intelligence: 74, leadership: 90, agility: 75, luck: 65 },
equipment: { equipment: {
@@ -10033,9 +10033,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 19, level: 19,
exp: 22, exp: 22,
hp: 78, hp: 52,
maxHp: 78, maxHp: 66,
attack: 25, attack: 20,
move: 3, move: 3,
stats: { might: 102, intelligence: 74, leadership: 90, agility: 75, luck: 65 }, stats: { might: 102, intelligence: 74, leadership: 90, agility: 75, luck: 65 },
equipment: { equipment: {
@@ -10054,9 +10054,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 19, level: 19,
exp: 22, exp: 22,
hp: 60, hp: 40,
maxHp: 60, maxHp: 52,
attack: 24, attack: 18,
move: 3, move: 3,
stats: { might: 74, intelligence: 92, leadership: 82, agility: 80, luck: 68 }, stats: { might: 74, intelligence: 92, leadership: 82, agility: 80, luck: 68 },
equipment: { equipment: {
@@ -10075,9 +10075,9 @@ export const seventeenthBattleUnits: UnitData[] = [
classKey: 'rebelLeader', classKey: 'rebelLeader',
level: 20, level: 20,
exp: 24, exp: 24,
hp: 104, hp: 72,
maxHp: 104, maxHp: 104,
attack: 28, attack: 22,
move: 4, move: 4,
stats: { might: 108, intelligence: 76, leadership: 98, agility: 82, luck: 66 }, stats: { might: 108, intelligence: 76, leadership: 98, agility: 82, luck: 66 },
equipment: { equipment: {
@@ -10831,8 +10831,8 @@ const twentiethBattleAllyPositions: Record<string, { x: number; y: number }> = {
'zhang-fei': { x: 6, y: 23 }, 'zhang-fei': { x: 6, y: 23 },
'jian-yong': { x: 3, y: 24 }, 'jian-yong': { x: 3, y: 24 },
'mi-zhu': { x: 5, y: 25 }, 'mi-zhu': { x: 5, y: 25 },
'sun-qian': { x: 7, y: 22 }, 'sun-qian': { x: 4, y: 24 },
'zhao-yun': { x: 8, y: 20 }, 'zhao-yun': { x: 8, y: 21 },
'zhuge-liang': { x: 6, y: 21 } 'zhuge-liang': { x: 6, y: 21 }
}; };
@@ -10852,9 +10852,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'bandit', classKey: 'bandit',
level: 24, level: 24,
exp: 34, exp: 34,
hp: 70, hp: 44,
maxHp: 70, maxHp: 56,
attack: 27, attack: 18,
move: 4, move: 4,
stats: { might: 102, intelligence: 74, leadership: 80, agility: 100, luck: 70 }, stats: { might: 102, intelligence: 74, leadership: 80, agility: 100, luck: 70 },
equipment: { equipment: {
@@ -10862,7 +10862,7 @@ export const twentiethBattleUnits: UnitData[] = [
armor: { itemId: 'rebel-vest', level: 3, exp: 4 }, armor: { itemId: 'rebel-vest', level: 3, exp: 4 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 } accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
}, },
x: 13, x: 14,
y: 21 y: 21
}, },
{ {
@@ -10873,9 +10873,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'bandit', classKey: 'bandit',
level: 24, level: 24,
exp: 34, exp: 34,
hp: 70, hp: 56,
maxHp: 70, maxHp: 56,
attack: 27, attack: 23,
move: 4, move: 4,
stats: { might: 102, intelligence: 74, leadership: 80, agility: 100, luck: 70 }, stats: { might: 102, intelligence: 74, leadership: 80, agility: 100, luck: 70 },
equipment: { equipment: {
@@ -10883,7 +10883,7 @@ export const twentiethBattleUnits: UnitData[] = [
armor: { itemId: 'rebel-vest', level: 3, exp: 4 }, armor: { itemId: 'rebel-vest', level: 3, exp: 4 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 } accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
}, },
x: 14, x: 15,
y: 24 y: 24
}, },
{ {
@@ -10894,9 +10894,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 25, level: 25,
exp: 36, exp: 36,
hp: 94, hp: 74,
maxHp: 94, maxHp: 86,
attack: 32, attack: 26,
move: 5, move: 5,
stats: { might: 116, intelligence: 74, leadership: 92, agility: 110, luck: 72 }, stats: { might: 116, intelligence: 74, leadership: 92, agility: 110, luck: 72 },
equipment: { equipment: {
@@ -10904,7 +10904,7 @@ export const twentiethBattleUnits: UnitData[] = [
armor: { itemId: 'lamellar-armor', level: 3, exp: 18 }, armor: { itemId: 'lamellar-armor', level: 3, exp: 18 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 } accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
}, },
x: 17, x: 19,
y: 19 y: 19
}, },
{ {
@@ -10915,9 +10915,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 25, level: 25,
exp: 36, exp: 36,
hp: 94, hp: 74,
maxHp: 94, maxHp: 86,
attack: 32, attack: 26,
move: 5, move: 5,
stats: { might: 116, intelligence: 74, leadership: 92, agility: 110, luck: 72 }, stats: { might: 116, intelligence: 74, leadership: 92, agility: 110, luck: 72 },
equipment: { equipment: {
@@ -10925,7 +10925,7 @@ export const twentiethBattleUnits: UnitData[] = [
armor: { itemId: 'lamellar-armor', level: 3, exp: 18 }, armor: { itemId: 'lamellar-armor', level: 3, exp: 18 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 } accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
}, },
x: 18, x: 20,
y: 23 y: 23
}, },
{ {
@@ -10936,9 +10936,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 26, level: 26,
exp: 38, exp: 38,
hp: 98, hp: 64,
maxHp: 98, maxHp: 92,
attack: 33, attack: 24,
move: 5, move: 5,
stats: { might: 118, intelligence: 76, leadership: 94, agility: 112, luck: 72 }, stats: { might: 118, intelligence: 76, leadership: 94, agility: 112, luck: 72 },
equipment: { equipment: {
@@ -10957,9 +10957,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'cavalry', classKey: 'cavalry',
level: 26, level: 26,
exp: 38, exp: 38,
hp: 98, hp: 64,
maxHp: 98, maxHp: 92,
attack: 33, attack: 24,
move: 5, move: 5,
stats: { might: 118, intelligence: 76, leadership: 94, agility: 112, luck: 72 }, stats: { might: 118, intelligence: 76, leadership: 94, agility: 112, luck: 72 },
equipment: { equipment: {
@@ -10978,9 +10978,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 24, level: 24,
exp: 34, exp: 34,
hp: 88, hp: 72,
maxHp: 88, maxHp: 88,
attack: 29, attack: 25,
move: 3, move: 3,
stats: { might: 110, intelligence: 76, leadership: 94, agility: 82, luck: 70 }, stats: { might: 110, intelligence: 76, leadership: 94, agility: 82, luck: 70 },
equipment: { equipment: {
@@ -10999,9 +10999,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 24, level: 24,
exp: 34, exp: 34,
hp: 88, hp: 72,
maxHp: 88, maxHp: 88,
attack: 29, attack: 25,
move: 3, move: 3,
stats: { might: 110, intelligence: 76, leadership: 94, agility: 82, luck: 70 }, stats: { might: 110, intelligence: 76, leadership: 94, agility: 82, luck: 70 },
equipment: { equipment: {
@@ -11020,9 +11020,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 25, level: 25,
exp: 36, exp: 36,
hp: 92, hp: 64,
maxHp: 92, maxHp: 92,
attack: 30, attack: 24,
move: 3, move: 3,
stats: { might: 112, intelligence: 78, leadership: 96, agility: 84, luck: 71 }, stats: { might: 112, intelligence: 78, leadership: 96, agility: 84, luck: 71 },
equipment: { equipment: {
@@ -11041,9 +11041,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 25, level: 25,
exp: 36, exp: 36,
hp: 92, hp: 64,
maxHp: 92, maxHp: 92,
attack: 30, attack: 24,
move: 3, move: 3,
stats: { might: 112, intelligence: 78, leadership: 96, agility: 84, luck: 71 }, stats: { might: 112, intelligence: 78, leadership: 96, agility: 84, luck: 71 },
equipment: { equipment: {
@@ -11062,9 +11062,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 24, level: 24,
exp: 34, exp: 34,
hp: 68, hp: 56,
maxHp: 68, maxHp: 68,
attack: 29, attack: 24,
move: 3, move: 3,
stats: { might: 98, intelligence: 88, leadership: 86, agility: 96, luck: 72 }, stats: { might: 98, intelligence: 88, leadership: 86, agility: 96, luck: 72 },
equipment: { equipment: {
@@ -11083,9 +11083,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 24, level: 24,
exp: 34, exp: 34,
hp: 68, hp: 56,
maxHp: 68, maxHp: 68,
attack: 29, attack: 24,
move: 3, move: 3,
stats: { might: 98, intelligence: 88, leadership: 86, agility: 96, luck: 72 }, stats: { might: 98, intelligence: 88, leadership: 86, agility: 96, luck: 72 },
equipment: { equipment: {
@@ -11104,9 +11104,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 25, level: 25,
exp: 36, exp: 36,
hp: 70, hp: 44,
maxHp: 70, maxHp: 52,
attack: 30, attack: 22,
move: 3, move: 3,
stats: { might: 100, intelligence: 90, leadership: 88, agility: 98, luck: 72 }, stats: { might: 100, intelligence: 90, leadership: 88, agility: 98, luck: 72 },
equipment: { equipment: {
@@ -11125,9 +11125,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 26, level: 26,
exp: 38, exp: 38,
hp: 100, hp: 52,
maxHp: 100, maxHp: 84,
attack: 32, attack: 22,
move: 3, move: 3,
stats: { might: 118, intelligence: 80, leadership: 104, agility: 86, luck: 72 }, stats: { might: 118, intelligence: 80, leadership: 104, agility: 86, luck: 72 },
equipment: { equipment: {
@@ -11146,9 +11146,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'yellowTurban', classKey: 'yellowTurban',
level: 26, level: 26,
exp: 38, exp: 38,
hp: 100, hp: 52,
maxHp: 100, maxHp: 84,
attack: 32, attack: 22,
move: 3, move: 3,
stats: { might: 118, intelligence: 80, leadership: 104, agility: 86, luck: 72 }, stats: { might: 118, intelligence: 80, leadership: 104, agility: 86, luck: 72 },
equipment: { equipment: {
@@ -11167,9 +11167,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'archer', classKey: 'archer',
level: 25, level: 25,
exp: 36, exp: 36,
hp: 72, hp: 52,
maxHp: 72, maxHp: 64,
attack: 29, attack: 23,
move: 3, move: 3,
stats: { might: 78, intelligence: 98, leadership: 90, agility: 86, luck: 74 }, stats: { might: 78, intelligence: 98, leadership: 90, agility: 86, luck: 74 },
equipment: { equipment: {
@@ -11188,9 +11188,9 @@ export const twentiethBattleUnits: UnitData[] = [
classKey: 'rebelLeader', classKey: 'rebelLeader',
level: 27, level: 27,
exp: 42, exp: 42,
hp: 132, hp: 84,
maxHp: 132, maxHp: 132,
attack: 34, attack: 26,
move: 4, move: 4,
stats: { might: 120, intelligence: 86, leadership: 112, agility: 90, luck: 76 }, stats: { might: 120, intelligence: 86, leadership: 112, agility: 90, luck: 76 },
equipment: { equipment: {

View File

@@ -1609,8 +1609,8 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
'liu-biao-road-archer-d': 'hold', 'liu-biao-road-archer-d': 'hold',
'liu-biao-road-cavalry-a': 'aggressive', 'liu-biao-road-cavalry-a': 'aggressive',
'liu-biao-road-cavalry-b': 'aggressive', 'liu-biao-road-cavalry-b': 'aggressive',
'liu-biao-road-cavalry-c': 'aggressive', 'liu-biao-road-cavalry-c': 'guard',
'liu-biao-road-cavalry-d': 'aggressive', 'liu-biao-road-cavalry-d': 'guard',
'liu-biao-road-guard-a': 'guard', 'liu-biao-road-guard-a': 'guard',
'liu-biao-road-guard-b': 'guard', 'liu-biao-road-guard-b': 'guard',
'liu-biao-road-strategist-a': 'hold', 'liu-biao-road-strategist-a': 'hold',
@@ -1667,8 +1667,8 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
'envoy-road-scout-b': 'aggressive', 'envoy-road-scout-b': 'aggressive',
'envoy-road-cavalry-a': 'aggressive', 'envoy-road-cavalry-a': 'aggressive',
'envoy-road-cavalry-b': 'aggressive', 'envoy-road-cavalry-b': 'aggressive',
'envoy-road-cavalry-c': 'aggressive', 'envoy-road-cavalry-c': 'guard',
'envoy-road-cavalry-d': 'aggressive', 'envoy-road-cavalry-d': 'guard',
'envoy-road-infantry-a': 'guard', 'envoy-road-infantry-a': 'guard',
'envoy-road-infantry-b': 'guard', 'envoy-road-infantry-b': 'guard',
'envoy-road-infantry-c': 'guard', 'envoy-road-infantry-c': 'guard',

View File

@@ -742,9 +742,9 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
{ unitId: 'sun-qian', reason: '문서와 외교 명분을 지니고 있어 이번 전투의 생존 목표입니다.' }, { unitId: 'sun-qian', reason: '문서와 외교 명분을 지니고 있어 이번 전투의 생존 목표입니다.' },
{ unitId: 'zhao-yun', reason: '추격 기병을 끊고 사절의 측면을 지키는 데 좋습니다.' }, { unitId: 'zhao-yun', reason: '추격 기병을 끊고 사절의 측면을 지키는 데 좋습니다.' },
{ unitId: 'guan-yu', reason: '강나루 보병과 포구 수비대를 받아낼 전열 핵심입니다.' }, { unitId: 'guan-yu', reason: '강나루 보병과 포구 수비대를 받아낼 전열 핵심입니다.' },
{ unitId: 'mi-zhu', reason: '사절 보급과 장기전 회복 운용에 유리합니다.' } { unitId: 'zhang-fei', reason: '포구 수비대를 빠르게 흔들어 사절단이 길게 물리지 않게 합니다.' }
], ],
note: '강동 사절로는 전투력만으로 고르기 어렵습니다. 제갈량과 손건을 보호하면서 전열, 기동, 보급 중 무엇을 남길지 선택하십시오.' note: '강동 사절로는 보호 대상이 많은 전장입니다. 제갈량과 손건을 뒤에 두고, 관우·장비·조운으로 전열 기동을 두껍게 세우십시오.'
}, },
'twenty-first-battle-red-cliffs-vanguard': { 'twenty-first-battle-red-cliffs-vanguard': {
maxUnits: 6, maxUnits: 6,