Add Fu Pass entry chapter

This commit is contained in:
2026-06-23 09:14:41 +09:00
parent 17cbaab55d
commit 8349d1044f
11 changed files with 1260 additions and 34 deletions

View File

@@ -31,6 +31,10 @@ import {
nineteenthBattleMap,
nineteenthBattleUnits,
nineteenthBattleVictoryPages,
twentyEighthBattleBonds,
twentyEighthBattleMap,
twentyEighthBattleUnits,
twentyEighthBattleVictoryPages,
tenthBattleBonds,
tenthBattleMap,
tenthBattleUnits,
@@ -140,7 +144,8 @@ export type BattleScenarioId =
| 'twenty-fourth-battle-guiyang-persuasion'
| 'twenty-fifth-battle-wuling-mountain-road'
| 'twenty-sixth-battle-changsha-veteran'
| 'twenty-seventh-battle-yizhou-relief-road';
| 'twenty-seventh-battle-yizhou-relief-road'
| 'twenty-eighth-battle-fu-pass-entry';
export type BattleObjectiveKind = 'defeat-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
@@ -1701,6 +1706,69 @@ export const twentySeventhBattleScenario: BattleScenarioDefinition = {
nextCampScene: 'CampScene'
};
export const twentyEighthBattleScenario: BattleScenarioDefinition = {
id: 'twenty-eighth-battle-fu-pass-entry',
title: '부수관 진입전',
victoryConditionLabel: '고패 퇴각',
defeatConditionLabel: '유비 또는 제갈량 퇴각',
openingObjectiveLines: [
'익주 원군로를 연 유비군은 부수관의 첫 문 앞에 섰습니다. 고패는 좁은 협곡과 성루 궁병을 이용해 원군의 명분을 관문 앞에서 묶으려 합니다.',
'이번 전투부터 방통이 출전 후보에 들어옵니다. 와룡과 봉추를 함께 세우면 계책은 강해지지만, 전열과 보급 선택이 더 날카로워집니다.',
'유비와 제갈량을 지키며 고패를 물러나게 하면 익주 내부 인재 법정이 군영에 합류합니다.'
],
map: twentyEighthBattleMap,
units: twentyEighthBattleUnits,
bonds: twentyEighthBattleBonds,
mapTextureKey: 'battle-map-twenty-eighth',
leaderUnitId: 'fupass-leader-gao-pei',
quickVictoryTurnLimit: 37,
baseVictoryGold: 3980,
objectives: [
{
id: 'leader',
kind: 'defeat-leader',
label: '고패 퇴각',
rewardGold: 2520,
unitId: 'fupass-leader-gao-pei'
},
{
id: 'liu-bei',
kind: 'keep-unit-alive',
label: '유비 생존',
rewardGold: 740,
unitId: 'liu-bei'
},
{
id: 'zhuge-liang',
kind: 'keep-unit-alive',
label: '제갈량 생존',
rewardGold: 1020,
unitId: 'zhuge-liang'
},
{
id: 'fu-pass-village',
kind: 'secure-terrain',
label: '부수관 마을 안정',
rewardGold: 1220,
terrain: 'village'
},
{
id: 'quick',
kind: 'quick-victory',
label: '37턴 이내 승리',
rewardGold: 960,
maxTurn: 37
}
],
defeatConditions: [
{ kind: 'unit-defeated', unitId: 'liu-bei' },
{ kind: 'unit-defeated', unitId: 'zhuge-liang' }
],
itemRewards: ['콩 13', '상처약 9', '탁주 6', '부수관 보급표 +1', '법정 합류'],
victoryPages: twentyEighthBattleVictoryPages,
nextCampScene: 'CampScene'
};
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
@@ -1730,7 +1798,8 @@ export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition>
'twenty-fourth-battle-guiyang-persuasion': twentyFourthBattleScenario,
'twenty-fifth-battle-wuling-mountain-road': twentyFifthBattleScenario,
'twenty-sixth-battle-changsha-veteran': twentySixthBattleScenario,
'twenty-seventh-battle-yizhou-relief-road': twentySeventhBattleScenario
'twenty-seventh-battle-yizhou-relief-road': twentySeventhBattleScenario,
'twenty-eighth-battle-fu-pass-entry': twentyEighthBattleScenario
};
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];

View File

@@ -17,6 +17,7 @@ import {
seventeenthBattleScenario,
tenthBattleScenario,
thirteenthBattleScenario,
twentyEighthBattleScenario,
twentyFirstBattleScenario,
twentySecondBattleScenario,
twentyThirdBattleScenario,
@@ -63,6 +64,8 @@ import {
tenthBattleVictoryPages,
thirteenthBattleIntroPages,
thirteenthBattleVictoryPages,
twentyEighthBattleIntroPages,
twentyEighthBattleVictoryPages,
twentyFirstBattleIntroPages,
twentyFirstBattleVictoryPages,
twentySecondBattleIntroPages,
@@ -375,13 +378,24 @@ const sortieFlows: Record<string, SortieFlow> = {
},
[twentySeventhBattleScenario.id]: {
afterBattleId: twentySeventhBattleScenario.id,
eyebrow: '다음 장 준비',
title: '부수관 진입 준비',
eyebrow: '다음 장',
title: twentyEighthBattleScenario.title,
description:
'익주 원군로가 열리고 방통이 합류했습니다. 이제 유비군은 촉의 깊은 산문 부수관으로 들어가기 전, 와룡과 봉추의 계책을 함께 다듬어야 합니다.',
rewardHint: '다음 장: 부수관 진입 준비 중',
pages: twentySeventhBattleVictoryPages,
unavailableNotice: '부수관 이후 익주 심부 장은 다음 작업에서 이어집니다. 군영에서 방통과 기존 무장들의 공명도를 올리고 다음 대장정의 출전 후보를 정비하십시오.'
'익주 원군로가 열리고 방통이 합류했습니다. 이제 와룡과 봉추를 함께 편성할지 고민하며, 촉의 깊은 산문 부수관으로 들어가야 합니다.',
rewardHint: `예상 보상: ${twentyEighthBattleScenario.title} 개방 / 법정 합류`,
nextBattleId: twentyEighthBattleScenario.id,
campaignStep: 'twenty-eighth-battle',
pages: [...twentySeventhBattleVictoryPages, ...twentyEighthBattleIntroPages]
},
[twentyEighthBattleScenario.id]: {
afterBattleId: twentyEighthBattleScenario.id,
eyebrow: '다음 장 준비',
title: '낙성 진입 준비',
description:
'부수관이 열리고 법정이 합류했습니다. 이제 유비군은 익주 안쪽의 마음과 길을 동시에 읽으며 낙성으로 이어지는 더 어려운 전장을 준비해야 합니다.',
rewardHint: '다음 장: 낙성 진입 준비 중',
pages: twentyEighthBattleVictoryPages,
unavailableNotice: '낙성 이후 익주 심부 장은 다음 작업에서 이어집니다. 군영에서 법정과 방통의 공명도를 올리고 다음 관문을 준비하십시오.'
}
};

View File

@@ -1766,6 +1766,68 @@ export const twentySeventhBattleVictoryPages: StoryPage[] = [
}
];
export const twentyEighthBattleIntroPages: StoryPage[] = [
{
id: 'twenty-eighth-fu-pass-shadow',
bgm: 'story-dark',
chapter: '부수관의 그림자',
background: 'story-three-heroes',
speaker: '방통',
text: '익주 원군로는 열렸으나 부수관은 아직 닫혀 있습니다. 고패가 관문 병력을 모아 길을 끊으면, 우리 명분은 산문 앞에서 멈출 것입니다.'
},
{
id: 'twenty-eighth-fa-zheng-message',
bgm: 'battle-prep',
chapter: '익주 내부의 손',
background: 'story-liu-bei',
speaker: '제갈량',
text: '익주 안쪽에서 법정이라는 인물이 은밀히 소식을 보냈습니다. 그는 유장의 답답한 정치를 걱정하며, 부수관을 넘을 길목을 알려 주겠다고 합니다.'
},
{
id: 'twenty-eighth-roster-pressure',
bgm: 'battle-prep',
chapter: '와룡과 봉추의 첫 편성',
background: 'story-militia',
speaker: '마량',
text: '이번 전투부터 방통도 출전 후보가 됩니다. 책사 둘을 모두 데려가면 관문 계책은 강해지지만, 전열과 보급 중 하나가 얇아질 수 있습니다.'
},
{
id: 'twenty-eighth-fu-pass-sortie',
bgm: 'battle-prep',
chapter: '부수관 진입전',
background: 'story-sortie',
speaker: '유비',
portrait: 'liuBei',
text: '관문을 부수는 일보다 중요한 것은, 그 너머의 백성이 우리를 어떻게 기억하느냐요. 방통의 기책과 제갈량의 큰 판을 살려 부수관의 길을 열겠소.'
}
];
export const twentyEighthBattleVictoryPages: StoryPage[] = [
{
id: 'twenty-eighth-victory-pass-open',
bgm: 'militia-theme',
chapter: '부수관이 열리다',
background: 'story-sortie',
text: '고패의 관문 병력이 물러나고 부수관의 첫 문이 열렸습니다. 유비군은 관문 창고를 봉인하고 마을의 곡식을 지켜, 익주 내부의 의심을 조금 누그러뜨렸습니다.'
},
{
id: 'twenty-eighth-fa-zheng-joins',
bgm: 'battle-prep',
chapter: '법정의 합류',
background: 'story-liu-bei',
speaker: '법정',
text: '익주는 험한 땅이지만, 더 험한 것은 닫힌 마음입니다. 주공께서 그 마음을 함부로 베지 않으신다면, 이 법정이 안쪽 길을 밝히겠습니다.'
},
{
id: 'twenty-eighth-next-luo-castle',
bgm: 'story-dark',
chapter: '낙성으로 이어지는 길',
background: 'story-three-heroes',
speaker: '방통',
text: '부수관은 문에 불과합니다. 낙성으로 이어지는 길에는 더 깊은 매복과 더 복잡한 마음이 기다립니다. 이제 법정의 내부 정보까지 함께 써야 합니다.'
}
];
export const firstBattleMap: BattleMap = {
width: 20,
height: 18,
@@ -2073,6 +2135,12 @@ export const twentySeventhBattleMap: BattleMap = {
terrain: createTwentySeventhBattleTerrain()
};
export const twentyEighthBattleMap: BattleMap = {
width: 56,
height: 38,
terrain: createTwentyEighthBattleTerrain()
};
export const firstBattleUnits: UnitData[] = [
{
id: 'liu-bei',
@@ -4170,6 +4238,30 @@ export const yizhouRecruitUnits: UnitData[] = [
}
];
export const fuPassRecruitUnits: UnitData[] = [
{
id: 'fa-zheng',
name: '법정',
faction: 'ally',
className: '익주 모사',
classKey: 'strategist',
level: 17,
exp: 0,
hp: 38,
maxHp: 38,
attack: 9,
move: 4,
stats: { might: 42, intelligence: 94, leadership: 84, agility: 70, luck: 80 },
equipment: {
weapon: { itemId: 'white-feather-fan', level: 2, exp: 18 },
armor: { itemId: 'cloth-armor', level: 2, exp: 16 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 8,
y: 25
}
];
const eighthBattleAllyPositions: Record<string, { x: number; y: number }> = {
'liu-bei': { x: 2, y: 17 },
'guan-yu': { x: 3, y: 17 },
@@ -11105,6 +11197,458 @@ export const twentySeventhBattleUnits: UnitData[] = [
}
];
const twentyEighthBattleAllyPositions: Record<string, { x: number; y: number }> = {
'liu-bei': { x: 4, y: 32 },
'guan-yu': { x: 6, y: 31 },
'zhang-fei': { x: 5, y: 34 },
'jian-yong': { x: 3, y: 35 },
'mi-zhu': { x: 4, y: 36 },
'sun-qian': { x: 7, y: 35 },
'zhao-yun': { x: 8, y: 32 },
'zhuge-liang': { x: 5, y: 32 },
'ma-liang': { x: 8, y: 36 },
'yi-ji': { x: 9, y: 34 },
'gong-zhi': { x: 10, y: 36 },
'huang-zhong': { x: 7, y: 33 },
'wei-yan': { x: 10, y: 31 },
'pang-tong': { x: 9, y: 33 }
};
export const twentyEighthBattleUnits: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally'),
...xuzhouRecruitUnits,
...caoBreakRecruitUnits,
...liuBiaoRecruitUnits,
...zhugeRecruitUnits,
...jingzhouRecruitUnits,
...guiyangRecruitUnits,
...wulingRecruitUnits,
...changshaRecruitUnits,
...yizhouRecruitUnits
].map((unit) => placeScenarioUnit(unit, twentyEighthBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
{
id: 'fupass-scout-a',
name: '부수관 척후',
faction: 'enemy',
className: '관문 척후',
classKey: 'bandit',
level: 44,
exp: 68,
hp: 112,
maxHp: 112,
attack: 43,
move: 4,
stats: { might: 134, intelligence: 96, leadership: 110, agility: 126, luck: 86 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 5, exp: 6 },
armor: { itemId: 'rebel-vest', level: 4, exp: 40 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 16,
y: 32
},
{
id: 'fupass-scout-b',
name: '부수관 척후',
faction: 'enemy',
className: '서문 척후',
classKey: 'bandit',
level: 44,
exp: 68,
hp: 112,
maxHp: 112,
attack: 43,
move: 4,
stats: { might: 134, intelligence: 96, leadership: 110, agility: 126, luck: 86 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 5, exp: 6 },
armor: { itemId: 'rebel-vest', level: 4, exp: 40 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 21,
y: 30
},
{
id: 'fupass-infantry-a',
name: '부수관 보병',
faction: 'enemy',
className: '산문 보병',
classKey: 'yellowTurban',
level: 45,
exp: 70,
hp: 154,
maxHp: 154,
attack: 48,
move: 3,
stats: { might: 150, intelligence: 96, leadership: 128, agility: 104, luck: 86 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 18 },
armor: { itemId: 'lamellar-armor', level: 5, exp: 8 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 25,
y: 29
},
{
id: 'fupass-infantry-b',
name: '부수관 보병',
faction: 'enemy',
className: '협곡 보병',
classKey: 'yellowTurban',
level: 45,
exp: 70,
hp: 154,
maxHp: 154,
attack: 48,
move: 3,
stats: { might: 150, intelligence: 96, leadership: 128, agility: 104, luck: 86 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 18 },
armor: { itemId: 'lamellar-armor', level: 5, exp: 8 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 30,
y: 26
},
{
id: 'fupass-infantry-c',
name: '부수관 보병',
faction: 'enemy',
className: '관문 보병',
classKey: 'yellowTurban',
level: 46,
exp: 72,
hp: 162,
maxHp: 162,
attack: 50,
move: 3,
stats: { might: 154, intelligence: 98, leadership: 132, agility: 106, luck: 86 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 26 },
armor: { itemId: 'reinforced-lamellar', level: 5, exp: 14 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 38,
y: 23
},
{
id: 'fupass-infantry-d',
name: '부수관 보병',
faction: 'enemy',
className: '성문 보병',
classKey: 'yellowTurban',
level: 46,
exp: 72,
hp: 162,
maxHp: 162,
attack: 50,
move: 3,
stats: { might: 154, intelligence: 98, leadership: 132, agility: 106, luck: 86 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 26 },
armor: { itemId: 'reinforced-lamellar', level: 5, exp: 14 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 44,
y: 19
},
{
id: 'fupass-archer-a',
name: '부수관 궁병',
faction: 'enemy',
className: '산루 궁병',
classKey: 'archer',
level: 45,
exp: 70,
hp: 112,
maxHp: 112,
attack: 45,
move: 3,
stats: { might: 108, intelligence: 108, leadership: 114, agility: 122, luck: 88 },
equipment: {
weapon: { itemId: 'short-bow', level: 5, exp: 14 },
armor: { itemId: 'cloth-armor', level: 5, exp: 4 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 30,
y: 22
},
{
id: 'fupass-archer-b',
name: '부수관 궁병',
faction: 'enemy',
className: '관문 궁병',
classKey: 'archer',
level: 46,
exp: 72,
hp: 116,
maxHp: 116,
attack: 46,
move: 3,
stats: { might: 110, intelligence: 110, leadership: 116, agility: 124, luck: 88 },
equipment: {
weapon: { itemId: 'short-bow', level: 5, exp: 22 },
armor: { itemId: 'cloth-armor', level: 5, exp: 10 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 42,
y: 16
},
{
id: 'fupass-archer-c',
name: '부수관 궁병',
faction: 'enemy',
className: '성루 궁병',
classKey: 'archer',
level: 46,
exp: 72,
hp: 116,
maxHp: 116,
attack: 46,
move: 3,
stats: { might: 110, intelligence: 110, leadership: 116, agility: 124, luck: 88 },
equipment: {
weapon: { itemId: 'short-bow', level: 5, exp: 22 },
armor: { itemId: 'cloth-armor', level: 5, exp: 10 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 50,
y: 20
},
{
id: 'fupass-cavalry-a',
name: '부수관 기병',
faction: 'enemy',
className: '고개 기병',
classKey: 'cavalry',
level: 46,
exp: 72,
hp: 162,
maxHp: 162,
attack: 51,
move: 5,
stats: { might: 154, intelligence: 98, leadership: 130, agility: 126, luck: 88 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 28 },
armor: { itemId: 'lamellar-armor', level: 5, exp: 16 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 23,
y: 34
},
{
id: 'fupass-cavalry-b',
name: '부수관 기병',
faction: 'enemy',
className: '관문 기병',
classKey: 'cavalry',
level: 46,
exp: 72,
hp: 162,
maxHp: 162,
attack: 51,
move: 5,
stats: { might: 154, intelligence: 98, leadership: 130, agility: 126, luck: 88 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 28 },
armor: { itemId: 'lamellar-armor', level: 5, exp: 16 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 40,
y: 29
},
{
id: 'fupass-cavalry-c',
name: '부수관 기병',
faction: 'enemy',
className: '성문 기병',
classKey: 'cavalry',
level: 47,
exp: 74,
hp: 170,
maxHp: 170,
attack: 53,
move: 5,
stats: { might: 158, intelligence: 100, leadership: 134, agility: 128, luck: 88 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 36 },
armor: { itemId: 'lamellar-armor', level: 5, exp: 24 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 49,
y: 27
},
{
id: 'fupass-guard-a',
name: '고패 친위대',
faction: 'enemy',
className: '관문 친위대',
classKey: 'yellowTurban',
level: 47,
exp: 74,
hp: 174,
maxHp: 174,
attack: 53,
move: 3,
stats: { might: 160, intelligence: 100, leadership: 138, agility: 108, luck: 88 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 40 },
armor: { itemId: 'reinforced-lamellar', level: 5, exp: 26 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 47,
y: 17
},
{
id: 'fupass-guard-b',
name: '고패 친위대',
faction: 'enemy',
className: '성문 친위대',
classKey: 'yellowTurban',
level: 47,
exp: 74,
hp: 174,
maxHp: 174,
attack: 53,
move: 3,
stats: { might: 160, intelligence: 100, leadership: 138, agility: 108, luck: 88 },
equipment: {
weapon: { itemId: 'iron-spear', level: 5, exp: 40 },
armor: { itemId: 'reinforced-lamellar', level: 5, exp: 26 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 51,
y: 19
},
{
id: 'fupass-strategist-a',
name: '부수관 책사',
faction: 'enemy',
className: '관문 책사',
classKey: 'archer',
level: 46,
exp: 72,
hp: 116,
maxHp: 116,
attack: 46,
move: 3,
stats: { might: 94, intelligence: 124, leadership: 116, agility: 100, luck: 88 },
equipment: {
weapon: { itemId: 'short-bow', level: 5, exp: 24 },
armor: { itemId: 'cloth-armor', level: 5, exp: 12 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 43,
y: 14
},
{
id: 'fupass-strategist-b',
name: '부수관 책사',
faction: 'enemy',
className: '성문 책사',
classKey: 'archer',
level: 46,
exp: 72,
hp: 116,
maxHp: 116,
attack: 46,
move: 3,
stats: { might: 94, intelligence: 124, leadership: 116, agility: 100, luck: 88 },
equipment: {
weapon: { itemId: 'short-bow', level: 5, exp: 24 },
armor: { itemId: 'cloth-armor', level: 5, exp: 12 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 51,
y: 23
},
{
id: 'fupass-ambusher-a',
name: '산길 복병',
faction: 'enemy',
className: '서쪽 복병',
classKey: 'bandit',
level: 45,
exp: 70,
hp: 120,
maxHp: 120,
attack: 45,
move: 4,
stats: { might: 140, intelligence: 98, leadership: 112, agility: 128, luck: 86 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 5, exp: 18 },
armor: { itemId: 'rebel-vest', level: 5, exp: 4 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 31,
y: 34
},
{
id: 'fupass-ambusher-b',
name: '산길 복병',
faction: 'enemy',
className: '북쪽 복병',
classKey: 'bandit',
level: 45,
exp: 70,
hp: 120,
maxHp: 120,
attack: 45,
move: 4,
stats: { might: 140, intelligence: 98, leadership: 112, agility: 128, luck: 86 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 5, exp: 18 },
armor: { itemId: 'rebel-vest', level: 5, exp: 4 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 35,
y: 8
},
{
id: 'fupass-ambusher-c',
name: '산길 복병',
faction: 'enemy',
className: '남쪽 복병',
classKey: 'bandit',
level: 45,
exp: 70,
hp: 120,
maxHp: 120,
attack: 45,
move: 4,
stats: { might: 140, intelligence: 98, leadership: 112, agility: 128, luck: 86 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 5, exp: 18 },
armor: { itemId: 'rebel-vest', level: 5, exp: 4 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 45,
y: 31
},
{
id: 'fupass-leader-gao-pei',
name: '고패',
faction: 'enemy',
className: '부수관 수장',
classKey: 'rebelLeader',
level: 48,
exp: 78,
hp: 222,
maxHp: 222,
attack: 55,
move: 4,
stats: { might: 162, intelligence: 116, leadership: 144, agility: 110, luck: 90 },
equipment: {
weapon: { itemId: 'leader-axe', level: 5, exp: 34 },
armor: { itemId: 'reinforced-lamellar', level: 5, exp: 30 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 52,
y: 18
}
];
export const firstBattleBonds: BattleBond[] = [
{
id: 'liu-bei__guan-yu',
@@ -11375,6 +11919,33 @@ export const yizhouRecruitBonds: BattleBond[] = [
}
];
export const fuPassRecruitBonds: BattleBond[] = [
{
id: 'liu-bei__fa-zheng',
unitIds: ['liu-bei', 'fa-zheng'],
title: '익주 내부의 길',
level: 34,
exp: 0,
description: '유비의 명분과 법정의 내부 정보가 만나, 익주의 닫힌 마음과 관문을 함께 열어 갑니다.'
},
{
id: 'pang-tong__fa-zheng',
unitIds: ['pang-tong', 'fa-zheng'],
title: '봉추와 내부책',
level: 32,
exp: 0,
description: '방통의 과감한 기책과 법정의 익주 사정이 맞물려, 적이 숨긴 길목을 먼저 흔듭니다.'
},
{
id: 'zhuge-liang__fa-zheng',
unitIds: ['zhuge-liang', 'fa-zheng'],
title: '큰 판과 속내',
level: 30,
exp: 0,
description: '제갈량의 큰 전략과 법정의 내부 정세 판단이 더해져, 익주 공략의 무리한 피를 줄입니다.'
}
];
export const secondBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
export const thirdBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
export const fourthBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
@@ -11407,6 +11978,7 @@ export const twentyFourthBattleBonds: BattleBond[] = [...twentyThirdBattleBonds,
export const twentyFifthBattleBonds: BattleBond[] = [...twentyFourthBattleBonds, ...guiyangRecruitBonds].map(cloneBattleBondForScenario);
export const twentySixthBattleBonds: BattleBond[] = [...twentyFifthBattleBonds, ...wulingRecruitBonds].map(cloneBattleBondForScenario);
export const twentySeventhBattleBonds: BattleBond[] = [...twentySixthBattleBonds, ...changshaRecruitBonds].map(cloneBattleBondForScenario);
export const twentyEighthBattleBonds: BattleBond[] = [...twentySeventhBattleBonds, ...yizhouRecruitBonds].map(cloneBattleBondForScenario);
function createEighthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 22 }, (_, y) =>
@@ -12428,6 +13000,62 @@ function createTwentySeventhBattleTerrain(): TerrainType[][] {
);
}
function createTwentyEighthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 38 }, (_, y) =>
Array.from({ length: 56 }, (_, x): TerrainType => {
if (x <= 4 && y >= 31) {
return 'camp';
}
if ((x >= 46 && x <= 54 && y >= 13 && y <= 22) || (x >= 42 && x <= 48 && y >= 10 && y <= 15)) {
return 'fort';
}
if ((x >= 17 && x <= 20 && y >= 28 && y <= 30) || (x >= 32 && x <= 34 && y >= 24 && y <= 26) || (x >= 39 && x <= 41 && y >= 18 && y <= 20)) {
return 'village';
}
if (
(y >= 33 && x >= 4 && x <= 15) ||
(x >= 14 && x <= 25 && y >= 29 && y <= 33) ||
(x >= 24 && x <= 34 && y >= 25 && y <= 29) ||
(x >= 33 && x <= 42 && y >= 20 && y <= 25) ||
(x >= 41 && x <= 50 && y >= 16 && y <= 20) ||
(x >= 49 && x <= 53 && y >= 17 && y <= 19)
) {
return 'road';
}
if ((x === 12 || x === 13) && y >= 0 && y <= 27) {
return 'river';
}
if ((x === 30 || x === 31) && y >= 2 && y <= 23) {
return 'river';
}
if ((x === 38 || x === 39) && y >= 28 && y <= 37) {
return 'river';
}
if (
(x >= 4 && x <= 17 && y >= 8 && y <= 22) ||
(x >= 18 && x <= 29 && y >= 11 && y <= 23) ||
(x >= 31 && x <= 44 && y >= 28 && y <= 37) ||
(x >= 43 && x <= 55 && y >= 24 && y <= 36)
) {
return 'forest';
}
if (
(x >= 0 && x <= 10 && y <= 12) ||
(x >= 19 && x <= 29 && y <= 10) ||
(x >= 31 && x <= 45 && y >= 3 && y <= 13) ||
(x >= 48 && x <= 55 && y <= 12) ||
(x >= 23 && x <= 33 && y >= 31 && y <= 37)
) {
return 'hill';
}
if ((x <= 2 && y <= 30) || (x >= 54 && y >= 22) || (x >= 44 && x <= 46 && y <= 9)) {
return 'cliff';
}
return 'plain';
})
);
}
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
return {
...cloneUnitForScenario(unit),