Add Xiapi outer siege chapter
This commit is contained in:
90
src/assets/images/battle/twelfth-battle-map.svg
Normal file
90
src/assets/images/battle/twelfth-battle-map.svg
Normal file
@@ -0,0 +1,90 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3000 2400" width="3000" height="2400">
|
||||
<defs>
|
||||
<filter id="xiapiGrain">
|
||||
<feTurbulence type="fractalNoise" baseFrequency="0.017" numOctaves="4" seed="1212" />
|
||||
<feColorMatrix type="saturate" values="0.68" />
|
||||
<feBlend mode="multiply" in2="SourceGraphic" />
|
||||
</filter>
|
||||
<pattern id="field" width="120" height="120" patternUnits="userSpaceOnUse">
|
||||
<rect width="120" height="120" fill="#5f704d" />
|
||||
<path d="M12 34h34M52 80h42M78 20l24 16M22 104l30-20" stroke="#adc077" stroke-width="4" opacity="0.18" />
|
||||
<path d="M20 68l18-30M62 42l22-20M90 98l14-30" stroke="#283b21" stroke-width="3" opacity="0.34" />
|
||||
</pattern>
|
||||
<pattern id="road" width="126" height="126" patternUnits="userSpaceOnUse">
|
||||
<rect width="126" height="126" fill="#8d7047" />
|
||||
<path d="M0 36c46-20 88 14 126-10M0 90c52-24 86 12 126-4" stroke="#c7a771" stroke-width="9" opacity="0.24" />
|
||||
<path d="M24 100l24-32M70 52l30-22M98 98l14-12" stroke="#3a2c20" stroke-width="4" opacity="0.32" />
|
||||
</pattern>
|
||||
<pattern id="forest" width="140" height="120" patternUnits="userSpaceOnUse">
|
||||
<rect width="140" height="120" fill="#1f3825" />
|
||||
<circle cx="28" cy="52" r="34" fill="#122717" />
|
||||
<circle cx="68" cy="34" r="40" fill="#456842" />
|
||||
<circle cx="112" cy="58" r="34" fill="#213a24" />
|
||||
<circle cx="56" cy="90" r="30" fill="#59774b" />
|
||||
<path d="M12 72c38 18 84 16 118-12M38 26c26 22 62 20 80-8" stroke="#09180d" stroke-width="5" opacity="0.34" />
|
||||
</pattern>
|
||||
<pattern id="hill" width="140" height="110" patternUnits="userSpaceOnUse">
|
||||
<rect width="140" height="110" fill="#766d4b" />
|
||||
<path d="M-16 98c52-70 100-88 146-68c38 18 62 50 82 92" fill="#4b4933" opacity="0.72" />
|
||||
<path d="M20 88c42-46 80-58 118-34" fill="none" stroke="#a39a64" stroke-width="11" opacity="0.26" />
|
||||
</pattern>
|
||||
<linearGradient id="river" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#6e9bad" />
|
||||
<stop offset="0.55" stop-color="#2d637c" />
|
||||
<stop offset="1" stop-color="#153448" />
|
||||
</linearGradient>
|
||||
<linearGradient id="fortWall" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#8b7661" />
|
||||
<stop offset="1" stop-color="#3c3026" />
|
||||
</linearGradient>
|
||||
<radialGradient id="fire" cx="0.5" cy="0.44" r="0.58">
|
||||
<stop offset="0" stop-color="#ffe6a0" />
|
||||
<stop offset="0.48" stop-color="#d6752f" />
|
||||
<stop offset="1" stop-color="#4b1e14" stop-opacity="0" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
<rect width="3000" height="2400" fill="#111a1f" />
|
||||
<rect width="3000" height="2400" fill="url(#field)" opacity="0.96" />
|
||||
<g filter="url(#xiapiGrain)">
|
||||
<path d="M1500-110c-70 344-42 620 84 828c122 202 96 468-76 796c-118 226-140 544-66 954" fill="none" stroke="#13354c" stroke-width="310" stroke-linecap="round" opacity="0.94" />
|
||||
<path d="M1500-110c-70 344-42 620 84 828c122 202 96 468-76 796c-118 226-140 544-66 954" fill="none" stroke="url(#river)" stroke-width="194" stroke-linecap="round" opacity="0.98" />
|
||||
<path d="M2110 250c-88 350-92 710-16 1080c72 350 70 676-32 1030" fill="none" stroke="#13354c" stroke-width="260" stroke-linecap="round" opacity="0.92" />
|
||||
<path d="M2110 250c-88 350-92 710-16 1080c72 350 70 676-32 1030" fill="none" stroke="url(#river)" stroke-width="158" stroke-linecap="round" opacity="0.95" />
|
||||
|
||||
<path d="M-80 1840C384 1780 802 1782 1240 1816c334 26 636 16 948-60c260-64 528-72 906-16" fill="none" stroke="#94754a" stroke-width="250" stroke-linecap="round" opacity="0.82" />
|
||||
<path d="M-80 1840C384 1780 802 1782 1240 1816c334 26 636 16 948-60c260-64 528-72 906-16" fill="none" stroke="url(#road)" stroke-width="138" stroke-linecap="round" opacity="0.9" />
|
||||
<path d="M430 2320C668 1946 956 1640 1294 1402c392-276 790-440 1200-522" fill="none" stroke="#94754a" stroke-width="190" stroke-linecap="round" opacity="0.76" />
|
||||
<path d="M430 2320C668 1946 956 1640 1294 1402c392-276 790-440 1200-522" fill="none" stroke="url(#road)" stroke-width="100" stroke-linecap="round" opacity="0.84" />
|
||||
<path d="M650 1010c360 14 722 12 1086-8c344-18 718-4 1110 40" fill="none" stroke="#94754a" stroke-width="210" stroke-linecap="round" opacity="0.78" />
|
||||
<path d="M650 1010c360 14 722 12 1086-8c344-18 718-4 1110 40" fill="none" stroke="url(#road)" stroke-width="108" stroke-linecap="round" opacity="0.84" />
|
||||
|
||||
<path d="M20 10c308-76 588-22 842 164c-24 222-170 364-438 426C190 536 36 406 20 10Z" fill="url(#forest)" opacity="0.82" />
|
||||
<path d="M360 850c298-122 574-72 828 150c-106 216-382 324-826 324c-116-160-116-318-2-474Z" fill="url(#forest)" opacity="0.82" />
|
||||
<path d="M2230 1650c214-70 418-38 612 96c-44 246-214 414-510 504c-154-108-188-308-102-600Z" fill="url(#forest)" opacity="0.76" />
|
||||
<path d="M620 198c240-76 452-36 636 120c-42 144-168 238-378 282c-168-74-254-208-258-402Z" fill="url(#hill)" opacity="0.82" />
|
||||
<path d="M2420 350c206-66 386-34 540 96c-18 210-126 342-324 396c-154-86-226-250-216-492Z" fill="url(#hill)" opacity="0.82" />
|
||||
<path d="M900 2060c210-62 400-26 570 108c-28 126-144 202-348 228c-142-68-216-180-222-336Z" fill="url(#hill)" opacity="0.76" />
|
||||
|
||||
<g transform="translate(2180 760)">
|
||||
<rect x="-82" y="-66" width="690" height="650" rx="20" fill="#0f0a07" opacity="0.45" />
|
||||
<rect x="0" y="0" width="540" height="520" rx="14" fill="url(#fortWall)" stroke="#211711" stroke-width="20" />
|
||||
<path d="M0 112h540M0 226h540M0 340h540M0 450h540" stroke="#2f251c" stroke-width="14" opacity="0.76" />
|
||||
<path d="M112 0v520M270 0v520M428 0v520" stroke="#67523e" stroke-width="10" opacity="0.48" />
|
||||
<rect x="164" y="218" width="210" height="134" fill="#1f1713" stroke="#0e0907" stroke-width="12" />
|
||||
<path d="M164 218l104-72l106 72" fill="#744923" stroke="#21160e" stroke-width="12" />
|
||||
<path d="M232 352v-82h74v82" fill="#0d0907" />
|
||||
<circle cx="84" cy="144" r="76" fill="url(#fire)" opacity="0.68" />
|
||||
<circle cx="462" cy="374" r="76" fill="url(#fire)" opacity="0.64" />
|
||||
</g>
|
||||
|
||||
<g transform="translate(70 1780)">
|
||||
<rect x="0" y="0" width="245" height="178" rx="10" fill="#594836" stroke="#201914" stroke-width="12" />
|
||||
<path d="M-26 22L122-70l170 92Z" fill="#986230" stroke="#2a1c12" stroke-width="12" />
|
||||
<path d="M76 178v-74h74v74" fill="#201713" />
|
||||
<circle cx="210" cy="30" r="58" fill="url(#fire)" opacity="0.55" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<rect width="3000" height="2400" fill="#000" opacity="0.1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
@@ -19,6 +19,10 @@ import {
|
||||
tenthBattleMap,
|
||||
tenthBattleUnits,
|
||||
tenthBattleVictoryPages,
|
||||
twelfthBattleBonds,
|
||||
twelfthBattleMap,
|
||||
twelfthBattleUnits,
|
||||
twelfthBattleVictoryPages,
|
||||
fifthBattleBonds,
|
||||
fifthBattleMap,
|
||||
fifthBattleUnits,
|
||||
@@ -60,7 +64,8 @@ export type BattleScenarioId =
|
||||
| 'eighth-battle-xiaopei-supply-road'
|
||||
| 'ninth-battle-xuzhou-gate-night-raid'
|
||||
| 'tenth-battle-xuzhou-breakout'
|
||||
| 'eleventh-battle-xudu-refuge-road';
|
||||
| 'eleventh-battle-xudu-refuge-road'
|
||||
| 'twelfth-battle-xiapi-outer-siege';
|
||||
|
||||
export type BattleObjectiveKind = 'defeat-leader' | 'keep-unit-alive' | 'secure-terrain' | 'quick-victory';
|
||||
|
||||
@@ -682,6 +687,59 @@ export const eleventhBattleScenario: BattleScenarioDefinition = {
|
||||
nextCampScene: 'CampScene'
|
||||
};
|
||||
|
||||
export const twelfthBattleScenario: BattleScenarioDefinition = {
|
||||
id: 'twelfth-battle-xiapi-outer-siege',
|
||||
title: '하비 외곽전',
|
||||
victoryConditionLabel: '장료 격파',
|
||||
defeatConditionLabel: '유비 퇴각',
|
||||
openingObjectiveLines: [
|
||||
'조조는 하비 포위망의 남쪽 둑길을 유비군에게 맡깁니다. 장료를 격파하면 여포군 선봉은 성 안으로 물러납니다.',
|
||||
'강줄기와 둑길이 전장을 나눕니다. 여포군 기병은 길을 타고 돌파하고, 성루 궁병과 진궁은 후방에서 압박합니다.',
|
||||
'둑길 진영을 확보하고 20턴 안에 승리하면 조조 휘하에서의 공적과 유비군의 독자 보급을 함께 지킬 수 있습니다.'
|
||||
],
|
||||
map: twelfthBattleMap,
|
||||
units: twelfthBattleUnits,
|
||||
bonds: twelfthBattleBonds,
|
||||
mapTextureKey: 'battle-map-twelfth',
|
||||
leaderUnitId: 'xiapi-leader-zhang-liao',
|
||||
quickVictoryTurnLimit: 20,
|
||||
baseVictoryGold: 1440,
|
||||
objectives: [
|
||||
{
|
||||
id: 'leader',
|
||||
kind: 'defeat-leader',
|
||||
label: '장료 격파',
|
||||
rewardGold: 900,
|
||||
unitId: 'xiapi-leader-zhang-liao'
|
||||
},
|
||||
{
|
||||
id: 'liu-bei',
|
||||
kind: 'keep-unit-alive',
|
||||
label: '유비 생존',
|
||||
rewardGold: 340,
|
||||
unitId: 'liu-bei'
|
||||
},
|
||||
{
|
||||
id: 'camp',
|
||||
kind: 'secure-terrain',
|
||||
label: '하비 둑길 진영 확보',
|
||||
rewardGold: 500,
|
||||
terrain: 'camp'
|
||||
},
|
||||
{
|
||||
id: 'quick',
|
||||
kind: 'quick-victory',
|
||||
label: '20턴 이내 승리',
|
||||
rewardGold: 390,
|
||||
maxTurn: 20
|
||||
}
|
||||
],
|
||||
defeatConditions: [{ kind: 'unit-defeated', unitId: 'liu-bei' }],
|
||||
itemRewards: ['콩 4', '상처약 3', '탁주 2', '하비 포위 공적 +1'],
|
||||
victoryPages: twelfthBattleVictoryPages,
|
||||
nextCampScene: 'CampScene'
|
||||
};
|
||||
|
||||
export const defaultBattleScenarioId: BattleScenarioId = firstBattleScenario.id;
|
||||
|
||||
export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition> = {
|
||||
@@ -695,7 +753,8 @@ export const battleScenarios: Record<BattleScenarioId, BattleScenarioDefinition>
|
||||
'eighth-battle-xiaopei-supply-road': eighthBattleScenario,
|
||||
'ninth-battle-xuzhou-gate-night-raid': ninthBattleScenario,
|
||||
'tenth-battle-xuzhou-breakout': tenthBattleScenario,
|
||||
'eleventh-battle-xudu-refuge-road': eleventhBattleScenario
|
||||
'eleventh-battle-xudu-refuge-road': eleventhBattleScenario,
|
||||
'twelfth-battle-xiapi-outer-siege': twelfthBattleScenario
|
||||
};
|
||||
|
||||
export const defaultBattleScenario = battleScenarios[defaultBattleScenarioId];
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
seventhBattleScenario,
|
||||
sixthBattleScenario,
|
||||
tenthBattleScenario,
|
||||
twelfthBattleScenario,
|
||||
thirdBattleScenario,
|
||||
type BattleScenarioId
|
||||
} from './battles';
|
||||
@@ -33,6 +34,8 @@ import {
|
||||
sixthBattleVictoryPages,
|
||||
tenthBattleIntroPages,
|
||||
tenthBattleVictoryPages,
|
||||
twelfthBattleIntroPages,
|
||||
twelfthBattleVictoryPages,
|
||||
thirdBattleIntroPages,
|
||||
thirdBattleVictoryPages,
|
||||
type StoryPage
|
||||
@@ -153,12 +156,22 @@ const sortieFlows: Record<string, SortieFlow> = {
|
||||
},
|
||||
[eleventhBattleScenario.id]: {
|
||||
afterBattleId: eleventhBattleScenario.id,
|
||||
eyebrow: '다음 전장',
|
||||
title: twelfthBattleScenario.title,
|
||||
description: '조조는 유비군을 하비 포위망에 투입합니다. 여포를 다시 마주하는 이 싸움에서 유비군은 조조의 명을 따르되, 서주 백성을 위한 뜻도 지켜야 합니다.',
|
||||
rewardHint: `예상 보상: ${twelfthBattleScenario.title} 개방`,
|
||||
nextBattleId: twelfthBattleScenario.id,
|
||||
campaignStep: 'twelfth-battle',
|
||||
pages: [...eleventhBattleVictoryPages, ...twelfthBattleIntroPages]
|
||||
},
|
||||
[twelfthBattleScenario.id]: {
|
||||
afterBattleId: twelfthBattleScenario.id,
|
||||
eyebrow: '다음 장 준비',
|
||||
title: '조조의 그늘 아래',
|
||||
description: '허도 입성로를 열어 조조의 장막에 들어섰지만, 유비군은 보호와 감시를 동시에 받게 됩니다. 다음 흐름은 조조 밑에서 기회를 기다리는 장으로 이어집니다.',
|
||||
rewardHint: '다음 장: 조조 휘하의 긴장 준비 중',
|
||||
pages: eleventhBattleVictoryPages,
|
||||
unavailableNotice: '조조 휘하 장은 다음 작업에서 이어집니다. 군영에서 성장과 출전 구성을 정비하십시오.'
|
||||
title: '하비 포위의 끝',
|
||||
description: '하비 외곽 포위망이 좁혀졌고, 여포의 마지막 운명도 가까워졌습니다. 다음 흐름은 여포 토벌의 결말과 조조 밑에서 깊어지는 긴장으로 이어집니다.',
|
||||
rewardHint: '다음 장: 하비 결전과 조조 이탈 준비 중',
|
||||
pages: twelfthBattleVictoryPages,
|
||||
unavailableNotice: '하비 결전과 조조 이탈 장은 다음 작업에서 이어집니다. 군영에서 성장과 출전 구성을 정비하십시오.'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -759,6 +759,60 @@ export const eleventhBattleVictoryPages: StoryPage[] = [
|
||||
}
|
||||
];
|
||||
|
||||
export const twelfthBattleIntroPages: StoryPage[] = [
|
||||
{
|
||||
id: 'twelfth-cao-cao-order',
|
||||
bgm: 'story-dark',
|
||||
chapter: '조조의 명',
|
||||
background: 'story-liu-bei',
|
||||
text: '허도에 머문 지 오래지 않아 조조는 유비군을 하비 포위전에 부른다. 여포를 치는 명령은 서주를 잃은 한을 풀 기회이자, 조조의 칼끝이 어디를 향하는지 가늠하는 시험이었다.'
|
||||
},
|
||||
{
|
||||
id: 'twelfth-xiapi-shadow',
|
||||
bgm: 'militia-theme',
|
||||
chapter: '하비의 물길',
|
||||
background: 'story-militia',
|
||||
speaker: '미축',
|
||||
text: '하비 외곽은 강과 진흙이 얽혀 있습니다. 보급로를 끊고 둑길을 잡지 못하면, 여포군 기병이 포위망의 빈틈을 찢고 나올 것입니다.'
|
||||
},
|
||||
{
|
||||
id: 'twelfth-brothers-before-lubu',
|
||||
bgm: 'story-dark',
|
||||
chapter: '다시 마주한 여포',
|
||||
background: 'story-three-heroes',
|
||||
speaker: '장비',
|
||||
portrait: 'zhangFei',
|
||||
text: '형님, 이번엔 여포의 이름만 들어도 창끝이 뜨겁습니다. 허나 서두르지 않겠습니다. 먼저 포위망을 조이고, 놈의 날뛰는 길을 끊겠습니다.'
|
||||
},
|
||||
{
|
||||
id: 'twelfth-xiapi-sortie',
|
||||
bgm: 'battle-prep',
|
||||
chapter: '하비 외곽전',
|
||||
background: 'story-sortie',
|
||||
speaker: '유비',
|
||||
portrait: 'liuBei',
|
||||
text: '여포를 치는 싸움이 조조의 명이라 해도, 서주 백성이 다시 짓밟히지 않게 하는 일은 우리의 뜻이다. 물길을 잡고 포위망을 열어라.'
|
||||
}
|
||||
];
|
||||
|
||||
export const twelfthBattleVictoryPages: StoryPage[] = [
|
||||
{
|
||||
id: 'twelfth-victory-outer-camp',
|
||||
bgm: 'militia-theme',
|
||||
chapter: '무너진 외곽 진영',
|
||||
background: 'story-militia',
|
||||
text: '유비군은 하비 외곽의 둑길과 보급 진영을 장악했다. 여포군 선봉은 성 안으로 물러났고, 조조군은 포위망을 한층 더 좁혔다.'
|
||||
},
|
||||
{
|
||||
id: 'twelfth-cao-cao-watches',
|
||||
bgm: 'story-dark',
|
||||
chapter: '칭찬과 감시',
|
||||
background: 'story-liu-bei',
|
||||
speaker: '간옹',
|
||||
text: '현덕, 조조는 오늘의 공을 칭찬하겠지만 동시에 더 깊이 살필 걸세. 여포를 치는 동안에도, 우리가 조조의 손안에만 있지 않다는 것을 잊지 말아야 하네.'
|
||||
}
|
||||
];
|
||||
|
||||
export const firstBattleMap: BattleMap = {
|
||||
width: 20,
|
||||
height: 18,
|
||||
@@ -970,6 +1024,12 @@ export const eleventhBattleMap: BattleMap = {
|
||||
terrain: createEleventhBattleTerrain()
|
||||
};
|
||||
|
||||
export const twelfthBattleMap: BattleMap = {
|
||||
width: 30,
|
||||
height: 24,
|
||||
terrain: createTwelfthBattleTerrain()
|
||||
};
|
||||
|
||||
export const firstBattleUnits: UnitData[] = [
|
||||
{
|
||||
id: 'liu-bei',
|
||||
@@ -3834,6 +3894,293 @@ export const eleventhBattleUnits: UnitData[] = [
|
||||
}
|
||||
];
|
||||
|
||||
const twelfthBattleAllyPositions: Record<string, { x: number; y: number }> = {
|
||||
'liu-bei': { x: 3, y: 18 },
|
||||
'guan-yu': { x: 4, y: 17 },
|
||||
'zhang-fei': { x: 4, y: 19 },
|
||||
'jian-yong': { x: 5, y: 20 },
|
||||
'mi-zhu': { x: 3, y: 21 }
|
||||
};
|
||||
|
||||
export const twelfthBattleUnits: UnitData[] = [
|
||||
...[...firstBattleUnits.filter((unit) => unit.faction === 'ally'), ...xuzhouRecruitUnits].map((unit) =>
|
||||
placeScenarioUnit(unit, twelfthBattleAllyPositions[unit.id] ?? { x: unit.x, y: unit.y })
|
||||
),
|
||||
{
|
||||
id: 'xiapi-cavalry-a',
|
||||
name: '여포군 돌격기병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 기병',
|
||||
classKey: 'cavalry',
|
||||
level: 13,
|
||||
exp: 76,
|
||||
hp: 58,
|
||||
maxHp: 58,
|
||||
attack: 20,
|
||||
move: 5,
|
||||
stats: { might: 95, intelligence: 54, leadership: 74, agility: 96, luck: 60 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 54 },
|
||||
armor: { itemId: 'rebel-vest', level: 2, exp: 24 },
|
||||
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
|
||||
},
|
||||
x: 20,
|
||||
y: 5
|
||||
},
|
||||
{
|
||||
id: 'xiapi-cavalry-b',
|
||||
name: '여포군 돌격기병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 기병',
|
||||
classKey: 'cavalry',
|
||||
level: 13,
|
||||
exp: 78,
|
||||
hp: 59,
|
||||
maxHp: 59,
|
||||
attack: 20,
|
||||
move: 5,
|
||||
stats: { might: 96, intelligence: 54, leadership: 74, agility: 97, luck: 60 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 56 },
|
||||
armor: { itemId: 'rebel-vest', level: 2, exp: 24 },
|
||||
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
|
||||
},
|
||||
x: 23,
|
||||
y: 15
|
||||
},
|
||||
{
|
||||
id: 'xiapi-cavalry-c',
|
||||
name: '여포군 돌격기병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 기병',
|
||||
classKey: 'cavalry',
|
||||
level: 13,
|
||||
exp: 78,
|
||||
hp: 59,
|
||||
maxHp: 59,
|
||||
attack: 20,
|
||||
move: 5,
|
||||
stats: { might: 96, intelligence: 55, leadership: 75, agility: 97, luck: 61 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 56 },
|
||||
armor: { itemId: 'rebel-vest', level: 2, exp: 24 },
|
||||
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
|
||||
},
|
||||
x: 25,
|
||||
y: 10
|
||||
},
|
||||
{
|
||||
id: 'xiapi-dike-guard-a',
|
||||
name: '하비 둑길 수비병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 보병',
|
||||
classKey: 'yellowTurban',
|
||||
level: 12,
|
||||
exp: 74,
|
||||
hp: 52,
|
||||
maxHp: 52,
|
||||
attack: 17,
|
||||
move: 3,
|
||||
stats: { might: 86, intelligence: 56, leadership: 72, agility: 65, luck: 57 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 50 },
|
||||
armor: { itemId: 'lamellar-armor', level: 2, exp: 22 },
|
||||
accessory: { itemId: 'yellow-scarf-charm', level: 1, exp: 0 }
|
||||
},
|
||||
x: 12,
|
||||
y: 14
|
||||
},
|
||||
{
|
||||
id: 'xiapi-dike-guard-b',
|
||||
name: '하비 둑길 수비병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 보병',
|
||||
classKey: 'yellowTurban',
|
||||
level: 12,
|
||||
exp: 76,
|
||||
hp: 53,
|
||||
maxHp: 53,
|
||||
attack: 17,
|
||||
move: 3,
|
||||
stats: { might: 87, intelligence: 56, leadership: 73, agility: 66, luck: 57 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 52 },
|
||||
armor: { itemId: 'lamellar-armor', level: 2, exp: 22 },
|
||||
accessory: { itemId: 'yellow-scarf-charm', level: 1, exp: 0 }
|
||||
},
|
||||
x: 14,
|
||||
y: 18
|
||||
},
|
||||
{
|
||||
id: 'xiapi-dike-guard-c',
|
||||
name: '하비 둑길 수비병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 보병',
|
||||
classKey: 'yellowTurban',
|
||||
level: 12,
|
||||
exp: 76,
|
||||
hp: 53,
|
||||
maxHp: 53,
|
||||
attack: 17,
|
||||
move: 3,
|
||||
stats: { might: 87, intelligence: 57, leadership: 73, agility: 66, luck: 57 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 52 },
|
||||
armor: { itemId: 'lamellar-armor', level: 2, exp: 22 },
|
||||
accessory: { itemId: 'yellow-scarf-charm', level: 1, exp: 0 }
|
||||
},
|
||||
x: 17,
|
||||
y: 9
|
||||
},
|
||||
{
|
||||
id: 'xiapi-archer-a',
|
||||
name: '하비 성루 궁병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 궁병',
|
||||
classKey: 'archer',
|
||||
level: 12,
|
||||
exp: 74,
|
||||
hp: 43,
|
||||
maxHp: 43,
|
||||
attack: 18,
|
||||
move: 3,
|
||||
stats: { might: 78, intelligence: 68, leadership: 66, agility: 78, luck: 58 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'short-bow', level: 2, exp: 50 },
|
||||
armor: { itemId: 'cloth-armor', level: 2, exp: 20 },
|
||||
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
|
||||
},
|
||||
x: 22,
|
||||
y: 7
|
||||
},
|
||||
{
|
||||
id: 'xiapi-archer-b',
|
||||
name: '하비 성루 궁병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 궁병',
|
||||
classKey: 'archer',
|
||||
level: 12,
|
||||
exp: 76,
|
||||
hp: 44,
|
||||
maxHp: 44,
|
||||
attack: 18,
|
||||
move: 3,
|
||||
stats: { might: 79, intelligence: 69, leadership: 67, agility: 79, luck: 58 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'short-bow', level: 2, exp: 52 },
|
||||
armor: { itemId: 'cloth-armor', level: 2, exp: 20 },
|
||||
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
|
||||
},
|
||||
x: 24,
|
||||
y: 18
|
||||
},
|
||||
{
|
||||
id: 'xiapi-archer-c',
|
||||
name: '하비 성루 궁병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 궁병',
|
||||
classKey: 'archer',
|
||||
level: 12,
|
||||
exp: 76,
|
||||
hp: 44,
|
||||
maxHp: 44,
|
||||
attack: 18,
|
||||
move: 3,
|
||||
stats: { might: 79, intelligence: 69, leadership: 67, agility: 79, luck: 58 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'short-bow', level: 2, exp: 52 },
|
||||
armor: { itemId: 'cloth-armor', level: 2, exp: 20 },
|
||||
accessory: { itemId: 'wind-quiver', level: 1, exp: 0 }
|
||||
},
|
||||
x: 19,
|
||||
y: 3
|
||||
},
|
||||
{
|
||||
id: 'xiapi-camp-raider-a',
|
||||
name: '여포군 기습병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 기습병',
|
||||
classKey: 'bandit',
|
||||
level: 12,
|
||||
exp: 74,
|
||||
hp: 48,
|
||||
maxHp: 48,
|
||||
attack: 18,
|
||||
move: 4,
|
||||
stats: { might: 88, intelligence: 55, leadership: 64, agility: 81, luck: 58 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 50 },
|
||||
armor: { itemId: 'rebel-vest', level: 2, exp: 22 },
|
||||
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
|
||||
},
|
||||
x: 9,
|
||||
y: 8
|
||||
},
|
||||
{
|
||||
id: 'xiapi-camp-raider-b',
|
||||
name: '여포군 기습병',
|
||||
faction: 'enemy',
|
||||
className: '여포군 기습병',
|
||||
classKey: 'bandit',
|
||||
level: 12,
|
||||
exp: 76,
|
||||
hp: 49,
|
||||
maxHp: 49,
|
||||
attack: 18,
|
||||
move: 4,
|
||||
stats: { might: 89, intelligence: 55, leadership: 64, agility: 82, luck: 58 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'yellow-turban-saber', level: 2, exp: 52 },
|
||||
armor: { itemId: 'rebel-vest', level: 2, exp: 22 },
|
||||
accessory: { itemId: 'grain-pouch', level: 1, exp: 0 }
|
||||
},
|
||||
x: 11,
|
||||
y: 21
|
||||
},
|
||||
{
|
||||
id: 'xiapi-strategist-chen-gong',
|
||||
name: '진궁',
|
||||
faction: 'enemy',
|
||||
className: '여포군 책사',
|
||||
classKey: 'strategist',
|
||||
level: 13,
|
||||
exp: 82,
|
||||
hp: 52,
|
||||
maxHp: 52,
|
||||
attack: 18,
|
||||
move: 3,
|
||||
stats: { might: 62, intelligence: 96, leadership: 84, agility: 70, luck: 64 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'short-bow', level: 2, exp: 54 },
|
||||
armor: { itemId: 'cloth-armor', level: 2, exp: 22 },
|
||||
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
|
||||
},
|
||||
x: 22,
|
||||
y: 12
|
||||
},
|
||||
{
|
||||
id: 'xiapi-leader-zhang-liao',
|
||||
name: '장료',
|
||||
faction: 'enemy',
|
||||
className: '여포군 선봉장',
|
||||
classKey: 'rebelLeader',
|
||||
level: 14,
|
||||
exp: 86,
|
||||
hp: 78,
|
||||
maxHp: 78,
|
||||
attack: 21,
|
||||
move: 5,
|
||||
stats: { might: 95, intelligence: 78, leadership: 92, agility: 86, luck: 63 },
|
||||
equipment: {
|
||||
weapon: { itemId: 'leader-axe', level: 2, exp: 58 },
|
||||
armor: { itemId: 'reinforced-lamellar', level: 2, exp: 26 },
|
||||
accessory: { itemId: 'war-manual', level: 1, exp: 0 }
|
||||
},
|
||||
x: 24,
|
||||
y: 11
|
||||
}
|
||||
];
|
||||
|
||||
export const firstBattleBonds: BattleBond[] = [
|
||||
{
|
||||
id: 'liu-bei__guan-yu',
|
||||
@@ -3890,6 +4237,7 @@ export const eighthBattleBonds: BattleBond[] = [...firstBattleBonds, ...xuzhouRe
|
||||
export const ninthBattleBonds: BattleBond[] = eighthBattleBonds.map(cloneBattleBondForScenario);
|
||||
export const tenthBattleBonds: BattleBond[] = ninthBattleBonds.map(cloneBattleBondForScenario);
|
||||
export const eleventhBattleBonds: BattleBond[] = tenthBattleBonds.map(cloneBattleBondForScenario);
|
||||
export const twelfthBattleBonds: BattleBond[] = eleventhBattleBonds.map(cloneBattleBondForScenario);
|
||||
|
||||
function createEighthBattleTerrain(): TerrainType[][] {
|
||||
return Array.from({ length: 22 }, (_, y) =>
|
||||
@@ -4046,6 +4394,44 @@ function createEleventhBattleTerrain(): TerrainType[][] {
|
||||
);
|
||||
}
|
||||
|
||||
function createTwelfthBattleTerrain(): TerrainType[][] {
|
||||
return Array.from({ length: 24 }, (_, y) =>
|
||||
Array.from({ length: 30 }, (_, x): TerrainType => {
|
||||
if (x <= 2 && y >= 17 && y <= 22) {
|
||||
return 'camp';
|
||||
}
|
||||
if ((x >= 23 && x <= 27 && y >= 8 && y <= 13) || (x >= 20 && x <= 24 && y >= 2 && y <= 4)) {
|
||||
return 'fort';
|
||||
}
|
||||
if ((x >= 10 && x <= 12 && y >= 16 && y <= 18) || (x >= 16 && x <= 18 && y >= 7 && y <= 9)) {
|
||||
return 'village';
|
||||
}
|
||||
if ((x === 14 || x === 15) && y >= 0 && y <= 22) {
|
||||
return 'river';
|
||||
}
|
||||
if ((x === 20 || x === 21) && y >= 4 && y <= 20) {
|
||||
return 'river';
|
||||
}
|
||||
if ((x >= 12 && x <= 22 && y === 12) || (x >= 4 && x <= 13 && y === 18) || (x >= 6 && x <= 24 && y === 10)) {
|
||||
return 'road';
|
||||
}
|
||||
if ((x >= 2 && x <= 26 && y === x - 2) || (x >= 3 && x <= 15 && y === 21 - x)) {
|
||||
return 'road';
|
||||
}
|
||||
if ((x <= 8 && y <= 8) || (x >= 4 && x <= 11 && y >= 9 && y <= 13) || (x >= 22 && y >= 16 && y <= 22)) {
|
||||
return 'forest';
|
||||
}
|
||||
if ((x >= 6 && x <= 10 && y >= 2 && y <= 5) || (x >= 24 && x <= 28 && y >= 4 && y <= 8) || (x >= 9 && x <= 13 && y >= 20)) {
|
||||
return 'hill';
|
||||
}
|
||||
if ((x >= 27 && y <= 4) || (x >= 27 && y >= 15) || (x <= 1 && y <= 4)) {
|
||||
return 'cliff';
|
||||
}
|
||||
return 'plain';
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function placeScenarioUnit(unit: UnitData, position: { x: number; y: number }): UnitData {
|
||||
return {
|
||||
...cloneUnitForScenario(unit),
|
||||
|
||||
@@ -60,7 +60,20 @@ const unitTexture: Record<string, string> = {
|
||||
'xuzhou-cavalry-c': 'unit-rebel-cavalry',
|
||||
'xuzhou-guard-b': 'unit-rebel',
|
||||
'xuzhou-archer-c': 'unit-rebel-archer',
|
||||
'xuzhou-leader-xiahou-dun': 'unit-rebel-leader'
|
||||
'xuzhou-leader-xiahou-dun': 'unit-rebel-leader',
|
||||
'xiapi-cavalry-a': 'unit-rebel-cavalry',
|
||||
'xiapi-cavalry-b': 'unit-rebel-cavalry',
|
||||
'xiapi-cavalry-c': 'unit-rebel-cavalry',
|
||||
'xiapi-dike-guard-a': 'unit-rebel',
|
||||
'xiapi-dike-guard-b': 'unit-rebel',
|
||||
'xiapi-dike-guard-c': 'unit-rebel',
|
||||
'xiapi-archer-a': 'unit-rebel-archer',
|
||||
'xiapi-archer-b': 'unit-rebel-archer',
|
||||
'xiapi-archer-c': 'unit-rebel-archer',
|
||||
'xiapi-camp-raider-a': 'unit-rebel',
|
||||
'xiapi-camp-raider-b': 'unit-rebel',
|
||||
'xiapi-strategist-chen-gong': 'unit-rebel-archer',
|
||||
'xiapi-leader-zhang-liao': 'unit-rebel-leader'
|
||||
};
|
||||
|
||||
const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
||||
@@ -568,7 +581,20 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
|
||||
'xudu-road-cavalry-b': 'aggressive',
|
||||
'xudu-road-guard-a': 'guard',
|
||||
'xudu-road-guard-b': 'guard',
|
||||
'xudu-road-leader-ji-ling': 'guard'
|
||||
'xudu-road-leader-ji-ling': 'guard',
|
||||
'xiapi-cavalry-a': 'aggressive',
|
||||
'xiapi-cavalry-b': 'aggressive',
|
||||
'xiapi-cavalry-c': 'aggressive',
|
||||
'xiapi-dike-guard-a': 'guard',
|
||||
'xiapi-dike-guard-b': 'guard',
|
||||
'xiapi-dike-guard-c': 'guard',
|
||||
'xiapi-archer-a': 'hold',
|
||||
'xiapi-archer-b': 'hold',
|
||||
'xiapi-archer-c': 'hold',
|
||||
'xiapi-camp-raider-a': 'aggressive',
|
||||
'xiapi-camp-raider-b': 'aggressive',
|
||||
'xiapi-strategist-chen-gong': 'hold',
|
||||
'xiapi-leader-zhang-liao': 'guard'
|
||||
};
|
||||
|
||||
const defaultEnemyAiByClass: Partial<Record<UnitClassKey, EnemyAiBehavior>> = {
|
||||
|
||||
@@ -10,6 +10,7 @@ import seventhBattleMapUrl from '../../assets/images/battle/seventh-battle-map.s
|
||||
import sixthBattleMapUrl from '../../assets/images/battle/sixth-battle-map.svg';
|
||||
import tenthBattleMapUrl from '../../assets/images/battle/tenth-battle-map.svg';
|
||||
import thirdBattleMapUrl from '../../assets/images/battle/third-battle-map.svg';
|
||||
import twelfthBattleMapUrl from '../../assets/images/battle/twelfth-battle-map.svg';
|
||||
import guanYuPortraitUrl from '../../assets/images/portraits/guan-yu.png';
|
||||
import liuBeiPortraitUrl from '../../assets/images/portraits/liu-bei.png';
|
||||
import zhangFeiPortraitUrl from '../../assets/images/portraits/zhang-fei.png';
|
||||
@@ -80,6 +81,7 @@ export class BootScene extends Phaser.Scene {
|
||||
this.load.image('battle-map-ninth', ninthBattleMapUrl);
|
||||
this.load.image('battle-map-tenth', tenthBattleMapUrl);
|
||||
this.load.image('battle-map-eleventh', eleventhBattleMapUrl);
|
||||
this.load.image('battle-map-twelfth', twelfthBattleMapUrl);
|
||||
this.load.image('portrait-liu-bei', liuBeiPortraitUrl);
|
||||
this.load.image('portrait-guan-yu', guanYuPortraitUrl);
|
||||
this.load.image('portrait-zhang-fei', zhangFeiPortraitUrl);
|
||||
|
||||
@@ -176,7 +176,8 @@ const campBattleIds = {
|
||||
eighth: 'eighth-battle-xiaopei-supply-road',
|
||||
ninth: 'ninth-battle-xuzhou-gate-night-raid',
|
||||
tenth: 'tenth-battle-xuzhou-breakout',
|
||||
eleventh: 'eleventh-battle-xudu-refuge-road'
|
||||
eleventh: 'eleventh-battle-xudu-refuge-road',
|
||||
twelfth: 'twelfth-battle-xiapi-outer-siege'
|
||||
} as const;
|
||||
|
||||
const requiredSortieUnitIds = new Set(['liu-bei']);
|
||||
@@ -288,6 +289,16 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
||||
{ unitId: 'mi-zhu', reason: '허도 입성 전 보급 안정에 유리합니다.' }
|
||||
],
|
||||
note: '허도 입성로는 조조군의 감시를 받는 시험입니다. 군율과 보급을 보여줄 무장을 챙기십시오.'
|
||||
},
|
||||
'twelfth-battle-xiapi-outer-siege': {
|
||||
maxUnits: 5,
|
||||
recommended: [
|
||||
{ unitId: 'liu-bei', reason: '조조 휘하 작전에서도 유비군의 명분을 지켜야 합니다.' },
|
||||
{ unitId: 'zhang-fei', reason: '여포군 기병 돌파를 막고 둑길을 압박합니다.' },
|
||||
{ unitId: 'jian-yong', reason: '조조군 감시 속 명분과 보고 문서를 조율합니다.' },
|
||||
{ unitId: 'mi-zhu', reason: '강가 포위전의 보급과 회복 운용에 유리합니다.' }
|
||||
],
|
||||
note: '하비 외곽전은 강줄기와 둑길이 전장을 나눕니다. 돌파와 보급, 조조군 보고까지 함께 고려하십시오.'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1236,6 +1247,87 @@ const campDialogues: CampDialogue[] = [
|
||||
rewardExp: 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-zhang-after-xiapi-outer',
|
||||
title: '창끝을 누르는 법',
|
||||
availableAfterBattleIds: [campBattleIds.twelfth],
|
||||
unitIds: ['liu-bei', 'zhang-fei'],
|
||||
bondId: 'liu-bei__zhang-fei',
|
||||
rewardExp: 22,
|
||||
lines: [
|
||||
'장비: 형님, 여포 놈의 깃발이 눈앞에 있는데도 창을 참는 일이 쉽지 않았습니다.',
|
||||
'유비: 참았기에 포위망이 무너지지 않았다. 익덕의 창은 분노보다 늦게 나갈 때 더 무겁소.',
|
||||
'장비: 다음에는 여포의 말발굽보다 먼저 제 마음을 묶어 두겠습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'praise-restraint',
|
||||
label: '참은 공을 칭찬한다',
|
||||
response: '장비는 호통보다 뜻밖의 칭찬에 더 깊이 고개를 숙였고, 다음 싸움에서도 전열을 지키겠다고 다짐했다.',
|
||||
rewardExp: 10
|
||||
},
|
||||
{
|
||||
id: 'assign-dike-front',
|
||||
label: '둑길 전열을 맡긴다',
|
||||
response: '장비는 자신이 앞에서 버티면 여포군 기병도 쉽게 뚫지 못할 것이라며 창대를 움켜쥐었다.',
|
||||
rewardExp: 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-jian-yong-after-xiapi-outer',
|
||||
title: '공적을 쓰는 붓',
|
||||
availableAfterBattleIds: [campBattleIds.twelfth],
|
||||
unitIds: ['liu-bei', 'jian-yong'],
|
||||
bondId: 'liu-bei__jian-yong',
|
||||
rewardExp: 20,
|
||||
lines: [
|
||||
'간옹: 오늘 공적은 조조의 장부에도 오르겠지만, 그 장부가 우리 목줄이 되지 않게 써야 하네.',
|
||||
'유비: 공을 세워도 빚이 되고, 물러서도 의심이 되는 형국이오.',
|
||||
'간옹: 그래서 말의 끝을 남겨야지. 우리는 조조를 위해서만 싸운 것이 아니라 서주 백성을 위해 싸웠다고.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'record-people-first',
|
||||
label: '백성 보호를 먼저 기록한다',
|
||||
response: '간옹은 전공 보고의 첫 줄에 피난민과 보급로 보호를 적어 유비군의 명분을 분명히 했다.',
|
||||
rewardExp: 9
|
||||
},
|
||||
{
|
||||
id: 'keep-private-notes',
|
||||
label: '별도 기록을 남긴다',
|
||||
response: '간옹은 조조에게 보일 보고와 훗날 유비군이 기억할 기록을 따로 남겼다.',
|
||||
rewardExp: 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-mi-after-xiapi-outer',
|
||||
title: '물가의 보급선',
|
||||
availableAfterBattleIds: [campBattleIds.twelfth],
|
||||
unitIds: ['liu-bei', 'mi-zhu'],
|
||||
bondId: 'liu-bei__mi-zhu',
|
||||
rewardExp: 18,
|
||||
lines: [
|
||||
'미축: 강가 포위전은 싸움보다 군량이 먼저 흔들립니다. 조조군 배급만 믿으면 우리 병사 마음도 함께 묶입니다.',
|
||||
'유비: 독자 보급이 곧 독자적인 마음이오. 작은 양이라도 우리가 스스로 마련할 길을 남깁시다.',
|
||||
'미축: 그렇다면 하비 외곽에서 거둔 전리품은 공용과 예비로 나누어 두겠습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'split-siege-supplies',
|
||||
label: '보급을 둘로 나눈다',
|
||||
response: '미축은 조조군 공용 보급과 유비군 예비 보급을 나누어, 훗날 떠날 수 있는 여지를 남겼다.',
|
||||
rewardExp: 8
|
||||
},
|
||||
{
|
||||
id: 'secure-river-cart',
|
||||
label: '강가 수레를 확보한다',
|
||||
response: '미축은 강가에서 쓸 수레와 배를 따로 챙겨 다음 포위전의 군량 흐름을 안정시켰다.',
|
||||
rewardExp: 8
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1319,7 +1411,8 @@ export class CampScene extends Phaser.Scene {
|
||||
battleId !== campBattleIds.eighth &&
|
||||
battleId !== campBattleIds.ninth &&
|
||||
battleId !== campBattleIds.tenth &&
|
||||
battleId !== campBattleIds.eleventh) ||
|
||||
battleId !== campBattleIds.eleventh &&
|
||||
battleId !== campBattleIds.twelfth) ||
|
||||
!this.campaign
|
||||
) {
|
||||
return;
|
||||
@@ -1341,6 +1434,9 @@ export class CampScene extends Phaser.Scene {
|
||||
|
||||
private currentCampTitle() {
|
||||
const battleId = this.currentCampBattleId();
|
||||
if (battleId === campBattleIds.twelfth) {
|
||||
return '하비 포위 군영';
|
||||
}
|
||||
if (battleId === campBattleIds.eleventh) {
|
||||
return '허도 의탁 군영';
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
seventhBattleScenario,
|
||||
sixthBattleScenario,
|
||||
tenthBattleScenario,
|
||||
twelfthBattleScenario,
|
||||
thirdBattleScenario
|
||||
} from '../data/battles';
|
||||
import { hasCampaignSave, loadCampaignState, startNewCampaign } from '../state/campaignState';
|
||||
@@ -321,7 +322,8 @@ export class TitleScene extends Phaser.Scene {
|
||||
campaign.step === 'eighth-camp' ||
|
||||
campaign.step === 'ninth-camp' ||
|
||||
campaign.step === 'tenth-camp' ||
|
||||
campaign.step === 'eleventh-camp'
|
||||
campaign.step === 'eleventh-camp' ||
|
||||
campaign.step === 'twelfth-camp'
|
||||
) {
|
||||
this.scene.start('CampScene');
|
||||
return;
|
||||
@@ -382,6 +384,11 @@ export class TitleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'twelfth-battle') {
|
||||
this.scene.start('BattleScene', { battleId: twelfthBattleScenario.id });
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'first-victory-story') {
|
||||
this.scene.start('StoryScene', { pages: firstBattleVictoryPages, nextScene: 'TitleScene' });
|
||||
return;
|
||||
|
||||
@@ -61,7 +61,9 @@ export type CampaignStep =
|
||||
| 'tenth-battle'
|
||||
| 'tenth-camp'
|
||||
| 'eleventh-battle'
|
||||
| 'eleventh-camp';
|
||||
| 'eleventh-camp'
|
||||
| 'twelfth-battle'
|
||||
| 'twelfth-camp';
|
||||
|
||||
export type CampaignUnitProgressSnapshot = {
|
||||
unitId: string;
|
||||
@@ -123,7 +125,8 @@ const campaignBattleSteps: Record<string, { victory: CampaignStep; retry: Campai
|
||||
'eighth-battle-xiaopei-supply-road': { victory: 'eighth-camp', retry: 'eighth-battle' },
|
||||
'ninth-battle-xuzhou-gate-night-raid': { victory: 'ninth-camp', retry: 'ninth-battle' },
|
||||
'tenth-battle-xuzhou-breakout': { victory: 'tenth-camp', retry: 'tenth-battle' },
|
||||
'eleventh-battle-xudu-refuge-road': { victory: 'eleventh-camp', retry: 'eleventh-battle' }
|
||||
'eleventh-battle-xudu-refuge-road': { victory: 'eleventh-camp', retry: 'eleventh-battle' },
|
||||
'twelfth-battle-xiapi-outer-siege': { victory: 'twelfth-camp', retry: 'twelfth-battle' }
|
||||
};
|
||||
|
||||
export type CampaignSaveSlotSummary = {
|
||||
|
||||
Reference in New Issue
Block a user