Add Wolong recruitment chapter

This commit is contained in:
2026-06-23 05:09:14 +09:00
parent c209107b43
commit 64af9c1f68
12 changed files with 1033 additions and 22 deletions

View File

@@ -1069,6 +1069,70 @@ export const sixteenthBattleVictoryPages: StoryPage[] = [
}
];
export const seventeenthBattleIntroPages: StoryPage[] = [
{
id: 'seventeenth-wolong-clue-gathered',
bgm: 'story-dark',
chapter: '와룡의 단서',
background: 'story-militia',
speaker: '손건',
text: '형주 선비들의 말이 하나로 모입니다. 융중의 초가에 머무는 제갈공명, 사람들은 그를 와룡이라 부릅니다. 주공께서 직접 찾아가 예를 다한다면 길이 열릴지도 모릅니다.'
},
{
id: 'seventeenth-liu-bei-third-visit',
bgm: 'militia-theme',
chapter: '삼고초려',
background: 'story-liu-bei',
speaker: '유비',
portrait: 'liuBei',
text: '한 번 찾아가 만나지 못했다 하여 뜻이 얕아지는 것은 아니오. 천하를 구할 계책을 구하려면, 내가 먼저 몸을 낮추어 그 문 앞에 서야 하오.'
},
{
id: 'seventeenth-road-to-longzhong',
bgm: 'battle-prep',
chapter: '융중 방문로',
background: 'story-three-heroes',
speaker: '조운',
text: '융중으로 향하는 산길에 수상한 가병들이 숨어 있습니다. 주공의 방문이 형주 안의 권신들에게 알려진 듯합니다. 길을 먼저 정리하겠습니다.'
},
{
id: 'seventeenth-longzhong-sortie',
bgm: 'battle-prep',
chapter: '와룡을 찾아',
background: 'story-sortie',
speaker: '장비',
portrait: 'zhangFei',
text: '군사 하나 만나러 가는데 길목마다 잔챙이들이 성가시게 하는군요. 그래도 형님 뜻이라면 길부터 시원하게 열어 보겠습니다.'
}
];
export const seventeenthBattleVictoryPages: StoryPage[] = [
{
id: 'seventeenth-victory-longzhong-road',
bgm: 'militia-theme',
chapter: '열린 초가 길',
background: 'story-sortie',
text: '융중으로 향하는 길목의 가병들이 흩어지고, 산길은 조용해졌다. 유비는 갑옷의 먼지를 털지도 않은 채 제갈량의 초가 앞에 다시 섰다.'
},
{
id: 'seventeenth-zhuge-liang-counsel',
bgm: 'story-dark',
chapter: '천하삼분의 말',
background: 'story-liu-bei',
speaker: '제갈량',
text: '한실을 일으키려면 먼저 형주와 익주를 얻어 근본을 세우고, 때를 기다려 북벌의 길을 여십시오. 주공의 뜻이 백성에게 닿는다면, 저는 그 길에 지혜를 보태겠습니다.'
},
{
id: 'seventeenth-zhuge-liang-joins',
bgm: 'battle-prep',
chapter: '와룡 출려',
background: 'story-three-heroes',
speaker: '유비',
portrait: 'liuBei',
text: '공명 선생이 함께한다면 우리 군은 비로소 길을 보는 눈을 얻은 것이오. 이제 형주의 머무름은 다음 큰 전장을 준비하는 시간이 될 것이오.'
}
];
export const firstBattleMap: BattleMap = {
width: 20,
height: 18,
@@ -1310,6 +1374,12 @@ export const sixteenthBattleMap: BattleMap = {
terrain: createSixteenthBattleTerrain()
};
export const seventeenthBattleMap: BattleMap = {
width: 34,
height: 26,
terrain: createSeventeenthBattleTerrain()
};
export const firstBattleUnits: UnitData[] = [
{
id: 'liu-bei',
@@ -3242,6 +3312,30 @@ export const liuBiaoRecruitUnits: UnitData[] = [
}
];
export const zhugeRecruitUnits: UnitData[] = [
{
id: 'zhuge-liang',
name: '제갈량',
faction: 'ally',
className: '군사',
classKey: 'strategist',
level: 8,
exp: 0,
hp: 28,
maxHp: 28,
attack: 8,
move: 4,
stats: { might: 34, intelligence: 100, leadership: 88, agility: 74, luck: 86 },
equipment: {
weapon: { itemId: 'white-feather-fan', level: 1, exp: 0 },
armor: { itemId: 'oath-robe', level: 1, exp: 0 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 7,
y: 20
}
];
const eighthBattleAllyPositions: Record<string, { x: number; y: number }> = {
'liu-bei': { x: 2, y: 17 },
'guan-yu': { x: 3, y: 17 },
@@ -5937,6 +6031,340 @@ export const sixteenthBattleUnits: UnitData[] = [
}
];
const seventeenthBattleAllyPositions: Record<string, { x: number; y: number }> = {
'liu-bei': { x: 3, y: 21 },
'guan-yu': { x: 4, y: 20 },
'zhang-fei': { x: 4, y: 22 },
'jian-yong': { x: 5, y: 21 },
'mi-zhu': { x: 3, y: 23 },
'sun-qian': { x: 5, y: 23 },
'zhao-yun': { x: 6, y: 22 }
};
export const seventeenthBattleUnits: UnitData[] = [
...[
...firstBattleUnits.filter((unit) => unit.faction === 'ally'),
...xuzhouRecruitUnits,
...caoBreakRecruitUnits,
...liuBiaoRecruitUnits
].map((unit) => placeScenarioUnit(unit, seventeenthBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
{
id: 'wolong-road-scout-a',
name: '산길 척후',
faction: 'enemy',
className: '형주 척후',
classKey: 'bandit',
level: 18,
exp: 16,
hp: 58,
maxHp: 58,
attack: 22,
move: 4,
stats: { might: 94, intelligence: 66, leadership: 72, agility: 92, luck: 64 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 82 },
armor: { itemId: 'rebel-vest', level: 2, exp: 38 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 10,
y: 20
},
{
id: 'wolong-road-scout-b',
name: '산길 척후',
faction: 'enemy',
className: '형주 척후',
classKey: 'bandit',
level: 18,
exp: 16,
hp: 58,
maxHp: 58,
attack: 22,
move: 4,
stats: { might: 94, intelligence: 66, leadership: 72, agility: 92, luck: 64 },
equipment: {
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 82 },
armor: { itemId: 'rebel-vest', level: 2, exp: 38 },
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
},
x: 12,
y: 23
},
{
id: 'wolong-road-infantry-a',
name: '형주 가병',
faction: 'enemy',
className: '산길 보병',
classKey: 'yellowTurban',
level: 18,
exp: 18,
hp: 70,
maxHp: 70,
attack: 24,
move: 3,
stats: { might: 100, intelligence: 68, leadership: 86, agility: 74, luck: 64 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 86 },
armor: { itemId: 'lamellar-armor', level: 2, exp: 42 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 15,
y: 18
},
{
id: 'wolong-road-infantry-b',
name: '형주 가병',
faction: 'enemy',
className: '산길 보병',
classKey: 'yellowTurban',
level: 18,
exp: 18,
hp: 70,
maxHp: 70,
attack: 24,
move: 3,
stats: { might: 100, intelligence: 68, leadership: 86, agility: 74, luck: 64 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 86 },
armor: { itemId: 'lamellar-armor', level: 2, exp: 42 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 17,
y: 20
},
{
id: 'wolong-road-infantry-c',
name: '형주 가병',
faction: 'enemy',
className: '초가 수비병',
classKey: 'yellowTurban',
level: 19,
exp: 20,
hp: 74,
maxHp: 74,
attack: 25,
move: 3,
stats: { might: 102, intelligence: 70, leadership: 88, agility: 74, luck: 65 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 90 },
armor: { itemId: 'reinforced-lamellar', level: 2, exp: 46 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 26,
y: 11
},
{
id: 'wolong-road-infantry-d',
name: '형주 가병',
faction: 'enemy',
className: '초가 수비병',
classKey: 'yellowTurban',
level: 19,
exp: 20,
hp: 74,
maxHp: 74,
attack: 25,
move: 3,
stats: { might: 102, intelligence: 70, leadership: 88, agility: 74, luck: 65 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 90 },
armor: { itemId: 'reinforced-lamellar', level: 2, exp: 46 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 27,
y: 15
},
{
id: 'wolong-road-archer-a',
name: '형주 궁병',
faction: 'enemy',
className: '숲길 궁병',
classKey: 'archer',
level: 18,
exp: 18,
hp: 56,
maxHp: 56,
attack: 23,
move: 3,
stats: { might: 88, intelligence: 80, leadership: 78, agility: 88, luck: 65 },
equipment: {
weapon: { itemId: 'short-bow', level: 2, exp: 84 },
armor: { itemId: 'cloth-armor', level: 2, exp: 40 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 16,
y: 14
},
{
id: 'wolong-road-archer-b',
name: '형주 궁병',
faction: 'enemy',
className: '숲길 궁병',
classKey: 'archer',
level: 18,
exp: 18,
hp: 56,
maxHp: 56,
attack: 23,
move: 3,
stats: { might: 88, intelligence: 80, leadership: 78, agility: 88, luck: 65 },
equipment: {
weapon: { itemId: 'short-bow', level: 2, exp: 84 },
armor: { itemId: 'cloth-armor', level: 2, exp: 40 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 22,
y: 10
},
{
id: 'wolong-road-archer-c',
name: '형주 궁병',
faction: 'enemy',
className: '초가 궁병',
classKey: 'archer',
level: 19,
exp: 20,
hp: 58,
maxHp: 58,
attack: 24,
move: 3,
stats: { might: 90, intelligence: 82, leadership: 80, agility: 88, luck: 66 },
equipment: {
weapon: { itemId: 'short-bow', level: 2, exp: 88 },
armor: { itemId: 'cloth-armor', level: 2, exp: 42 },
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
},
x: 29,
y: 13
},
{
id: 'wolong-road-cavalry-a',
name: '형주 기병',
faction: 'enemy',
className: '산길 기병',
classKey: 'cavalry',
level: 19,
exp: 20,
hp: 76,
maxHp: 76,
attack: 26,
move: 5,
stats: { might: 104, intelligence: 64, leadership: 82, agility: 96, luck: 66 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 90 },
armor: { itemId: 'lamellar-armor', level: 2, exp: 44 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 13,
y: 19
},
{
id: 'wolong-road-cavalry-b',
name: '형주 기병',
faction: 'enemy',
className: '산길 기병',
classKey: 'cavalry',
level: 19,
exp: 20,
hp: 76,
maxHp: 76,
attack: 26,
move: 5,
stats: { might: 104, intelligence: 64, leadership: 82, agility: 96, luck: 66 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 90 },
armor: { itemId: 'lamellar-armor', level: 2, exp: 44 },
accessory: { itemId: 'bravery-token', level: 1, exp: 0 }
},
x: 20,
y: 18
},
{
id: 'wolong-road-guard-a',
name: '채씨 가병',
faction: 'enemy',
className: '초가 감시병',
classKey: 'yellowTurban',
level: 19,
exp: 22,
hp: 78,
maxHp: 78,
attack: 25,
move: 3,
stats: { might: 102, intelligence: 74, leadership: 90, agility: 75, luck: 65 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 92 },
armor: { itemId: 'reinforced-lamellar', level: 2, exp: 48 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 30,
y: 14
},
{
id: 'wolong-road-guard-b',
name: '채씨 가병',
faction: 'enemy',
className: '초가 감시병',
classKey: 'yellowTurban',
level: 19,
exp: 22,
hp: 78,
maxHp: 78,
attack: 25,
move: 3,
stats: { might: 102, intelligence: 74, leadership: 90, agility: 75, luck: 65 },
equipment: {
weapon: { itemId: 'iron-spear', level: 2, exp: 92 },
armor: { itemId: 'reinforced-lamellar', level: 2, exp: 48 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 31,
y: 12
},
{
id: 'wolong-road-strategist-a',
name: '형주 문객',
faction: 'enemy',
className: '채씨 문객',
classKey: 'archer',
level: 19,
exp: 22,
hp: 60,
maxHp: 60,
attack: 24,
move: 3,
stats: { might: 74, intelligence: 92, leadership: 82, agility: 80, luck: 68 },
equipment: {
weapon: { itemId: 'short-bow', level: 2, exp: 90 },
armor: { itemId: 'cloth-armor', level: 2, exp: 44 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 28,
y: 12
},
{
id: 'wolong-road-leader-cai-xun',
name: '채순',
faction: 'enemy',
className: '채씨 가병장',
classKey: 'rebelLeader',
level: 20,
exp: 24,
hp: 104,
maxHp: 104,
attack: 28,
move: 4,
stats: { might: 108, intelligence: 76, leadership: 98, agility: 82, luck: 66 },
equipment: {
weapon: { itemId: 'leader-axe', level: 3, exp: 32 },
armor: { itemId: 'reinforced-lamellar', level: 2, exp: 52 },
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
},
x: 31,
y: 14
}
];
export const firstBattleBonds: BattleBond[] = [
{
id: 'liu-bei__guan-yu',
@@ -6021,6 +6449,33 @@ export const liuBiaoRecruitBonds: BattleBond[] = [
}
];
export const zhugeRecruitBonds: BattleBond[] = [
{
id: 'liu-bei__zhuge-liang',
unitIds: ['liu-bei', 'zhuge-liang'],
title: '군신의 만남',
level: 58,
exp: 0,
description: '유비의 뜻과 제갈량의 계책이 만나 천하를 향한 큰 그림을 열기 시작합니다.'
},
{
id: 'zhao-yun__zhuge-liang',
unitIds: ['zhao-yun', 'zhuge-liang'],
title: '창과 책략',
level: 36,
exp: 0,
description: '조운의 기동력과 제갈량의 판단은 빠른 구원과 정확한 돌파를 함께 만듭니다.'
},
{
id: 'guan-yu__zhuge-liang',
unitIds: ['guan-yu', 'zhuge-liang'],
title: '의와 계책',
level: 34,
exp: 0,
description: '관우의 의로운 전열과 제갈량의 큰 계책이 서로를 인정하며 군의 중심을 단단히 세웁니다.'
}
];
export const secondBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
export const thirdBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
export const fourthBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
@@ -6040,6 +6495,7 @@ export const fifteenthBattleBonds: BattleBond[] = fourteenthBattleBonds.map(clon
export const sixteenthBattleBonds: BattleBond[] = [...fifteenthBattleBonds, ...liuBiaoRecruitBonds].map(
cloneBattleBondForScenario
);
export const seventeenthBattleBonds: BattleBond[] = sixteenthBattleBonds.map(cloneBattleBondForScenario);
function createEighthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 22 }, (_, y) =>
@@ -6448,6 +6904,55 @@ function createSixteenthBattleTerrain(): TerrainType[][] {
);
}
function createSeventeenthBattleTerrain(): TerrainType[][] {
return Array.from({ length: 26 }, (_, y) =>
Array.from({ length: 34 }, (_, x): TerrainType => {
if ((x <= 2 && y >= 20 && y <= 24) || (x === 3 && y >= 22 && y <= 24)) {
return 'camp';
}
if ((x >= 29 && x <= 33 && y >= 10 && y <= 15) || (x >= 27 && x <= 30 && y >= 8 && y <= 10)) {
return 'fort';
}
if ((x >= 24 && x <= 26 && y >= 11 && y <= 13) || (x >= 12 && x <= 14 && y >= 18 && y <= 20)) {
return 'village';
}
if ((x === 18 || x === 19) && y >= 4 && y <= 23) {
return 'river';
}
if (
(y === 21 && x >= 2 && x <= 15) ||
(y === 18 && x >= 13 && x <= 24) ||
(y === 13 && x >= 22 && x <= 32) ||
(x === 29 && y >= 10 && y <= 18)
) {
return 'road';
}
if ((x >= 5 && x <= 15 && y === 25 - x) || (x >= 15 && x <= 29 && y === x - 11)) {
return 'road';
}
if (
(x <= 10 && y <= 9) ||
(x >= 4 && x <= 15 && y >= 10 && y <= 17) ||
(x >= 20 && x <= 28 && y >= 16 && y <= 24) ||
(x >= 25 && y <= 7)
) {
return 'forest';
}
if (
(x >= 8 && x <= 15 && y >= 2 && y <= 7) ||
(x >= 15 && x <= 23 && y >= 20 && y <= 25) ||
(x >= 27 && x <= 33 && y >= 1 && y <= 6)
) {
return 'hill';
}
if ((x >= 32 && y <= 9) || (x >= 32 && y >= 17) || (x <= 1 && y <= 6)) {
return 'cliff';
}
return 'plain';
})
);
}
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
return {
...cloneUnitForScenario(unit),