Add Yuan Shao refuge road chapter
This commit is contained in:
@@ -103,7 +103,24 @@ const unitTexture: Record<string, string> = {
|
||||
'cao-break-cavalry-c': 'unit-rebel-cavalry',
|
||||
'cao-break-guard-a': 'unit-rebel',
|
||||
'cao-break-guard-b': 'unit-rebel',
|
||||
'cao-break-leader-che-zhou': 'unit-rebel-leader'
|
||||
'cao-break-leader-che-zhou': 'unit-rebel-leader',
|
||||
'yuan-refuge-scout-a': 'unit-rebel',
|
||||
'yuan-refuge-scout-b': 'unit-rebel',
|
||||
'yuan-refuge-infantry-a': 'unit-rebel',
|
||||
'yuan-refuge-infantry-b': 'unit-rebel',
|
||||
'yuan-refuge-infantry-c': 'unit-rebel',
|
||||
'yuan-refuge-infantry-d': 'unit-rebel',
|
||||
'yuan-refuge-archer-a': 'unit-rebel-archer',
|
||||
'yuan-refuge-archer-b': 'unit-rebel-archer',
|
||||
'yuan-refuge-archer-c': 'unit-rebel-archer',
|
||||
'yuan-refuge-cavalry-a': 'unit-rebel-cavalry',
|
||||
'yuan-refuge-cavalry-b': 'unit-rebel-cavalry',
|
||||
'yuan-refuge-cavalry-c': 'unit-rebel-cavalry',
|
||||
'yuan-refuge-guard-a': 'unit-rebel',
|
||||
'yuan-refuge-guard-b': 'unit-rebel',
|
||||
'yuan-refuge-guard-c': 'unit-rebel',
|
||||
'yuan-refuge-strategist-a': 'unit-rebel-archer',
|
||||
'yuan-refuge-leader-cai-yang': 'unit-rebel-leader'
|
||||
};
|
||||
|
||||
const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
||||
@@ -655,7 +672,24 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
|
||||
'cao-break-cavalry-c': 'aggressive',
|
||||
'cao-break-guard-a': 'guard',
|
||||
'cao-break-guard-b': 'guard',
|
||||
'cao-break-leader-che-zhou': 'guard'
|
||||
'cao-break-leader-che-zhou': 'guard',
|
||||
'yuan-refuge-scout-a': 'aggressive',
|
||||
'yuan-refuge-scout-b': 'aggressive',
|
||||
'yuan-refuge-infantry-a': 'guard',
|
||||
'yuan-refuge-infantry-b': 'guard',
|
||||
'yuan-refuge-infantry-c': 'guard',
|
||||
'yuan-refuge-infantry-d': 'guard',
|
||||
'yuan-refuge-archer-a': 'hold',
|
||||
'yuan-refuge-archer-b': 'hold',
|
||||
'yuan-refuge-archer-c': 'hold',
|
||||
'yuan-refuge-cavalry-a': 'aggressive',
|
||||
'yuan-refuge-cavalry-b': 'aggressive',
|
||||
'yuan-refuge-cavalry-c': 'aggressive',
|
||||
'yuan-refuge-guard-a': 'guard',
|
||||
'yuan-refuge-guard-b': 'guard',
|
||||
'yuan-refuge-guard-c': 'guard',
|
||||
'yuan-refuge-strategist-a': 'hold',
|
||||
'yuan-refuge-leader-cai-yang': 'guard'
|
||||
};
|
||||
|
||||
const defaultEnemyAiByClass: Partial<Record<UnitClassKey, EnemyAiBehavior>> = {
|
||||
|
||||
@@ -2,6 +2,7 @@ import Phaser from 'phaser';
|
||||
import eighthBattleMapUrl from '../../assets/images/battle/eighth-battle-map.svg';
|
||||
import eleventhBattleMapUrl from '../../assets/images/battle/eleventh-battle-map.svg';
|
||||
import fifthBattleMapUrl from '../../assets/images/battle/fifth-battle-map.svg';
|
||||
import fifteenthBattleMapUrl from '../../assets/images/battle/fifteenth-battle-map.svg';
|
||||
import firstBattleMapUrl from '../../assets/images/battle/first-battle-map.png';
|
||||
import fourteenthBattleMapUrl from '../../assets/images/battle/fourteenth-battle-map.svg';
|
||||
import fourthBattleMapUrl from '../../assets/images/battle/fourth-battle-map.svg';
|
||||
@@ -86,6 +87,7 @@ export class BootScene extends Phaser.Scene {
|
||||
this.load.image('battle-map-twelfth', twelfthBattleMapUrl);
|
||||
this.load.image('battle-map-thirteenth', thirteenthBattleMapUrl);
|
||||
this.load.image('battle-map-fourteenth', fourteenthBattleMapUrl);
|
||||
this.load.image('battle-map-fifteenth', fifteenthBattleMapUrl);
|
||||
this.load.image('portrait-liu-bei', liuBeiPortraitUrl);
|
||||
this.load.image('portrait-guan-yu', guanYuPortraitUrl);
|
||||
this.load.image('portrait-zhang-fei', zhangFeiPortraitUrl);
|
||||
|
||||
@@ -193,7 +193,8 @@ const campBattleIds = {
|
||||
eleventh: 'eleventh-battle-xudu-refuge-road',
|
||||
twelfth: 'twelfth-battle-xiapi-outer-siege',
|
||||
thirteenth: 'thirteenth-battle-xiapi-final',
|
||||
fourteenth: 'fourteenth-battle-cao-break'
|
||||
fourteenth: 'fourteenth-battle-cao-break',
|
||||
fifteenth: 'fifteenth-battle-yuan-refuge-road'
|
||||
} as const;
|
||||
|
||||
const requiredSortieUnitIds = new Set(['liu-bei']);
|
||||
@@ -337,6 +338,17 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
||||
{ unitId: 'mi-zhu', reason: '보급과 회복 도구 운용으로 장기전을 안정시킵니다.' }
|
||||
],
|
||||
note: '차주의 관문은 길과 강이 겹쳐 전열, 기동, 책사, 보급이 모두 필요합니다. 새로 합류한 손건도 출전 후보로 살펴보십시오.'
|
||||
},
|
||||
'fifteenth-battle-yuan-refuge-road': {
|
||||
maxUnits: 6,
|
||||
recommended: [
|
||||
{ unitId: 'liu-bei', reason: '원소 진영에 의탁할 명분과 생존 조건을 모두 짊어집니다.' },
|
||||
{ unitId: 'guan-yu', reason: '채양의 수비선을 정면에서 무너뜨릴 전열 핵심입니다.' },
|
||||
{ unitId: 'zhang-fei', reason: '추격 기병의 돌파를 받아치고 북상로를 벌리는 데 강합니다.' },
|
||||
{ unitId: 'jian-yong', reason: '원소 사자와의 접선 명분을 조율하고 책략 지원을 맡습니다.' },
|
||||
{ unitId: 'sun-qian', reason: '문서와 외교 판단으로 접선지 확보 목표에 직접 힘을 보탭니다.' }
|
||||
],
|
||||
note: '원소 의탁로는 추격 기병과 고지 궁병이 함께 압박합니다. 전열을 두껍게 세우되 책사와 보급 장수도 빼지 않는 편이 안정적입니다.'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1528,6 +1540,87 @@ const campDialogues: CampDialogue[] = [
|
||||
rewardExp: 8
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-jian-after-yuan-refuge',
|
||||
title: '큰 깃발 아래의 말',
|
||||
availableAfterBattleIds: [campBattleIds.fifteenth],
|
||||
unitIds: ['liu-bei', 'jian-yong'],
|
||||
bondId: 'liu-bei__jian-yong',
|
||||
rewardExp: 22,
|
||||
lines: [
|
||||
'간옹: 원소의 장막은 크지만, 그 안의 사람들 말도 그만큼 큽니다. 주공의 이름이 오래 머물수록 여러 귀에 다르게 들릴 것입니다.',
|
||||
'유비: 우리가 의탁한 것은 몸이지 뜻이 아니오. 그러나 그 뜻을 지키려면 지금은 말 한마디도 조심해야 하겠지.',
|
||||
'간옹: 그렇다면 제가 먼저 가벼운 말로 무거운 시선을 흩뜨리겠습니다. 주공께서는 백성을 향한 뜻만 흐리지 마십시오.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'measure-words-in-yuan-camp',
|
||||
label: '말을 낮추고 뜻을 숨긴다',
|
||||
response: '간옹은 원소 진영의 술자리와 군막 사이를 오가며 유비군의 속내가 쉽게 드러나지 않도록 말을 다듬었다.',
|
||||
rewardExp: 9
|
||||
},
|
||||
{
|
||||
id: 'keep-liu-bei-name-clean',
|
||||
label: '유비의 명분을 조용히 남긴다',
|
||||
response: '간옹은 크게 외치지 않는 방식으로 유비가 조조를 떠난 이유와 백성을 살핀 행적을 진영 곳곳에 흘렸다.',
|
||||
rewardExp: 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-sun-after-yuan-refuge',
|
||||
title: '의탁의 문서',
|
||||
availableAfterBattleIds: [campBattleIds.fifteenth],
|
||||
unitIds: ['liu-bei', 'sun-qian'],
|
||||
bondId: 'liu-bei__sun-qian',
|
||||
rewardExp: 22,
|
||||
lines: [
|
||||
'손건: 원소에게 보낼 문서는 이미 통과했지만, 머무는 동안의 문서가 더 중요합니다. 작은 약속이 나중에 큰 족쇄가 될 수 있습니다.',
|
||||
'유비: 지금 얻은 쉼터가 훗날 발목을 잡아서는 안 되겠지. 우리가 받은 은혜는 잊지 않되, 길을 잃지는 말아야 하오.',
|
||||
'손건: 그 뜻을 문서마다 남기겠습니다. 주공의 군은 원소의 사병이 아니라, 난세를 건너는 의로운 객군으로 남아야 합니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'write-guest-army-status',
|
||||
label: '객군의 지위를 분명히 한다',
|
||||
response: '손건은 유비군의 지위를 원소 진영의 객군으로 적어, 명령 체계에 휩쓸릴 여지를 줄였다.',
|
||||
rewardExp: 10
|
||||
},
|
||||
{
|
||||
id: 'record-cao-pursuit-proof',
|
||||
label: '조조 추격의 증거를 남긴다',
|
||||
response: '손건은 채양 추격대의 움직임을 기록해 조조와의 긴장이 실제였음을 원소 진영에 설득할 근거로 남겼다.',
|
||||
rewardExp: 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'zhang-mi-after-yuan-refuge',
|
||||
title: '낯선 군영의 밥',
|
||||
availableAfterBattleIds: [campBattleIds.fifteenth],
|
||||
unitIds: ['zhang-fei', 'mi-zhu'],
|
||||
bondId: 'liu-bei__mi-zhu',
|
||||
rewardExp: 18,
|
||||
lines: [
|
||||
'장비: 원소군 밥은 양은 많아도 속이 편치 않소. 남의 군량을 먹으니 창끝까지 남의 눈치를 보는 기분이오.',
|
||||
'미축: 그래서 우리 몫의 장부를 따로 두려 합니다. 받은 것은 받은 대로, 쓴 것은 쓴 대로 남겨야 훗날 떳떳하게 떠날 수 있습니다.',
|
||||
'장비: 좋소. 그럼 나는 병사들이 주눅 들지 않게 술 대신 목소리를 나눠 주겠소. 배가 차도 기가 죽으면 싸움은 못 하니까.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'separate-supply-ledger',
|
||||
label: '보급 장부를 따로 둔다',
|
||||
response: '미축은 유비군의 군량 장부를 따로 정리해 원소 진영에 빚이 쌓이는 일을 줄였고, 장비는 병사들에게 그 뜻을 크게 알렸다.',
|
||||
rewardExp: 8
|
||||
},
|
||||
{
|
||||
id: 'raise-camp-spirits',
|
||||
label: '병사들의 사기를 다독인다',
|
||||
response: '장비는 낯선 군영에서 움츠러든 병사들을 불러 세워 웃음과 호통으로 사기를 끌어올렸고, 미축은 작은 술과 밥을 나눴다.',
|
||||
rewardExp: 8
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1610,7 +1703,11 @@ export class CampScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.thirteenth || battleId === campBattleIds.fourteenth) {
|
||||
if (
|
||||
battleId === campBattleIds.thirteenth ||
|
||||
battleId === campBattleIds.fourteenth ||
|
||||
battleId === campBattleIds.fifteenth
|
||||
) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[...xuzhouRecruitUnits, ...caoBreakRecruitUnits],
|
||||
[...xuzhouRecruitBonds, ...caoBreakRecruitBonds]
|
||||
@@ -1646,6 +1743,9 @@ export class CampScene extends Phaser.Scene {
|
||||
|
||||
private currentCampTitle() {
|
||||
const battleId = this.currentCampBattleId();
|
||||
if (battleId === campBattleIds.fifteenth) {
|
||||
return '원소 의탁 후 군영';
|
||||
}
|
||||
if (battleId === campBattleIds.fourteenth) {
|
||||
return '서주 재기 후 군영';
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
eighthBattleScenario,
|
||||
eleventhBattleScenario,
|
||||
fifthBattleScenario,
|
||||
fifteenthBattleScenario,
|
||||
fourteenthBattleScenario,
|
||||
fourthBattleScenario,
|
||||
ninthBattleScenario,
|
||||
@@ -327,7 +328,8 @@ export class TitleScene extends Phaser.Scene {
|
||||
campaign.step === 'eleventh-camp' ||
|
||||
campaign.step === 'twelfth-camp' ||
|
||||
campaign.step === 'thirteenth-camp' ||
|
||||
campaign.step === 'fourteenth-camp'
|
||||
campaign.step === 'fourteenth-camp' ||
|
||||
campaign.step === 'fifteenth-camp'
|
||||
) {
|
||||
this.scene.start('CampScene');
|
||||
return;
|
||||
@@ -403,6 +405,11 @@ export class TitleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'fifteenth-battle') {
|
||||
this.scene.start('BattleScene', { battleId: fifteenthBattleScenario.id });
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'first-victory-story') {
|
||||
this.scene.start('StoryScene', { pages: firstBattleVictoryPages, nextScene: 'TitleScene' });
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user