Add Luo Castle outer wall chapter
This commit is contained in:
@@ -36,6 +36,7 @@ const unitTexture: Record<string, string> = {
|
||||
'wei-yan': 'unit-guan-yu',
|
||||
'pang-tong': 'unit-liu-bei',
|
||||
'fa-zheng': 'unit-liu-bei',
|
||||
'wu-yi': 'unit-guan-yu',
|
||||
'rebel-a': 'unit-rebel',
|
||||
'rebel-b': 'unit-rebel',
|
||||
'rebel-c': 'unit-rebel-archer',
|
||||
@@ -357,7 +358,27 @@ const unitTexture: Record<string, string> = {
|
||||
'fupass-ambusher-a': 'unit-rebel',
|
||||
'fupass-ambusher-b': 'unit-rebel',
|
||||
'fupass-ambusher-c': 'unit-rebel',
|
||||
'fupass-leader-gao-pei': 'unit-rebel-leader'
|
||||
'fupass-leader-gao-pei': 'unit-rebel-leader',
|
||||
'luo-scout-a': 'unit-rebel',
|
||||
'luo-scout-b': 'unit-rebel',
|
||||
'luo-infantry-a': 'unit-rebel',
|
||||
'luo-infantry-b': 'unit-rebel',
|
||||
'luo-infantry-c': 'unit-rebel',
|
||||
'luo-infantry-d': 'unit-rebel',
|
||||
'luo-archer-a': 'unit-rebel-archer',
|
||||
'luo-archer-b': 'unit-rebel-archer',
|
||||
'luo-archer-c': 'unit-rebel-archer',
|
||||
'luo-cavalry-a': 'unit-rebel-cavalry',
|
||||
'luo-cavalry-b': 'unit-rebel-cavalry',
|
||||
'luo-cavalry-c': 'unit-rebel-cavalry',
|
||||
'luo-guard-a': 'unit-rebel',
|
||||
'luo-guard-b': 'unit-rebel',
|
||||
'luo-strategist-a': 'unit-rebel-archer',
|
||||
'luo-strategist-b': 'unit-rebel-archer',
|
||||
'luo-ambusher-a': 'unit-rebel',
|
||||
'luo-ambusher-b': 'unit-rebel',
|
||||
'luo-officer-wu-yi': 'unit-guan-yu',
|
||||
'luo-leader-zhang-ren': 'unit-rebel-leader'
|
||||
};
|
||||
|
||||
const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
||||
@@ -785,7 +806,8 @@ const unitStrategyIds: Record<string, string[]> = {
|
||||
'huang-zhong': ['encourage'],
|
||||
'wei-yan': ['roar'],
|
||||
'pang-tong': ['aid', 'encourage', 'fireTactic'],
|
||||
'fa-zheng': ['aid', 'encourage', 'fireTactic']
|
||||
'fa-zheng': ['aid', 'encourage', 'fireTactic'],
|
||||
'wu-yi': ['encourage']
|
||||
};
|
||||
|
||||
const initialItemStocks: Record<string, Record<string, number>> = {
|
||||
@@ -803,7 +825,8 @@ const initialItemStocks: Record<string, Record<string, number>> = {
|
||||
'huang-zhong': { bean: 1, wine: 1 },
|
||||
'wei-yan': { bean: 2 },
|
||||
'pang-tong': { bean: 1, salve: 1, wine: 1 },
|
||||
'fa-zheng': { bean: 1, salve: 1, wine: 1 }
|
||||
'fa-zheng': { bean: 1, salve: 1, wine: 1 },
|
||||
'wu-yi': { bean: 2, wine: 1 }
|
||||
};
|
||||
|
||||
const attackRangeByClass: Partial<Record<UnitClassKey, number>> = {
|
||||
@@ -1177,7 +1200,27 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
|
||||
'fupass-ambusher-a': 'aggressive',
|
||||
'fupass-ambusher-b': 'aggressive',
|
||||
'fupass-ambusher-c': 'aggressive',
|
||||
'fupass-leader-gao-pei': 'guard'
|
||||
'fupass-leader-gao-pei': 'guard',
|
||||
'luo-scout-a': 'aggressive',
|
||||
'luo-scout-b': 'aggressive',
|
||||
'luo-infantry-a': 'guard',
|
||||
'luo-infantry-b': 'guard',
|
||||
'luo-infantry-c': 'guard',
|
||||
'luo-infantry-d': 'guard',
|
||||
'luo-archer-a': 'hold',
|
||||
'luo-archer-b': 'hold',
|
||||
'luo-archer-c': 'hold',
|
||||
'luo-cavalry-a': 'aggressive',
|
||||
'luo-cavalry-b': 'aggressive',
|
||||
'luo-cavalry-c': 'aggressive',
|
||||
'luo-guard-a': 'guard',
|
||||
'luo-guard-b': 'guard',
|
||||
'luo-strategist-a': 'hold',
|
||||
'luo-strategist-b': 'hold',
|
||||
'luo-ambusher-a': 'aggressive',
|
||||
'luo-ambusher-b': 'aggressive',
|
||||
'luo-officer-wu-yi': 'guard',
|
||||
'luo-leader-zhang-ren': 'guard'
|
||||
};
|
||||
|
||||
const defaultEnemyAiByClass: Partial<Record<UnitClassKey, EnemyAiBehavior>> = {
|
||||
|
||||
@@ -23,6 +23,7 @@ import twentySecondBattleMapUrl from '../../assets/images/battle/twenty-second-b
|
||||
import twentyThirdBattleMapUrl from '../../assets/images/battle/twenty-third-battle-map.svg';
|
||||
import twentyFifthBattleMapUrl from '../../assets/images/battle/twenty-fifth-battle-map.svg';
|
||||
import twentyFourthBattleMapUrl from '../../assets/images/battle/twenty-fourth-battle-map.svg';
|
||||
import twentyNinthBattleMapUrl from '../../assets/images/battle/twenty-ninth-battle-map.svg';
|
||||
import twentySixthBattleMapUrl from '../../assets/images/battle/twenty-sixth-battle-map.svg';
|
||||
import twentySeventhBattleMapUrl from '../../assets/images/battle/twenty-seventh-battle-map.svg';
|
||||
import twentiethBattleMapUrl from '../../assets/images/battle/twentieth-battle-map.svg';
|
||||
@@ -114,6 +115,7 @@ export class BootScene extends Phaser.Scene {
|
||||
this.load.image('battle-map-twenty-sixth', twentySixthBattleMapUrl);
|
||||
this.load.image('battle-map-twenty-seventh', twentySeventhBattleMapUrl);
|
||||
this.load.image('battle-map-twenty-eighth', twentyEighthBattleMapUrl);
|
||||
this.load.image('battle-map-twenty-ninth', twentyNinthBattleMapUrl);
|
||||
this.load.image('portrait-liu-bei', liuBeiPortraitUrl);
|
||||
this.load.image('portrait-guan-yu', guanYuPortraitUrl);
|
||||
this.load.image('portrait-zhang-fei', zhangFeiPortraitUrl);
|
||||
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
jingzhouRecruitUnits,
|
||||
liuBiaoRecruitBonds,
|
||||
liuBiaoRecruitUnits,
|
||||
luoCastleRecruitBonds,
|
||||
luoCastleRecruitUnits,
|
||||
wulingRecruitBonds,
|
||||
wulingRecruitUnits,
|
||||
xuzhouRecruitBonds,
|
||||
@@ -313,7 +315,8 @@ const campaignTimelineChapters: CampaignTimelineChapter[] = [
|
||||
'twenty-fifth-battle-wuling-mountain-road',
|
||||
'twenty-sixth-battle-changsha-veteran',
|
||||
'twenty-seventh-battle-yizhou-relief-road',
|
||||
'twenty-eighth-battle-fu-pass-entry'
|
||||
'twenty-eighth-battle-fu-pass-entry',
|
||||
'twenty-ninth-battle-luo-outer-wall'
|
||||
],
|
||||
nextHints: ['형주 방위', '익주 진입', '방통·법정 합류']
|
||||
},
|
||||
@@ -355,7 +358,8 @@ const campBattleIds = {
|
||||
twentyFifth: 'twenty-fifth-battle-wuling-mountain-road',
|
||||
twentySixth: 'twenty-sixth-battle-changsha-veteran',
|
||||
twentySeventh: 'twenty-seventh-battle-yizhou-relief-road',
|
||||
twentyEighth: 'twenty-eighth-battle-fu-pass-entry'
|
||||
twentyEighth: 'twenty-eighth-battle-fu-pass-entry',
|
||||
twentyNinth: 'twenty-ninth-battle-luo-outer-wall'
|
||||
} as const;
|
||||
|
||||
const requiredSortieUnitIds = new Set(['liu-bei']);
|
||||
@@ -666,6 +670,18 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
||||
{ unitId: 'zhao-yun', reason: '협곡 기병과 복병을 빠르게 끊는 기동 핵심입니다.' }
|
||||
],
|
||||
note: '부수관 진입전은 열네 명 중 여섯 명만 고르는 전장입니다. 방통을 데려가면 계책은 강해지지만, 보급이나 전열 후보를 한 명 줄여야 합니다.'
|
||||
},
|
||||
'twenty-ninth-battle-luo-outer-wall': {
|
||||
maxUnits: 6,
|
||||
recommended: [
|
||||
{ unitId: 'liu-bei', reason: '낙성 외곽 마을을 안정시키는 명분의 중심입니다.' },
|
||||
{ unitId: 'fa-zheng', reason: '법정은 익주 내부 사정을 알고 있어 오의 설득과 성문 정보에 강합니다.' },
|
||||
{ unitId: 'pang-tong', reason: '방통의 계책은 낙성으로 들어가는 좁은 길과 매복을 읽는 데 필요합니다.' },
|
||||
{ unitId: 'zhuge-liang', reason: '장임의 방어선과 낙봉파로 이어지는 다음 전장을 동시에 살핍니다.' },
|
||||
{ unitId: 'huang-zhong', reason: '낙성 외곽의 궁병과 고지 방어선을 안정적으로 견제합니다.' },
|
||||
{ unitId: 'zhao-yun', reason: '넓어진 외곽 맵에서 정찰과 기병 대응을 맡기 좋습니다.' }
|
||||
],
|
||||
note: '낙성 외곽전은 열다섯 명 중 여섯 명만 출전합니다. 법정을 데려가면 설득과 정보가 강해지고, 무장을 더 넣으면 전열이 단단해지는 선택지가 생깁니다.'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3018,6 +3034,87 @@ const campDialogues: CampDialogue[] = [
|
||||
rewardExp: 10
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-wu-after-luo',
|
||||
title: '낙성의 새 길',
|
||||
availableAfterBattleIds: [campBattleIds.twentyNinth],
|
||||
unitIds: ['liu-bei', 'wu-yi'],
|
||||
bondId: 'liu-bei__wu-yi',
|
||||
rewardExp: 30,
|
||||
lines: [
|
||||
'오의: 성문을 지킨다는 명분으로 백성을 몰아넣는 일은 장수의 길이 아니었습니다.',
|
||||
'유비: 성문은 닫혀 있어도 사람의 마음은 열 수 있소. 그대가 길을 보여준다면 피를 덜 흘릴 수 있겠지.',
|
||||
'오의: 그렇다면 낙성의 길목과 성 안의 동요를 제가 살피겠습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'promise-luo-discipline',
|
||||
label: '낙성 군율을 약속한다',
|
||||
response: '유비가 약탈 금지를 다시 못박자 오의는 익주 장수들을 설득할 명분이 생겼다고 고개를 숙였다.',
|
||||
rewardExp: 12
|
||||
},
|
||||
{
|
||||
id: 'ask-wu-yi-gate',
|
||||
label: '성문 방비를 묻는다',
|
||||
response: '오의는 낙성 외곽의 문루와 보급로를 짚으며 다음 출전에서 자신이 맡을 역할을 분명히 했다.',
|
||||
rewardExp: 11
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'fa-wu-after-luo',
|
||||
title: '익주 내부 설득',
|
||||
availableAfterBattleIds: [campBattleIds.twentyNinth],
|
||||
unitIds: ['fa-zheng', 'wu-yi'],
|
||||
bondId: 'fa-zheng__wu-yi',
|
||||
rewardExp: 28,
|
||||
lines: [
|
||||
'법정: 익주의 장수들은 강한 군대보다 오래 지켜질 약속을 보고 움직입니다.',
|
||||
'오의: 저도 그 약속을 확인했으니, 이제 흔들리는 장수들에게 말할 수 있습니다.',
|
||||
'법정: 다음 전장에서는 누가 백성을 버렸고 누가 지켰는지부터 말합시다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'write-yizhou-names',
|
||||
label: '설득할 장수를 적는다',
|
||||
response: '두 사람은 낙성 주변 장수들의 이름을 정리했고, 말이 통할 사람과 경계할 사람을 나누었다.',
|
||||
rewardExp: 10
|
||||
},
|
||||
{
|
||||
id: 'prepare-luo-message',
|
||||
label: '성 안에 보낼 말을 고른다',
|
||||
response: '법정은 문장을 다듬고 오의는 받을 사람을 정했다. 낙성의 문은 칼보다 먼저 말에 흔들리기 시작했다.',
|
||||
rewardExp: 11
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'pang-wu-after-luo',
|
||||
title: '봉추와 성문 장수',
|
||||
availableAfterBattleIds: [campBattleIds.twentyNinth],
|
||||
unitIds: ['pang-tong', 'wu-yi'],
|
||||
bondId: 'pang-tong__wu-yi',
|
||||
rewardExp: 28,
|
||||
lines: [
|
||||
'방통: 낙성의 길은 곧아 보일수록 위험합니다. 사람을 믿되 길은 의심해야 하지요.',
|
||||
'오의: 장임은 좁은 길에서 기다리는 법을 압니다. 성 밖보다 성 안쪽 길이 더 날카롭습니다.',
|
||||
'방통: 그렇다면 다음 전장은 빠른 칼보다 빠른 눈이 먼저 필요하겠군요.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'mark-luofeng-risk',
|
||||
label: '낙봉파 위험을 표시한다',
|
||||
response: '방통은 오의의 설명을 지도에 겹쳐 놓고, 지나치게 좋은 길목에 붉은 표시를 남겼다.',
|
||||
rewardExp: 11
|
||||
},
|
||||
{
|
||||
id: 'prepare-decoy-column',
|
||||
label: '유인 부대를 준비한다',
|
||||
response: '오의는 성문 병력의 시선을 끌 수 있는 깃발과 행군 순서를 알려 주었고, 방통은 미소를 지었다.',
|
||||
rewardExp: 10
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -3827,6 +3924,66 @@ const campVisits: CampVisitDefinition[] = [
|
||||
itemRewards: ['익주 연락 명단 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'luo-village-reassurance',
|
||||
title: '낙성 외곽 마을 위무',
|
||||
location: '낙성 외곽 마을',
|
||||
availableAfterBattleIds: [campBattleIds.twentyNinth],
|
||||
bondId: 'liu-bei__wu-yi',
|
||||
description: '오의가 앞장서서 마을 사람들을 안심시키고, 유비군이 낙성 백성을 해치지 않는다는 약속을 확인합니다.',
|
||||
lines: [
|
||||
'오의: 이 마을 사람들이 마음을 열면 낙성 안쪽도 곧 소문을 듣게 됩니다.',
|
||||
'유비: 군량과 말은 백성에게서 빼앗지 않는다. 이 약속을 먼저 전하시오.',
|
||||
'마을의 불안이 조금 누그러지고 낙성으로 이어지는 작은 길들이 지도에 더해졌습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'guard-luo-village',
|
||||
label: '마을 경계를 세운다',
|
||||
response: '오의가 아는 길목에 경계를 세우자 백성들은 유비군의 군율을 조금 더 믿게 되었다.',
|
||||
bondExp: 24,
|
||||
itemRewards: ['콩 4']
|
||||
},
|
||||
{
|
||||
id: 'share-grain-ledger',
|
||||
label: '군량 명부를 공개한다',
|
||||
response: '유비군이 쓸 군량과 남길 군량을 나누어 적자, 오의는 설득할 말이 생겼다고 말했다.',
|
||||
bondExp: 22,
|
||||
gold: 300,
|
||||
itemRewards: ['낙성 마을 명부 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'luofeng-shadow-council',
|
||||
title: '낙봉파 그림자 회의',
|
||||
location: '낙성 진군로',
|
||||
availableAfterBattleIds: [campBattleIds.twentyNinth],
|
||||
bondId: 'pang-tong__wu-yi',
|
||||
description: '방통과 오의가 낙성 안쪽 길을 살피며, 다음 전장으로 이어질 위험한 좁은 길을 표시합니다.',
|
||||
lines: [
|
||||
'방통: 이름부터 좋지 않군요. 봉황이 떨어지는 비탈이라니.',
|
||||
'오의: 그 길은 빠르지만 너무 조용합니다. 장임이라면 그 조용함을 그냥 두지 않을 겁니다.',
|
||||
'두 사람은 다음 출전에서 정찰과 호위를 어떻게 나눌지 군영 지도 위에 표시했습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'send-forward-scouts',
|
||||
label: '선행 정찰을 보낸다',
|
||||
response: '오의가 길을 아는 사람을 붙이고 방통이 정찰 순서를 정했다. 다음 전장의 불안이 조금 줄었다.',
|
||||
bondExp: 24,
|
||||
itemRewards: ['낙봉파 정찰표 1']
|
||||
},
|
||||
{
|
||||
id: 'prepare-ambush-counter',
|
||||
label: '매복 대응책을 세운다',
|
||||
response: '방통은 일부러 느슨해 보이는 행군을 제안했고, 오의는 적이 물어뜯을 만한 길목을 짚었다.',
|
||||
bondExp: 22,
|
||||
gold: 320,
|
||||
itemRewards: ['매복 대응 초안 1']
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -3912,6 +4069,39 @@ export class CampScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.twentyNinth) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[
|
||||
...xuzhouRecruitUnits,
|
||||
...caoBreakRecruitUnits,
|
||||
...liuBiaoRecruitUnits,
|
||||
...zhugeRecruitUnits,
|
||||
...jingzhouRecruitUnits,
|
||||
...guiyangRecruitUnits,
|
||||
...wulingRecruitUnits,
|
||||
...changshaRecruitUnits,
|
||||
...yizhouRecruitUnits,
|
||||
...fuPassRecruitUnits,
|
||||
...luoCastleRecruitUnits
|
||||
],
|
||||
[
|
||||
...xuzhouRecruitBonds,
|
||||
...caoBreakRecruitBonds,
|
||||
...liuBiaoRecruitBonds,
|
||||
...zhugeRecruitBonds,
|
||||
...jingzhouRecruitBonds,
|
||||
...guiyangRecruitBonds,
|
||||
...wulingRecruitBonds,
|
||||
...changshaRecruitBonds,
|
||||
...yizhouRecruitBonds,
|
||||
...fuPassRecruitBonds,
|
||||
...luoCastleRecruitBonds
|
||||
]
|
||||
);
|
||||
this.report = this.campaign.firstBattleReport ?? this.report;
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.twentyEighth) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[
|
||||
@@ -4120,6 +4310,9 @@ export class CampScene extends Phaser.Scene {
|
||||
|
||||
private currentCampTitle() {
|
||||
const battleId = this.currentCampBattleId();
|
||||
if (battleId === campBattleIds.twentyNinth) {
|
||||
return '낙성 외곽전 후 군영';
|
||||
}
|
||||
if (battleId === campBattleIds.twentyEighth) {
|
||||
return '부수관 진입 후 군영';
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
twentyThirdBattleScenario,
|
||||
twentyFifthBattleScenario,
|
||||
twentyFourthBattleScenario,
|
||||
twentyNinthBattleScenario,
|
||||
twentySixthBattleScenario,
|
||||
twentySeventhBattleScenario,
|
||||
twentiethBattleScenario,
|
||||
@@ -355,7 +356,8 @@ export class TitleScene extends Phaser.Scene {
|
||||
campaign.step === 'twenty-fifth-camp' ||
|
||||
campaign.step === 'twenty-sixth-camp' ||
|
||||
campaign.step === 'twenty-seventh-camp' ||
|
||||
campaign.step === 'twenty-eighth-camp'
|
||||
campaign.step === 'twenty-eighth-camp' ||
|
||||
campaign.step === 'twenty-ninth-camp'
|
||||
) {
|
||||
this.scene.start('CampScene');
|
||||
return;
|
||||
@@ -501,6 +503,11 @@ export class TitleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'twenty-ninth-battle') {
|
||||
this.scene.start('BattleScene', { battleId: twentyNinthBattleScenario.id });
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'first-victory-story') {
|
||||
this.scene.start('StoryScene', { pages: firstBattleVictoryPages, nextScene: 'TitleScene' });
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user