Add Mianzhu Gate sortie chapter
This commit is contained in:
@@ -2014,6 +2014,68 @@ export const thirtyFirstBattleVictoryPages: StoryPage[] = [
|
||||
}
|
||||
];
|
||||
|
||||
export const thirtySecondBattleIntroPages: StoryPage[] = [
|
||||
{
|
||||
id: 'thirty-second-chengdu-pressure',
|
||||
bgm: 'story-dark',
|
||||
chapter: '성도 압박의 시작',
|
||||
background: 'story-three-heroes',
|
||||
speaker: '법정',
|
||||
text: '낙성이 열리자 성도는 놀랐으나 아직 문을 닫고 있습니다. 면죽관의 수비장 이엄이 항복과 결전을 저울질하고 있으니, 힘과 명분을 함께 보여 주어야 합니다.'
|
||||
},
|
||||
{
|
||||
id: 'thirty-second-yan-yan-first-counsel',
|
||||
bgm: 'battle-prep',
|
||||
chapter: '엄안의 첫 출전',
|
||||
background: 'story-liu-bei',
|
||||
speaker: '엄안',
|
||||
text: '이엄은 무턱대고 물러설 장수가 아닙니다. 그러나 백성을 해치지 않는 군율과 익주 장수를 예우하는 마음을 보이면, 그의 칼끝도 흔들릴 것입니다.'
|
||||
},
|
||||
{
|
||||
id: 'thirty-second-mianzhu-plan',
|
||||
bgm: 'battle-prep',
|
||||
chapter: '면죽관 설득',
|
||||
background: 'story-militia',
|
||||
speaker: '방통',
|
||||
text: '정면으로만 밀면 성도는 더 굳게 닫힙니다. 엄안으로 익주 장수의 마음을 열고, 법정과 오의로 길을 짚으며, 황충과 장비가 수비선을 짧게 끊어야 합니다.'
|
||||
},
|
||||
{
|
||||
id: 'thirty-second-sortie',
|
||||
bgm: 'battle-prep',
|
||||
chapter: '면죽관 압박전',
|
||||
background: 'story-sortie',
|
||||
speaker: '유비',
|
||||
portrait: 'liuBei',
|
||||
text: '우리가 얻으려는 것은 성 하나가 아니라 익주의 마음이오. 면죽관을 넘되 백성을 다치게 하지 말고, 이엄에게도 함께 살 길을 보여 주시오.'
|
||||
}
|
||||
];
|
||||
|
||||
export const thirtySecondBattleVictoryPages: StoryPage[] = [
|
||||
{
|
||||
id: 'thirty-second-victory-pass-yields',
|
||||
bgm: 'militia-theme',
|
||||
chapter: '면죽관이 열리다',
|
||||
background: 'story-sortie',
|
||||
text: '면죽관의 수비선은 무너졌지만 성도 길목의 마을은 불타지 않았습니다. 유비군이 군율을 지키자 익주 병사들은 패배보다 이후의 처우를 먼저 바라보았습니다.'
|
||||
},
|
||||
{
|
||||
id: 'thirty-second-li-yan-joins',
|
||||
bgm: 'battle-prep',
|
||||
chapter: '이엄의 선택',
|
||||
background: 'story-liu-bei',
|
||||
speaker: '이엄',
|
||||
text: '칼을 거두는 일이 반드시 부끄러운 것은 아니군요. 백성을 살리고 익주의 길을 보전한다면, 이엄 또한 새 주군의 군율 아래 서겠습니다.'
|
||||
},
|
||||
{
|
||||
id: 'thirty-second-next-chengdu-surrender',
|
||||
bgm: 'story-dark',
|
||||
chapter: '성도 항복 권고',
|
||||
background: 'story-three-heroes',
|
||||
speaker: '제갈량',
|
||||
text: '낙성과 면죽이 열렸으니 유장의 선택지는 더욱 좁아졌습니다. 다음 길은 성도 포위와 항복 권고, 그리고 익주를 어떻게 다스릴 것인가에 달렸습니다.'
|
||||
}
|
||||
];
|
||||
|
||||
export const firstBattleMap: BattleMap = {
|
||||
width: 20,
|
||||
height: 18,
|
||||
@@ -2345,6 +2407,12 @@ export const thirtyFirstBattleMap: BattleMap = {
|
||||
terrain: createThirtyFirstBattleTerrain()
|
||||
};
|
||||
|
||||
export const thirtySecondBattleMap: BattleMap = {
|
||||
width: 64,
|
||||
height: 46,
|
||||
terrain: createThirtySecondBattleTerrain()
|
||||
};
|
||||
|
||||
export const firstBattleUnits: UnitData[] = [
|
||||
{
|
||||
id: 'liu-bei',
|
||||
@@ -4514,6 +4582,30 @@ export const luoCastleProperRecruitUnits: UnitData[] = [
|
||||
}
|
||||
];
|
||||
|
||||
export const chengduPressureRecruitUnits: UnitData[] = [
|
||||
{
|
||||
id: 'li-yan',
|
||||
name: '이엄',
|
||||
faction: 'ally',
|
||||
className: '익주 수비장',
|
||||
classKey: 'infantry',
|
||||
level: 20,
|
||||
exp: 0,
|
||||
hp: 46,
|
||||
maxHp: 46,
|
||||
attack: 15,
|
||||
move: 4,
|
||||
stats: { might: 80, intelligence: 78, leadership: 88, agility: 70, luck: 72 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'iron-spear', level: 3, exp: 24 },
|
||||
armor: { itemId: 'reinforced-lamellar', level: 3, exp: 12 },
|
||||
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
|
||||
},
|
||||
x: 11,
|
||||
y: 28
|
||||
}
|
||||
];
|
||||
|
||||
const eighthBattleAllyPositions: Record<string, { x: number; y: number }> = {
|
||||
'liu-bei': { x: 2, y: 17 },
|
||||
'guan-yu': { x: 3, y: 17 },
|
||||
@@ -13037,6 +13129,70 @@ export const thirtyFirstBattleUnits: UnitData[] = [
|
||||
createThirtyFirstEnemyUnit('luo-main-leader-zhang-ren', '장임', '낙성 본성 주장', 'rebelLeader', 58, 286, 78, 58, 18)
|
||||
];
|
||||
|
||||
const thirtySecondBattleAllyPositions: Record<string, { x: number; y: number }> = {
|
||||
'liu-bei': { x: 4, y: 40 },
|
||||
'guan-yu': { x: 5, y: 38 },
|
||||
'zhang-fei': { x: 4, y: 42 },
|
||||
'jian-yong': { x: 3, y: 43 },
|
||||
'mi-zhu': { x: 5, y: 44 },
|
||||
'sun-qian': { x: 7, y: 43 },
|
||||
'zhao-yun': { x: 8, y: 39 },
|
||||
'zhuge-liang': { x: 6, y: 38 },
|
||||
'ma-liang': { x: 8, y: 44 },
|
||||
'yi-ji': { x: 9, y: 41 },
|
||||
'gong-zhi': { x: 10, y: 44 },
|
||||
'huang-zhong': { x: 7, y: 40 },
|
||||
'wei-yan': { x: 10, y: 38 },
|
||||
'pang-tong': { x: 9, y: 39 },
|
||||
'fa-zheng': { x: 11, y: 41 },
|
||||
'wu-yi': { x: 12, y: 39 },
|
||||
'yan-yan': { x: 11, y: 37 }
|
||||
};
|
||||
|
||||
export const thirtySecondBattleUnits: UnitData[] = [
|
||||
...[
|
||||
...firstBattleUnits.filter((unit) => unit.faction === 'ally'),
|
||||
...xuzhouRecruitUnits,
|
||||
...caoBreakRecruitUnits,
|
||||
...liuBiaoRecruitUnits,
|
||||
...zhugeRecruitUnits,
|
||||
...jingzhouRecruitUnits,
|
||||
...guiyangRecruitUnits,
|
||||
...wulingRecruitUnits,
|
||||
...changshaRecruitUnits,
|
||||
...yizhouRecruitUnits,
|
||||
...fuPassRecruitUnits,
|
||||
...luoCastleRecruitUnits,
|
||||
...luoCastleProperRecruitUnits
|
||||
].map((unit) => placeScenarioUnit(unit, thirtySecondBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })),
|
||||
createThirtyFirstEnemyUnit('chengdu-scout-a', '성도 정찰병', '남로 정찰병', 'bandit', 56, 164, 60, 18, 39),
|
||||
createThirtyFirstEnemyUnit('chengdu-scout-b', '성도 정찰병', '수로 정찰병', 'bandit', 56, 164, 60, 24, 36),
|
||||
createThirtyFirstEnemyUnit('chengdu-scout-c', '성도 정찰병', '산길 정찰병', 'bandit', 57, 172, 62, 31, 35),
|
||||
createThirtyFirstEnemyUnit('chengdu-infantry-a', '면죽관 보병', '외곽 보병', 'yellowTurban', 57, 236, 74, 29, 33),
|
||||
createThirtyFirstEnemyUnit('chengdu-infantry-b', '면죽관 보병', '외곽 보병', 'yellowTurban', 57, 236, 74, 34, 31),
|
||||
createThirtyFirstEnemyUnit('chengdu-infantry-c', '면죽관 보병', '관문 보병', 'yellowTurban', 58, 246, 76, 41, 27),
|
||||
createThirtyFirstEnemyUnit('chengdu-infantry-d', '면죽관 보병', '관문 보병', 'yellowTurban', 58, 246, 76, 45, 25),
|
||||
createThirtyFirstEnemyUnit('chengdu-infantry-e', '성도 보병', '내곽 보병', 'yellowTurban', 59, 256, 78, 53, 22),
|
||||
createThirtyFirstEnemyUnit('chengdu-infantry-f', '성도 보병', '창고 보병', 'yellowTurban', 59, 256, 78, 57, 25),
|
||||
createThirtyFirstEnemyUnit('chengdu-archer-a', '면죽관 궁병', '숲길 궁병', 'archer', 57, 160, 60, 31, 29),
|
||||
createThirtyFirstEnemyUnit('chengdu-archer-b', '면죽관 궁병', '성벽 궁병', 'archer', 58, 166, 62, 43, 21),
|
||||
createThirtyFirstEnemyUnit('chengdu-archer-c', '성도 궁병', '고지 궁병', 'archer', 58, 166, 62, 50, 18),
|
||||
createThirtyFirstEnemyUnit('chengdu-archer-d', '성도 궁병', '창고 궁병', 'archer', 59, 174, 64, 58, 23),
|
||||
createThirtyFirstEnemyUnit('chengdu-cavalry-a', '성도 기병', '우익 기병', 'cavalry', 58, 246, 78, 28, 41),
|
||||
createThirtyFirstEnemyUnit('chengdu-cavalry-b', '성도 기병', '좌익 기병', 'cavalry', 58, 246, 78, 40, 36),
|
||||
createThirtyFirstEnemyUnit('chengdu-cavalry-c', '성도 기병', '내성 기병', 'cavalry', 59, 258, 80, 55, 30),
|
||||
createThirtyFirstEnemyUnit('chengdu-guard-a', '이엄 친위대', '관문 친위대', 'yellowTurban', 59, 266, 80, 48, 22),
|
||||
createThirtyFirstEnemyUnit('chengdu-guard-b', '이엄 친위대', '관문 친위대', 'yellowTurban', 59, 266, 80, 52, 21),
|
||||
createThirtyFirstEnemyUnit('chengdu-guard-c', '이엄 친위대', '성도 친위대', 'yellowTurban', 60, 276, 82, 58, 19),
|
||||
createThirtyFirstEnemyUnit('chengdu-strategist-a', '성도 책사', '항복 반대파', 'strategist', 58, 166, 62, 45, 18),
|
||||
createThirtyFirstEnemyUnit('chengdu-strategist-b', '성도 책사', '창고 책사', 'strategist', 59, 174, 64, 55, 15),
|
||||
createThirtyFirstEnemyUnit('chengdu-ambusher-a', '성도 복병', '남벽 복병', 'bandit', 57, 174, 64, 35, 39),
|
||||
createThirtyFirstEnemyUnit('chengdu-ambusher-b', '성도 복병', '동문 복병', 'bandit', 57, 174, 64, 49, 33),
|
||||
createThirtyFirstEnemyUnit('chengdu-ambusher-c', '성도 복병', '북벽 복병', 'bandit', 58, 182, 66, 59, 11),
|
||||
createThirtyFirstEnemyUnit('chengdu-officer-fei-guan', '비관', '익주 부장', 'rebelLeader', 60, 286, 84, 55, 20),
|
||||
createThirtyFirstEnemyUnit('chengdu-leader-li-yan', '이엄', '면죽관 수비장', 'rebelLeader', 61, 306, 86, 60, 18)
|
||||
];
|
||||
|
||||
export const firstBattleBonds: BattleBond[] = [
|
||||
{
|
||||
id: 'liu-bei__guan-yu',
|
||||
@@ -13388,6 +13544,33 @@ export const luoCastleProperRecruitBonds: BattleBond[] = [
|
||||
}
|
||||
];
|
||||
|
||||
export const chengduPressureRecruitBonds: BattleBond[] = [
|
||||
{
|
||||
id: 'liu-bei__li-yan',
|
||||
unitIds: ['liu-bei', 'li-yan'],
|
||||
title: '성도 앞의 군율',
|
||||
level: 30,
|
||||
exp: 0,
|
||||
description: '유비의 군율과 이엄의 수비 책임이 맞닿아, 익주 백성을 해치지 않는 항복 명분을 더 단단하게 만듭니다.'
|
||||
},
|
||||
{
|
||||
id: 'zhuge-liang__li-yan',
|
||||
unitIds: ['zhuge-liang', 'li-yan'],
|
||||
title: '내정과 책략',
|
||||
level: 28,
|
||||
exp: 0,
|
||||
description: '제갈량의 큰 판과 이엄의 창고·관문 지식이 만나, 전투 이후 익주를 다스릴 준비를 앞당깁니다.'
|
||||
},
|
||||
{
|
||||
id: 'yan-yan__li-yan',
|
||||
unitIds: ['yan-yan', 'li-yan'],
|
||||
title: '익주 장수의 결단',
|
||||
level: 28,
|
||||
exp: 0,
|
||||
description: '엄안의 선례와 이엄의 신중함이 서로를 비추며, 익주 장수들이 유비군을 받아들이는 길을 넓힙니다.'
|
||||
}
|
||||
];
|
||||
|
||||
export const secondBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
||||
export const thirdBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
||||
export const fourthBattleBonds: BattleBond[] = firstBattleBonds.map(cloneBattleBondForScenario);
|
||||
@@ -13424,6 +13607,9 @@ export const twentyEighthBattleBonds: BattleBond[] = [...twentySeventhBattleBond
|
||||
export const twentyNinthBattleBonds: BattleBond[] = [...twentyEighthBattleBonds, ...fuPassRecruitBonds].map(cloneBattleBondForScenario);
|
||||
export const thirtiethBattleBonds: BattleBond[] = [...twentyNinthBattleBonds, ...luoCastleRecruitBonds].map(cloneBattleBondForScenario);
|
||||
export const thirtyFirstBattleBonds: BattleBond[] = [...thirtiethBattleBonds].map(cloneBattleBondForScenario);
|
||||
export const thirtySecondBattleBonds: BattleBond[] = [...thirtyFirstBattleBonds, ...luoCastleProperRecruitBonds].map(
|
||||
cloneBattleBondForScenario
|
||||
);
|
||||
|
||||
function createEighthBattleTerrain(): TerrainType[][] {
|
||||
return Array.from({ length: 22 }, (_, y) =>
|
||||
@@ -14685,6 +14871,72 @@ function createThirtyFirstBattleTerrain(): TerrainType[][] {
|
||||
);
|
||||
}
|
||||
|
||||
function createThirtySecondBattleTerrain(): TerrainType[][] {
|
||||
return Array.from({ length: 46 }, (_, y) =>
|
||||
Array.from({ length: 64 }, (_, x): TerrainType => {
|
||||
if (x <= 4 && y >= 39) {
|
||||
return 'camp';
|
||||
}
|
||||
if (
|
||||
(x >= 49 && x <= 62 && y >= 12 && y <= 26) ||
|
||||
(x >= 45 && x <= 54 && y >= 8 && y <= 17) ||
|
||||
(x >= 54 && x <= 62 && y >= 17 && y <= 30) ||
|
||||
(x >= 52 && x <= 58 && y >= 27 && y <= 32)
|
||||
) {
|
||||
return 'fort';
|
||||
}
|
||||
if (
|
||||
(x >= 18 && x <= 21 && y >= 37 && y <= 39) ||
|
||||
(x >= 36 && x <= 38 && y >= 31 && y <= 33) ||
|
||||
(x >= 45 && x <= 47 && y >= 26 && y <= 28) ||
|
||||
(x >= 55 && x <= 57 && y >= 29 && y <= 31)
|
||||
) {
|
||||
return 'village';
|
||||
}
|
||||
if (
|
||||
(y >= 41 && x >= 4 && x <= 19) ||
|
||||
(x >= 18 && x <= 31 && y >= 37 && y <= 41) ||
|
||||
(x >= 30 && x <= 43 && y >= 32 && y <= 37) ||
|
||||
(x >= 42 && x <= 54 && y >= 26 && y <= 32) ||
|
||||
(x >= 53 && x <= 61 && y >= 20 && y <= 26) ||
|
||||
(x >= 58 && x <= 62 && y >= 18 && y <= 21)
|
||||
) {
|
||||
return 'road';
|
||||
}
|
||||
if ((x === 14 || x === 15) && y >= 0 && y <= 35) {
|
||||
return 'river';
|
||||
}
|
||||
if ((x === 35 || x === 36) && y >= 4 && y <= 30) {
|
||||
return 'river';
|
||||
}
|
||||
if ((x === 46 || x === 47) && y >= 32 && y <= 45) {
|
||||
return 'river';
|
||||
}
|
||||
if (
|
||||
(x >= 4 && x <= 21 && y >= 8 && y <= 30) ||
|
||||
(x >= 22 && x <= 34 && y >= 14 && y <= 31) ||
|
||||
(x >= 37 && x <= 50 && y >= 33 && y <= 45) ||
|
||||
(x >= 49 && x <= 63 && y >= 29 && y <= 44)
|
||||
) {
|
||||
return 'forest';
|
||||
}
|
||||
if (
|
||||
(x >= 0 && x <= 12 && y <= 16) ||
|
||||
(x >= 22 && x <= 34 && y <= 13) ||
|
||||
(x >= 36 && x <= 52 && y >= 2 && y <= 14) ||
|
||||
(x >= 55 && x <= 63 && y <= 12) ||
|
||||
(x >= 26 && x <= 38 && y >= 38 && y <= 45)
|
||||
) {
|
||||
return 'hill';
|
||||
}
|
||||
if ((x <= 2 && y <= 38) || (x >= 62 && y >= 26) || (x >= 49 && x <= 52 && y <= 8)) {
|
||||
return 'cliff';
|
||||
}
|
||||
return 'plain';
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
|
||||
return {
|
||||
...cloneUnitForScenario(unit),
|
||||
|
||||
Reference in New Issue
Block a user