Balance cumulative campaign flow

This commit is contained in:
2026-06-28 08:11:08 +09:00
parent fcc2e28e05
commit 87a25ffbc1
5 changed files with 479 additions and 87 deletions

View File

@@ -3142,7 +3142,7 @@ export const fortySeventhBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 50', '상처약 40', '탁주 17', '남중 산길 지도 1', '마을 회유 문서 1'],
itemRewards: ['콩 42', '상처약 30', '탁주 13', '남중 산길 지도 1', '마을 회유 문서 1'],
victoryPages: fortySeventhBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3202,7 +3202,7 @@ export const fortyEighthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 54', '상처약 42', '탁주 18', '맹획 회유 서신 1', '남중 포로 명부 1'],
itemRewards: ['콩 44', '상처약 32', '탁주 14', '맹획 회유 서신 1', '남중 포로 명부 1'],
victoryPages: fortyEighthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3262,7 +3262,7 @@ export const fortyNinthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 58', '상처약 44', '탁주 19', '칠종칠금 회유문 1', '포로 안심 장부 1'],
itemRewards: ['콩 46', '상처약 34', '탁주 15', '칠종칠금 회유문 1', '포로 안심 장부 1'],
victoryPages: fortyNinthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3322,7 +3322,7 @@ export const fiftiethBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 62', '상처약 46', '탁주 20', '남중 호족 설득문 1', '세 번째 회유 장부 1'],
itemRewards: ['콩 42', '상처약 30', '탁주 14', '남중 호족 설득문 1', '세 번째 회유 장부 1'],
victoryPages: fiftiethBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3389,7 +3389,7 @@ export const fiftyFirstBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 46', '상처약 34', '탁주 16', '호족 보증 장부 1', '회유 퇴로 표식 1'],
itemRewards: ['콩 34', '상처약 24', '탁주 12', '호족 보증 장부 1', '회유 퇴로 표식 1'],
victoryPages: fiftyFirstBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3456,7 +3456,7 @@ export const fiftySecondBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 50', '상처약 38', '탁주 18', '강경파 분리 장부 1', '남중 회유 깃발 1'],
itemRewards: ['콩 36', '상처약 26', '탁주 13', '강경파 분리 장부 1', '남중 회유 깃발 1'],
victoryPages: fiftySecondBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3523,7 +3523,7 @@ export const fiftyThirdBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 54', '상처약 42', '탁주 20', '남중 신뢰 장부 1', '계곡 회유 표식 1'],
itemRewards: ['콩 38', '상처약 28', '탁주 14', '남중 신뢰 장부 1', '계곡 회유 표식 1'],
victoryPages: fiftyThirdBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3590,7 +3590,7 @@ export const fiftyFourthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 60', '상처약 46', '탁주 22', '남중 평정 장부 1', '맹획 항복 서약 1'],
itemRewards: ['콩 42', '상처약 30', '탁주 15', '남중 평정 장부 1', '맹획 항복 서약 1'],
victoryPages: fiftyFourthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3657,7 +3657,7 @@ export const fiftyFifthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 86', '상처약 70', '탁주 34', '기산 출진 장부 1', '한중 보급 표식 1'],
itemRewards: ['콩 60', '상처약 44', '탁주 22', '기산 출진 장부 1', '한중 보급 표식 1'],
victoryPages: fiftyFifthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3731,7 +3731,7 @@ export const fiftySixthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 90', '상처약 74', '탁주 36', '천수 진군 장부 1', '가정 지형 표식 1'],
itemRewards: ['콩 62', '상처약 46', '탁주 23', '천수 진군 장부 1', '가정 지형 표식 1'],
victoryPages: fiftySixthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3815,7 +3815,7 @@ export const fiftySeventhBattleScenario: BattleScenarioDefinition = {
{ kind: 'unit-defeated', unitId: 'zhuge-liang' },
{ kind: 'unit-defeated', unitId: 'wang-ping' }
],
itemRewards: ['콩 94', '상처약 78', '탁주 38', '가정 물길 장부 1', '강유 합류'],
itemRewards: ['콩 64', '상처약 48', '탁주 24', '가정 물길 장부 1', '강유 합류'],
victoryPages: fiftySeventhBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3896,7 +3896,7 @@ export const fiftyEighthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 98', '상처약 82', '탁주 40', '기산 퇴각 지도 1', '강유 첫 출전 기록 1'],
itemRewards: ['콩 66', '상처약 50', '탁주 25', '기산 퇴각 지도 1', '강유 첫 출전 기록 1'],
victoryPages: fiftyEighthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -3977,7 +3977,7 @@ export const fiftyNinthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 104', '상처약 86', '탁주 42', '진창 공성 장부 1', '왕쌍 추격 기록 1'],
itemRewards: ['콩 68', '상처약 52', '탁주 26', '진창 공성 장부 1', '왕쌍 추격 기록 1'],
victoryPages: fiftyNinthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4058,7 +4058,7 @@ export const sixtiethBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 110', '상처약 90', '탁주 44', '무도·음평 장부 1', '곽회 구원로 기록 1'],
itemRewards: ['콩 70', '상처약 54', '탁주 27', '무도·음평 장부 1', '곽회 구원로 기록 1'],
victoryPages: sixtiethBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4139,7 +4139,7 @@ export const sixtyFirstBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 118', '상처약 94', '탁주 46', '한중 우로 장부 1', '조진 역공 기록 1'],
itemRewards: ['콩 72', '상처약 56', '탁주 28', '한중 우로 장부 1', '조진 역공 기록 1'],
victoryPages: sixtyFirstBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4206,7 +4206,7 @@ export const sixtySecondBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 126', '상처약 98', '탁주 48', '기산 재출정 장부 1', '노성 지연선 기록 1'],
itemRewards: ['콩 74', '상처약 58', '탁주 29', '기산 재출정 장부 1', '노성 지연선 기록 1'],
victoryPages: sixtySecondBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4273,7 +4273,7 @@ export const sixtyThirdBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 132', '상처약 102', '탁주 50', '노성 추격 장부 1', '회수 표식 기록 1'],
itemRewards: ['콩 76', '상처약 60', '탁주 30', '노성 추격 장부 1', '회수 표식 기록 1'],
victoryPages: sixtyThirdBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4340,7 +4340,7 @@ export const sixtyFourthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 138', '상처약 106', '탁주 52', '위수 진영 장부 1', '강안 봉화 기록 1'],
itemRewards: ['콩 78', '상처약 62', '탁주 30', '위수 진영 장부 1', '강안 봉화 기록 1'],
victoryPages: sixtyFourthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4407,7 +4407,7 @@ export const sixtyFifthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 144', '상처약 110', '탁주 54', '북안 전진 장부 1', '위수 재추격 기록 1'],
itemRewards: ['콩 80', '상처약 64', '탁주 31', '북안 전진 장부 1', '위수 재추격 기록 1'],
victoryPages: sixtyFifthBattleVictoryPages,
nextCampScene: 'CampScene'
};
@@ -4474,7 +4474,7 @@ export const sixtySixthBattleScenario: BattleScenarioDefinition = {
}
],
defeatConditions: [{ kind: 'unit-defeated', unitId: 'zhuge-liang' }],
itemRewards: ['콩 150', '상처약 114', '탁주 56', '오장원 귀환 장부 1', '강유 계승 지도 1'],
itemRewards: ['콩 84', '상처약 66', '탁주 32', '오장원 귀환 장부 1', '강유 계승 지도 1'],
victoryPages: sixtySixthBattleVictoryPages,
nextCampScene: 'CampScene'
};

View File

@@ -15516,6 +15516,17 @@ const createThirtyFirstEnemyUnit = (
rebelLeader: 4
};
const statLift = Math.max(0, level - 52) * 2;
const lateNorthernTuned = [
'northern-sixth-',
'northern-seventh-',
'northern-eighth-',
'northern-ninth-',
'northern-tenth-',
'northern-eleventh-',
'northern-twelfth-'
].some((prefix) => id.startsWith(prefix));
const tunedHp = lateNorthernTuned ? Math.max(1, Math.round(hp * 0.72)) : hp;
const tunedAttack = lateNorthernTuned ? Math.max(1, Math.round(attack * 0.72)) : attack;
return {
id,
@@ -15525,9 +15536,9 @@ const createThirtyFirstEnemyUnit = (
classKey,
level,
exp: Math.min(98, 84 + statLift),
hp,
maxHp: hp,
attack,
hp: tunedHp,
maxHp: tunedHp,
attack: tunedAttack,
move: moveByClass[classKey],
stats: {
might: 148 + statLift + (classKey === 'rebelLeader' ? 34 : classKey === 'cavalry' ? 24 : classKey === 'yellowTurban' ? 20 : 0),
@@ -16627,13 +16638,13 @@ const fortyFourthBattleUnitsBase: UnitData[] = [
export const fortyFourthBattleUnits: UnitData[] = tuneEnemyUnitGroup(fortyFourthBattleUnitsBase, ['maicheng-'], {
hpScale: 0.55,
attackScale: 0.7,
attackScale: 0.64,
overrides: {
'maicheng-officer-pan-zhang': { hp: 360, attack: 116, x: 52, y: 54 },
'maicheng-officer-ma-zhong': { hp: 300, attack: 104, x: 50, y: 42 },
'maicheng-officer-lu-xun': { hp: 280, attack: 104, x: 58, y: 48 },
'maicheng-officer-xu-huang': { hp: 380, attack: 118, x: 60, y: 34 },
'maicheng-leader-lu-meng': { hp: 430, attack: 122, x: 54, y: 55 }
'maicheng-officer-pan-zhang': { hp: 360, attack: 108, x: 52, y: 54 },
'maicheng-officer-ma-zhong': { hp: 300, attack: 98, x: 50, y: 42 },
'maicheng-officer-lu-xun': { hp: 280, attack: 98, x: 58, y: 48 },
'maicheng-officer-xu-huang': { hp: 380, attack: 110, x: 60, y: 34 },
'maicheng-leader-lu-meng': { hp: 430, attack: 114, x: 54, y: 55 }
}
});
@@ -17683,25 +17694,25 @@ const fiftySixthBattleAllyPositions: Record<string, { x: number; y: number }> =
'jian-yong': { x: 10, y: 86 },
'mi-zhu': { x: 14, y: 88 },
'sun-qian': { x: 19, y: 88 },
'zhao-yun': { x: 29, y: 76 },
'zhuge-liang': { x: 17, y: 75 },
'ma-liang': { x: 21, y: 72 },
'zhao-yun': { x: 42, y: 72 },
'zhuge-liang': { x: 36, y: 74 },
'ma-liang': { x: 39, y: 68 },
'yi-ji': { x: 9, y: 90 },
'gong-zhi': { x: 25, y: 88 },
'huang-zhong': { x: 34, y: 75 },
'wei-yan': { x: 40, y: 79 },
'wei-yan': { x: 44, y: 75 },
'pang-tong': { x: 14, y: 70 },
'fa-zheng': { x: 25, y: 70 },
'wu-yi': { x: 41, y: 86 },
'yan-yan': { x: 45, y: 79 },
'li-yan': { x: 32, y: 69 },
'huang-quan': { x: 11, y: 74 },
'huang-quan': { x: 35, y: 71 },
'ma-chao': { x: 48, y: 75 },
'ma-dai': { x: 52, y: 82 },
'wang-ping': { x: 36, y: 70 }
'ma-dai': { x: 48, y: 72 },
'wang-ping': { x: 45, y: 69 }
};
export const fiftySixthBattleUnits: UnitData[] = [
const fiftySixthBattleUnitsBase: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally' && unit.id !== 'liu-bei'),
...xuzhouRecruitUnits,
@@ -17766,31 +17777,36 @@ export const fiftySixthBattleUnits: UnitData[] = [
createThirtyFirstEnemyUnit('northern-second-leader-guo-huai', '곽회', '위군 북방 지휘관', 'rebelLeader', 182, 1320, 316, 104, 24)
];
export const fiftySixthBattleUnits: UnitData[] = tuneEnemyUnitGroup(fiftySixthBattleUnitsBase, ['northern-second-'], {
hpScale: 0.62,
attackScale: 0.72
});
const fiftySeventhBattleAllyPositions: Record<string, { x: number; y: number }> = {
'guan-yu': { x: 18, y: 83 },
'zhang-fei': { x: 24, y: 84 },
'jian-yong': { x: 11, y: 90 },
'mi-zhu': { x: 15, y: 91 },
'sun-qian': { x: 20, y: 91 },
'zhao-yun': { x: 31, y: 80 },
'zhuge-liang': { x: 17, y: 79 },
'ma-liang': { x: 22, y: 76 },
'zhao-yun': { x: 42, y: 80 },
'zhuge-liang': { x: 38, y: 79 },
'ma-liang': { x: 39, y: 76 },
'yi-ji': { x: 10, y: 93 },
'gong-zhi': { x: 26, y: 91 },
'huang-zhong': { x: 37, y: 79 },
'wei-yan': { x: 43, y: 82 },
'wei-yan': { x: 48, y: 75 },
'pang-tong': { x: 14, y: 75 },
'fa-zheng': { x: 26, y: 74 },
'wu-yi': { x: 44, y: 89 },
'yan-yan': { x: 48, y: 82 },
'li-yan': { x: 34, y: 73 },
'huang-quan': { x: 11, y: 78 },
'huang-quan': { x: 38, y: 81 },
'ma-chao': { x: 51, y: 78 },
'ma-dai': { x: 55, y: 85 },
'wang-ping': { x: 39, y: 73 }
'ma-dai': { x: 55, y: 80 },
'wang-ping': { x: 58, y: 72 }
};
export const fiftySeventhBattleUnits: UnitData[] = [
const fiftySeventhBattleUnitsBase: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally' && unit.id !== 'liu-bei'),
...xuzhouRecruitUnits,
@@ -17847,14 +17863,19 @@ export const fiftySeventhBattleUnits: UnitData[] = [
createThirtyFirstEnemyUnit('northern-third-strategist-b', '위군 가정 군리', '고지 기록 군리', 'strategist', 184, 988, 276, 84, 39),
createThirtyFirstEnemyUnit('northern-third-strategist-c', '위군 가정 군리', '보급 차단 군리', 'strategist', 184, 988, 276, 96, 54),
createThirtyFirstEnemyUnit('northern-third-strategist-d', '위군 가정 군리', '장합 본영 군리', 'strategist', 185, 1000, 278, 108, 26),
createThirtyFirstEnemyUnit('northern-third-officer-jiang-wei', '강유', '흔들리는 천수 장수', 'rebelLeader', 186, 1320, 322, 87, 43),
createThirtyFirstEnemyUnit('northern-third-officer-jiang-wei', '강유', '흔들리는 천수 장수', 'rebelLeader', 186, 1320, 322, 84, 45),
createThirtyFirstEnemyUnit('northern-third-officer-fei-yao', '비요', '장합 지원 장수', 'rebelLeader', 185, 1300, 318, 99, 57),
createThirtyFirstEnemyUnit('northern-third-officer-ma-zun', '마준', '천수 태수', 'rebelLeader', 185, 1300, 316, 105, 64),
createThirtyFirstEnemyUnit('northern-third-officer-supply', '위군 보급 장교', '물길 차단 장수', 'rebelLeader', 184, 1280, 312, 77, 71),
createThirtyFirstEnemyUnit('northern-third-officer-masu-pressure', '가정 압박대', '마속 진영 압박', 'rebelLeader', 184, 1280, 312, 92, 35),
createThirtyFirstEnemyUnit('northern-third-leader-zhang-he', '장합', '위군 역습 총대장', 'rebelLeader', 187, 1400, 332, 109, 24)
createThirtyFirstEnemyUnit('northern-third-leader-zhang-he', '장합', '위군 역습 총대장', 'rebelLeader', 187, 1400, 332, 102, 34)
];
export const fiftySeventhBattleUnits: UnitData[] = tuneEnemyUnitGroup(fiftySeventhBattleUnitsBase, ['northern-third-'], {
hpScale: 0.72,
attackScale: 0.72
});
const fiftyEighthBattleAllyPositions: Record<string, { x: number; y: number }> = {
'guan-yu': { x: 20, y: 85 },
'zhang-fei': { x: 26, y: 86 },
@@ -17952,26 +17973,26 @@ const fiftyNinthBattleAllyPositions: Record<string, { x: number; y: number }> =
'jian-yong': { x: 10, y: 95 },
'mi-zhu': { x: 14, y: 96 },
'sun-qian': { x: 19, y: 96 },
'zhao-yun': { x: 31, y: 86 },
'zhuge-liang': { x: 17, y: 85 },
'ma-liang': { x: 22, y: 82 },
'zhao-yun': { x: 43, y: 84 },
'zhuge-liang': { x: 44, y: 82 },
'ma-liang': { x: 43, y: 79 },
'yi-ji': { x: 9, y: 98 },
'gong-zhi': { x: 27, y: 96 },
'huang-zhong': { x: 37, y: 84 },
'wei-yan': { x: 43, y: 86 },
'wei-yan': { x: 52, y: 82 },
'pang-tong': { x: 15, y: 81 },
'fa-zheng': { x: 27, y: 80 },
'fa-zheng': { x: 46, y: 78 },
'wu-yi': { x: 45, y: 94 },
'yan-yan': { x: 49, y: 87 },
'li-yan': { x: 35, y: 79 },
'huang-quan': { x: 12, y: 84 },
'huang-quan': { x: 44, y: 84 },
'ma-chao': { x: 52, y: 83 },
'ma-dai': { x: 56, y: 90 },
'wang-ping': { x: 40, y: 79 },
'jiang-wei': { x: 33, y: 82 }
'ma-dai': { x: 56, y: 86 },
'wang-ping': { x: 50, y: 78 },
'jiang-wei': { x: 48, y: 80 }
};
export const fiftyNinthBattleUnits: UnitData[] = [
const fiftyNinthBattleUnitsBase: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally' && unit.id !== 'liu-bei'),
...xuzhouRecruitUnits,
@@ -18029,14 +18050,19 @@ export const fiftyNinthBattleUnits: UnitData[] = [
createThirtyFirstEnemyUnit('northern-fifth-strategist-b', '위군 공성 대응 군리', '봉화 연락 군리', 'strategist', 193, 1092, 298, 86, 45),
createThirtyFirstEnemyUnit('northern-fifth-strategist-c', '위군 공성 대응 군리', '학소 본영 군리', 'strategist', 193, 1092, 298, 100, 36),
createThirtyFirstEnemyUnit('northern-fifth-strategist-d', '위군 공성 대응 군리', '군량 차단 군리', 'strategist', 194, 1104, 300, 106, 63),
createThirtyFirstEnemyUnit('northern-fifth-officer-wang-shuang', '왕쌍', '위군 추격 장수', 'rebelLeader', 196, 1480, 356, 87, 72),
createThirtyFirstEnemyUnit('northern-fifth-officer-wang-shuang', '왕쌍', '위군 추격 장수', 'rebelLeader', 196, 1480, 356, 78, 72),
createThirtyFirstEnemyUnit('northern-fifth-officer-fei-yao', '비요', '진창 지원 장수', 'rebelLeader', 194, 1440, 348, 101, 58),
createThirtyFirstEnemyUnit('northern-fifth-officer-guo-huai', '곽회', '북방 지원 장수', 'rebelLeader', 194, 1440, 348, 110, 68),
createThirtyFirstEnemyUnit('northern-fifth-officer-supply', '위군 군량 차단장', '공성 진영 압박 장수', 'rebelLeader', 193, 1420, 344, 78, 76),
createThirtyFirstEnemyUnit('northern-fifth-officer-wall', '진창 성벽 장수', '성문 수비 장수', 'rebelLeader', 194, 1440, 348, 112, 27),
createThirtyFirstEnemyUnit('northern-fifth-leader-hao-zhao', '학소', '진창 수비장', 'rebelLeader', 197, 1540, 362, 109, 35)
createThirtyFirstEnemyUnit('northern-fifth-leader-hao-zhao', '학소', '진창 수비장', 'rebelLeader', 197, 1540, 362, 104, 36)
];
export const fiftyNinthBattleUnits: UnitData[] = tuneEnemyUnitGroup(fiftyNinthBattleUnitsBase, ['northern-fifth-'], {
hpScale: 0.72,
attackScale: 0.72
});
const sixtiethBattleAllyPositions: Record<string, { x: number; y: number }> = {
'guan-yu': { x: 18, y: 90 },
'zhang-fei': { x: 24, y: 92 },
@@ -18572,7 +18598,7 @@ const sixtyFifthEnemySpecs: ReadonlyArray<
['northern-eleventh-officer-supply', '강북 수레 차단장', '수레 차단 장수', 'rebelLeader', 247, 1920, 456, 111, 76],
['northern-eleventh-officer-guo-huai', '곽회', '북안 봉화 장수', 'rebelLeader', 246, 1900, 452, 121, 74],
['northern-eleventh-officer-relay', '봉화 연락장', '북안 뒤 봉화 장수', 'rebelLeader', 246, 1900, 452, 125, 56],
['northern-eleventh-officer-zhang-he', '장합', '재추격 대장', 'rebelLeader', 248, 1960, 462, 126, 35],
['northern-eleventh-officer-zhang-he', '장합', '재추격 대장', 'rebelLeader', 248, 1960, 462, 112, 52],
['northern-eleventh-leader-sima-yi', '사마의', '북안 지연 총지휘', 'rebelLeader', 249, 2000, 468, 122, 47]
];
@@ -18668,7 +18694,7 @@ const sixtySixthEnemySpecs: ReadonlyArray<
['northern-twelfth-officer-wuzhang', '오장원 전진장', '전진 진영 무장', 'rebelLeader', 252, 2000, 472, 90, 84],
['northern-twelfth-officer-ledger', '장부 차단장', '장부 차단 무장', 'rebelLeader', 252, 2000, 472, 111, 74],
['northern-twelfth-officer-guo-huai', '곽회', '봉화 차단 무장', 'rebelLeader', 252, 1980, 468, 122, 70],
['northern-twelfth-officer-zhang-he', '장합', '추격 총대장', 'rebelLeader', 253, 2040, 478, 116, 44],
['northern-twelfth-officer-zhang-he', '장합', '추격 총대장', 'rebelLeader', 253, 2040, 478, 108, 58],
['northern-twelfth-leader-sima-yi', '사마의', '오장원 총지휘관', 'rebelLeader', 254, 2100, 486, 124, 52]
];
@@ -23198,7 +23224,7 @@ function createFiftySixthBattleTerrain(): TerrainType[][] {
Array.from({ length: 112 }, (_, x): TerrainType => {
if (
(x >= 0 && x <= 111 && y >= 82) ||
(x >= 76 && x <= 81 && y >= 0 && y <= 93) ||
(x >= 76 && x <= 81 && y >= 0 && y <= 93 && !(y >= 43 && y <= 58)) ||
(x >= 0 && x <= 30 && y >= 73 && y <= 90) ||
(x >= 86 && x <= 107 && y >= 69 && y <= 84)
) {
@@ -23274,14 +23300,15 @@ function createFiftySeventhBattleTerrain(): TerrainType[][] {
Array.from({ length: 114 }, (_, x): TerrainType => {
if (
(x >= 0 && x <= 113 && y >= 84) ||
(x >= 30 && x <= 36 && y >= 0 && y <= 94) ||
(x >= 78 && x <= 84 && y >= 0 && y <= 88) ||
(x >= 30 && x <= 36 && y >= 0 && y <= 94 && !((y >= 46 && y <= 54) || (y >= 62 && y <= 83))) ||
(x >= 78 && x <= 84 && y >= 0 && y <= 88 && !(y >= 44 && y <= 70)) ||
(x >= 88 && x <= 113 && y >= 70 && y <= 88)
) {
return 'river';
}
if (
(x >= 8 && x <= 110 && y >= 78 && y <= 83) ||
(x >= 28 && x <= 68 && y >= 46 && y <= 54) ||
(x >= 28 && x <= 91 && y >= 62 && y <= 70) ||
(x >= 64 && x <= 110 && y >= 53 && y <= 61) ||
(x >= 46 && x <= 53 && y >= 54 && y <= 84) ||
@@ -23311,7 +23338,7 @@ function createFiftySeventhBattleTerrain(): TerrainType[][] {
if (
(x <= 2 && y <= 84) ||
(x >= 111 && y <= 80) ||
(x >= 36 && x <= 42 && y >= 0 && y <= 56) ||
(x >= 36 && x <= 42 && y >= 0 && y <= 56 && !(y >= 46 && y <= 54)) ||
(x >= 84 && x <= 89 && y >= 0 && y <= 44) ||
(x >= 54 && x <= 60 && y >= 76 && y <= 95)
) {
@@ -23427,7 +23454,7 @@ function createFiftyNinthBattleTerrain(): TerrainType[][] {
Array.from({ length: 118 }, (_, x): TerrainType => {
if (
(x >= 4 && x <= 10 && y >= 0 && y <= 99) ||
(x >= 60 && x <= 67 && y >= 20 && y <= 99) ||
(x >= 60 && x <= 67 && y >= 20 && y <= 99 && !(y >= 54 && y <= 90)) ||
(x >= 0 && x <= 117 && y >= 92)
) {
return 'river';
@@ -23502,7 +23529,7 @@ function createSixtiethBattleTerrain(): TerrainType[][] {
Array.from({ length: 120 }, (_, x): TerrainType => {
if (
(x >= 5 && x <= 11 && y >= 0 && y <= 101) ||
(x >= 62 && x <= 68 && y >= 16 && y <= 101) ||
(x >= 62 && x <= 68 && y >= 16 && y <= 101 && !(y >= 55 && y <= 92)) ||
(x >= 0 && x <= 119 && y >= 94)
) {
return 'river';
@@ -23577,7 +23604,7 @@ function createSixtyFirstBattleTerrain(): TerrainType[][] {
Array.from({ length: 122 }, (_, x): TerrainType => {
if (
(x >= 5 && x <= 12 && y >= 0 && y <= 103) ||
(x >= 63 && x <= 70 && y >= 14 && y <= 103) ||
(x >= 63 && x <= 70 && y >= 14 && y <= 103 && !(y >= 56 && y <= 94)) ||
(x >= 0 && x <= 121 && y >= 96)
) {
return 'river';
@@ -23655,7 +23682,7 @@ function createSixtySecondBattleTerrain(): TerrainType[][] {
Array.from({ length: 124 }, (_, x): TerrainType => {
if (
(x >= 5 && x <= 12 && y >= 0 && y <= 105) ||
(x >= 64 && x <= 71 && y >= 12 && y <= 105) ||
(x >= 64 && x <= 71 && y >= 12 && y <= 105 && !(y >= 56 && y <= 96)) ||
(x >= 0 && x <= 123 && y >= 98)
) {
return 'river';
@@ -23735,7 +23762,7 @@ function createSixtyThirdBattleTerrain(): TerrainType[][] {
Array.from({ length: 126 }, (_, x): TerrainType => {
if (
(x >= 6 && x <= 13 && y >= 0 && y <= 107) ||
(x >= 66 && x <= 73 && y >= 10 && y <= 107) ||
(x >= 66 && x <= 73 && y >= 10 && y <= 107 && !(y >= 58 && y <= 98)) ||
(x >= 0 && x <= 125 && y >= 100)
) {
return 'river';
@@ -23816,8 +23843,8 @@ function createSixtyFourthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 110 }, (_, y) =>
Array.from({ length: 128 }, (_, x): TerrainType => {
if (
(x >= 2 && x <= 126 && y >= 21 && y <= 32) ||
(x >= 2 && x <= 126 && y >= 36 && y <= 45)
(x >= 2 && x <= 126 && y >= 21 && y <= 32 && !(x >= 100 && x <= 116)) ||
(x >= 2 && x <= 126 && y >= 36 && y <= 45 && !(x >= 99 && x <= 127))
) {
return 'river';
}
@@ -23897,8 +23924,8 @@ function createSixtyFifthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 112 }, (_, y) =>
Array.from({ length: 130 }, (_, x): TerrainType => {
if (
(x >= 2 && x <= 128 && y >= 27 && y <= 38) ||
(x >= 3 && x <= 128 && y >= 42 && y <= 52)
(x >= 2 && x <= 128 && y >= 27 && y <= 38 && !(x >= 102 && x <= 118)) ||
(x >= 3 && x <= 128 && y >= 42 && y <= 52 && !(x >= 101 && x <= 129))
) {
return 'river';
}

View File

@@ -6831,7 +6831,9 @@ export class BattleScene extends Phaser.Scene {
'northern-seventh',
'northern-eighth',
'northern-ninth',
'northern-tenth'
'northern-tenth',
'northern-eleventh',
'northern-twelfth'
];
if (lateNorthernPrefixes.some((prefix) => enemy.id.startsWith(prefix))) {
if (
@@ -6839,7 +6841,9 @@ export class BattleScene extends Phaser.Scene {
enemy.id.includes('-cavalry') ||
enemy.id === 'northern-eighth-officer-zhang-he' ||
enemy.id === 'northern-ninth-officer-zhang-he' ||
enemy.id === 'northern-tenth-officer-zhang-he'
enemy.id === 'northern-tenth-officer-zhang-he' ||
enemy.id === 'northern-eleventh-officer-zhang-he' ||
enemy.id === 'northern-twelfth-officer-zhang-he'
) {
return 'aggressive';
}
@@ -6850,17 +6854,25 @@ export class BattleScene extends Phaser.Scene {
}
if (
enemy.id.startsWith('northern-first-scout') ||
enemy.id.startsWith('northern-second-scout') ||
enemy.id.startsWith('northern-third-scout') ||
enemy.id.startsWith('northern-first-cavalry') ||
enemy.id.startsWith('northern-second-cavalry') ||
enemy.id.startsWith('northern-third-cavalry') ||
enemy.id === 'northern-first-officer-zhang-he' ||
enemy.id === 'northern-second-officer-jiang-wei' ||
enemy.id === 'northern-third-leader-zhang-he'
enemy.id === 'northern-first-officer-zhang-he'
) {
return 'aggressive';
}
if (
enemy.id.startsWith('northern-second-scout') ||
enemy.id.startsWith('northern-second-cavalry') ||
enemy.id.startsWith('northern-third-scout') ||
enemy.id.startsWith('northern-third-cavalry')
) {
return enemy.id.endsWith('-a') || enemy.id.endsWith('-b') || enemy.id.endsWith('-c') ? 'aggressive' : 'guard';
}
if (enemy.id === 'northern-second-officer-jiang-wei') {
return 'guard';
}
if (enemy.id === 'northern-third-leader-zhang-he') {
return 'guard';
}
if (
enemy.id.startsWith('northern-first-archer') ||
enemy.id.startsWith('northern-second-archer') ||

View File

@@ -223,6 +223,12 @@ export type CampaignReserveTrainingFocusDefinition = {
export const defaultCampaignReserveTrainingFocusId: CampaignReserveTrainingFocusId = 'balanced';
const campaignInventoryCaps: Record<string, number> = {
['\uCF69']: 120,
['\uC0C1\uCC98\uC57D']: 80,
['\uD0C1\uC8FC']: 80
};
export const campaignReserveTrainingFocusDefinitions: CampaignReserveTrainingFocusDefinition[] = [
{
id: 'balanced',
@@ -770,7 +776,9 @@ function createBattleSettlement(report: FirstBattleReport, reserveTraining: Camp
function applyRewardDelta(inventory: Record<string, number>, rewards: string[], direction: 1 | -1) {
return rewards.reduce<Record<string, number>>((nextInventory, reward) => {
const { label, amount } = parseRewardLabel(reward);
nextInventory[label] = Math.max(0, (nextInventory[label] ?? 0) + amount * direction);
const nextAmount = Math.max(0, (nextInventory[label] ?? 0) + amount * direction);
const cap = direction === 1 ? campaignInventoryCaps[label] : undefined;
nextInventory[label] = cap ? Math.min(nextAmount, cap) : nextAmount;
if (nextInventory[label] === 0) {
delete nextInventory[label];
}