Add Wolong recruitment chapter
This commit is contained in:
@@ -13,6 +13,8 @@ import {
|
||||
liuBiaoRecruitUnits,
|
||||
xuzhouRecruitBonds,
|
||||
xuzhouRecruitUnits,
|
||||
zhugeRecruitBonds,
|
||||
zhugeRecruitUnits,
|
||||
type PortraitKey,
|
||||
type UnitData
|
||||
} from '../data/scenario';
|
||||
@@ -218,7 +220,8 @@ const campBattleIds = {
|
||||
thirteenth: 'thirteenth-battle-xiapi-final',
|
||||
fourteenth: 'fourteenth-battle-cao-break',
|
||||
fifteenth: 'fifteenth-battle-yuan-refuge-road',
|
||||
sixteenth: 'sixteenth-battle-liu-biao-refuge'
|
||||
sixteenth: 'sixteenth-battle-liu-biao-refuge',
|
||||
seventeenth: 'seventeenth-battle-wolong-visit-road'
|
||||
} as const;
|
||||
|
||||
const requiredSortieUnitIds = new Set(['liu-bei']);
|
||||
@@ -385,6 +388,18 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
||||
{ unitId: 'mi-zhu', reason: '큰 맵의 장기전을 대비한 보급과 회복 운용에 유리합니다.' }
|
||||
],
|
||||
note: '유표 의탁로부터는 합류 무장이 출전 제한보다 많아집니다. 조운의 기동력을 시험할지, 책사와 보급을 두껍게 둘지 직접 고르십시오.'
|
||||
},
|
||||
'seventeenth-battle-wolong-visit-road': {
|
||||
maxUnits: 6,
|
||||
recommended: [
|
||||
{ unitId: 'liu-bei', reason: '와룡을 직접 찾아가는 주장입니다.' },
|
||||
{ unitId: 'zhao-yun', reason: '산길 척후와 기병을 빠르게 끊는 기동 역할입니다.' },
|
||||
{ unitId: 'guan-yu', reason: '초가 앞 수비병을 정면에서 밀어낼 전열 핵심입니다.' },
|
||||
{ unitId: 'zhang-fei', reason: '좁은 길목을 뚫고 채순을 압박하는 돌파 역할입니다.' },
|
||||
{ unitId: 'sun-qian', reason: '와룡 방문의 예와 명분을 정리하는 책사 역할입니다.' },
|
||||
{ unitId: 'mi-zhu', reason: '산길 장기전에 필요한 보급과 회복 운용을 맡습니다.' }
|
||||
],
|
||||
note: '와룡 단서를 모은 뒤 융중으로 향합니다. 출전 제한보다 무장이 많으니 조운의 기동, 책사의 지원, 보급 중 무엇을 중시할지 선택하십시오.'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1738,6 +1753,87 @@ const campDialogues: CampDialogue[] = [
|
||||
rewardExp: 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-zhuge-after-wolong-visit',
|
||||
title: '초가에서 열린 큰 그림',
|
||||
availableAfterBattleIds: [campBattleIds.seventeenth],
|
||||
unitIds: ['liu-bei', 'zhuge-liang'],
|
||||
bondId: 'liu-bei__zhuge-liang',
|
||||
rewardExp: 28,
|
||||
lines: [
|
||||
'제갈량: 주공께서 세 번이나 초가를 찾으신 것은 한 사람을 얻기 위함이 아니라, 백성을 살릴 길을 묻기 위함이라 보았습니다.',
|
||||
'유비: 나는 아직 작은 군영 하나도 온전히 지키기 어려운 몸이오. 그러나 선생의 말은 우리 군이 가야 할 길을 눈앞에 펼쳤소.',
|
||||
'제갈량: 그 길은 서두르면 흐트러지고, 늦추면 빼앗깁니다. 이제부터는 뜻과 때를 함께 살피겠습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'share-three-kingdoms-plan',
|
||||
label: '천하삼분의 뜻을 묻는다',
|
||||
response: '제갈량은 형주와 익주, 그리고 북벌의 때를 차분히 설명했고, 유비는 그 말을 군영의 첫 방침으로 삼았다.',
|
||||
rewardExp: 12
|
||||
},
|
||||
{
|
||||
id: 'entrust-camp-strategy',
|
||||
label: '군영의 계책을 맡긴다',
|
||||
response: '유비는 제갈량에게 군영의 큰 판단을 맡겼고, 공명은 병사와 장수의 이름부터 조용히 살피기 시작했다.',
|
||||
rewardExp: 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'zhao-zhuge-after-wolong-visit',
|
||||
title: '말발굽과 부채',
|
||||
availableAfterBattleIds: [campBattleIds.seventeenth],
|
||||
unitIds: ['zhao-yun', 'zhuge-liang'],
|
||||
bondId: 'zhao-yun__zhuge-liang',
|
||||
rewardExp: 22,
|
||||
lines: [
|
||||
'조운: 선생의 계책은 멀리 보되, 실제 길목의 먼지까지 살피는군요. 제 말이 달릴 곳을 미리 본 듯했습니다.',
|
||||
'제갈량: 자룡의 창은 빠르지만 앞서 나가도 군의 마음을 놓치지 않습니다. 그래서 빠른 구원이 가능해집니다.',
|
||||
'조운: 그렇다면 다음 전장에서는 선생의 지시에 맞춰, 가장 필요한 곳에 먼저 닿겠습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'map-relief-routes',
|
||||
label: '구원로를 함께 살핀다',
|
||||
response: '제갈량은 지형 위에 구원로를 표시했고, 조운은 말이 지나갈 수 있는 폭과 위험한 샛길을 덧붙였다.',
|
||||
rewardExp: 10
|
||||
},
|
||||
{
|
||||
id: 'coordinate-feint-charge',
|
||||
label: '유인 돌격을 맞춘다',
|
||||
response: '조운은 일부러 빈틈을 보이는 돌격법을 익혔고, 제갈량은 그 틈에 적을 몰아넣는 순서를 정했다.',
|
||||
rewardExp: 9
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'guan-zhuge-after-wolong-visit',
|
||||
title: '의와 계책의 첫 인사',
|
||||
availableAfterBattleIds: [campBattleIds.seventeenth],
|
||||
unitIds: ['guan-yu', 'zhuge-liang'],
|
||||
bondId: 'guan-yu__zhuge-liang',
|
||||
rewardExp: 20,
|
||||
lines: [
|
||||
'관우: 선생의 말은 크고 깊으나, 전장에서는 한 걸음의 늦음도 군을 잃게 합니다. 그 점을 잊지 않으셨으면 하오.',
|
||||
'제갈량: 운장께서 전열을 지키는 까닭도 결국 주공의 뜻을 잃지 않기 위함입니다. 저는 그 의를 가벼이 여기지 않겠습니다.',
|
||||
'관우: 그렇다면 나 또한 선생의 계책을 먼저 듣겠소. 의가 길을 잃지 않게 해 주시오.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'align-duty-and-plan',
|
||||
label: '의와 계책을 맞춘다',
|
||||
response: '관우는 제갈량의 병력 운용을 듣고 전열의 기준을 새로 세웠고, 제갈량은 관우가 지켜야 할 선을 존중했다.',
|
||||
rewardExp: 9
|
||||
},
|
||||
{
|
||||
id: 'promise-clear-orders',
|
||||
label: '명령의 기준을 분명히 한다',
|
||||
response: '제갈량은 전장 명령의 우선순위를 문서로 정리했고, 관우는 그 분명함을 보고 조용히 고개를 끄덕였다.',
|
||||
rewardExp: 8
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1829,6 +1925,65 @@ const campVisits: CampVisitDefinition[] = [
|
||||
itemRewards: ['탁주 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'longzhong-cottage-records',
|
||||
title: '융중 초가 정리',
|
||||
location: '융중 초가',
|
||||
availableAfterBattleIds: [campBattleIds.seventeenth],
|
||||
bondId: 'liu-bei__zhuge-liang',
|
||||
description: '제갈량과 함께 초가의 지도와 서책을 정리하며 다음 큰 흐름을 준비합니다.',
|
||||
lines: [
|
||||
'제갈량: 이 지도들은 아직 군영의 전장 지도가 아니라 천하의 형세입니다. 그러나 전장은 늘 여기서 시작됩니다.',
|
||||
'유비: 우리 군이 지금 가진 것은 많지 않소. 그래서 더더욱 무엇을 먼저 지킬지 알아야 하오.',
|
||||
'초가의 낮은 책상 위에는 형주와 강동, 북방의 길이 하나씩 펼쳐집니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'study-red-cliff-winds',
|
||||
label: '강동의 바람을 살핀다',
|
||||
response: '제갈량은 강동과 조조군의 충돌 가능성을 짚었고, 유비군은 다음 큰 전장의 이름을 조심스럽게 떠올렸다.',
|
||||
bondExp: 24,
|
||||
itemRewards: ['강동 풍문 1']
|
||||
},
|
||||
{
|
||||
id: 'organize-wolong-scrolls',
|
||||
label: '와룡의 서책을 정리한다',
|
||||
response: '손상되기 쉬운 서책을 군영으로 옮기며 제갈량의 계책을 병사들도 이해할 수 있는 말로 옮기기 시작했다.',
|
||||
bondExp: 20,
|
||||
itemRewards: ['와룡의 서찰 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'xinye-merchant-after-wolong',
|
||||
title: '신야 상인 접견',
|
||||
location: '신야 장터',
|
||||
availableAfterBattleIds: [campBattleIds.seventeenth],
|
||||
bondId: 'liu-bei__mi-zhu',
|
||||
description: '제갈량 합류 소문을 듣고 찾아온 상인들과 다음 전투를 위한 보급 조건을 조율합니다.',
|
||||
lines: [
|
||||
'미축: 와룡이 주공의 군영에 들었다는 말이 퍼지자 상인들의 셈도 달라졌습니다. 지금 보급선을 고정할 기회입니다.',
|
||||
'유비: 값이 싸다고 무리하게 사들이지는 마시오. 백성의 삶을 해치지 않는 선에서 군을 세워야 하오.',
|
||||
'상인들은 유비군의 앞날에 걸지, 당장의 이익만 챙길지 서로 눈치를 봅니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'secure-medicine-contract',
|
||||
label: '약재 계약을 맺는다',
|
||||
response: '미축은 오래 보관할 수 있는 약재 계약을 맺었고, 군영의 치료 물자가 안정되었다.',
|
||||
bondExp: 14,
|
||||
itemRewards: ['상처약 2']
|
||||
},
|
||||
{
|
||||
id: 'preserve-war-funds',
|
||||
label: '군자금을 아낀다',
|
||||
response: '미축은 급하지 않은 거래를 미루고 군자금을 보존했다. 병사들은 검소한 군영의 기준을 이해했다.',
|
||||
bondExp: 12,
|
||||
gold: 160,
|
||||
itemRewards: ['콩 2']
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1914,6 +2069,15 @@ export class CampScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.seventeenth) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[...xuzhouRecruitUnits, ...caoBreakRecruitUnits, ...liuBiaoRecruitUnits, ...zhugeRecruitUnits],
|
||||
[...xuzhouRecruitBonds, ...caoBreakRecruitBonds, ...liuBiaoRecruitBonds, ...zhugeRecruitBonds]
|
||||
);
|
||||
this.report = this.campaign.firstBattleReport ?? this.report;
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.fifteenth || battleId === campBattleIds.sixteenth) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[...xuzhouRecruitUnits, ...caoBreakRecruitUnits, ...liuBiaoRecruitUnits],
|
||||
@@ -1962,6 +2126,9 @@ export class CampScene extends Phaser.Scene {
|
||||
|
||||
private currentCampTitle() {
|
||||
const battleId = this.currentCampBattleId();
|
||||
if (battleId === campBattleIds.seventeenth) {
|
||||
return '와룡 출려 후 군영';
|
||||
}
|
||||
if (battleId === campBattleIds.sixteenth) {
|
||||
return '형주 의탁 후 군영';
|
||||
}
|
||||
@@ -2701,6 +2868,14 @@ export class CampScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flow.nextBattleId === campBattleIds.seventeenth && this.wolongClueCount() <= 0) {
|
||||
this.hideSortiePrep();
|
||||
this.activeTab = 'visit';
|
||||
this.render();
|
||||
this.showCampNotice('와룡의 단서를 먼저 모으십시오. 방문 탭에서 형주 선비들의 말을 들어 보세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
markCampaignStep(flow.campaignStep);
|
||||
this.scene.start('StoryScene', {
|
||||
pages: flow.pages,
|
||||
@@ -3058,7 +3233,7 @@ export class CampScene extends Phaser.Scene {
|
||||
bg.setStrokeStyle(1, palette.blue, 0.42);
|
||||
this.track(this.add.text(x + 14, y + 12, '현지 준비', this.textStyle(17, '#f2e3bf', true)));
|
||||
this.track(this.add.text(x + 14, y + 40, `방문 ${completed.length}/${visits.length} 완료`, this.textStyle(13, completed.length >= visits.length && visits.length > 0 ? '#a8ffd0' : '#d4dce6', true)));
|
||||
const insightCount = this.inventoryAmount('와룡 소문') + this.inventoryAmount('민심 기록');
|
||||
const insightCount = this.wolongClueCount();
|
||||
this.track(this.add.text(x + 14, y + 66, `제갈량 단서 ${insightCount} · 군자금 ${this.campaign?.gold ?? 0}`, this.textStyle(13, '#9fb0bf', true)));
|
||||
}
|
||||
|
||||
@@ -3586,6 +3761,10 @@ export class CampScene extends Phaser.Scene {
|
||||
return this.campaign?.inventory[label] ?? 0;
|
||||
}
|
||||
|
||||
private wolongClueCount() {
|
||||
return this.inventoryAmount('와룡 소문') + this.inventoryAmount('민심 기록');
|
||||
}
|
||||
|
||||
private drawBar(x: number, y: number, width: number, height: number, ratio: number, color: number) {
|
||||
const track = this.track(this.add.rectangle(x, y, width, height, 0x070b10, 0.86));
|
||||
track.setOrigin(0);
|
||||
|
||||
Reference in New Issue
Block a user