Add Luo Castle main gate chapter
This commit is contained in:
@@ -37,6 +37,7 @@ const unitTexture: Record<string, string> = {
|
||||
'pang-tong': 'unit-liu-bei',
|
||||
'fa-zheng': 'unit-liu-bei',
|
||||
'wu-yi': 'unit-guan-yu',
|
||||
'yan-yan': 'unit-rebel-archer',
|
||||
'rebel-a': 'unit-rebel',
|
||||
'rebel-b': 'unit-rebel',
|
||||
'rebel-c': 'unit-rebel-archer',
|
||||
@@ -401,7 +402,32 @@ const unitTexture: Record<string, string> = {
|
||||
'luofeng-ambusher-b': 'unit-rebel',
|
||||
'luofeng-ambusher-c': 'unit-rebel',
|
||||
'luofeng-ambusher-d': 'unit-rebel',
|
||||
'luofeng-leader-zhang-ren': 'unit-rebel-leader'
|
||||
'luofeng-leader-zhang-ren': 'unit-rebel-leader',
|
||||
'luo-main-scout-a': 'unit-rebel',
|
||||
'luo-main-scout-b': 'unit-rebel',
|
||||
'luo-main-infantry-a': 'unit-rebel',
|
||||
'luo-main-infantry-b': 'unit-rebel',
|
||||
'luo-main-infantry-c': 'unit-rebel',
|
||||
'luo-main-infantry-d': 'unit-rebel',
|
||||
'luo-main-infantry-e': 'unit-rebel',
|
||||
'luo-main-archer-a': 'unit-rebel-archer',
|
||||
'luo-main-archer-b': 'unit-rebel-archer',
|
||||
'luo-main-archer-c': 'unit-rebel-archer',
|
||||
'luo-main-archer-d': 'unit-rebel-archer',
|
||||
'luo-main-cavalry-a': 'unit-rebel-cavalry',
|
||||
'luo-main-cavalry-b': 'unit-rebel-cavalry',
|
||||
'luo-main-cavalry-c': 'unit-rebel-cavalry',
|
||||
'luo-main-guard-a': 'unit-rebel',
|
||||
'luo-main-guard-b': 'unit-rebel',
|
||||
'luo-main-guard-c': 'unit-rebel',
|
||||
'luo-main-strategist-a': 'unit-rebel-archer',
|
||||
'luo-main-strategist-b': 'unit-rebel-archer',
|
||||
'luo-main-ambusher-a': 'unit-rebel',
|
||||
'luo-main-ambusher-b': 'unit-rebel',
|
||||
'luo-main-ambusher-c': 'unit-rebel',
|
||||
'luo-main-veteran-yan-yan': 'unit-rebel-archer',
|
||||
'luo-main-officer-a': 'unit-rebel-leader',
|
||||
'luo-main-leader-zhang-ren': 'unit-rebel-leader'
|
||||
};
|
||||
|
||||
const unitTextureByClass: Partial<Record<UnitClassKey, string>> = {
|
||||
@@ -1266,7 +1292,32 @@ const enemyAiByUnitId: Record<string, EnemyAiBehavior> = {
|
||||
'luofeng-ambusher-b': 'aggressive',
|
||||
'luofeng-ambusher-c': 'aggressive',
|
||||
'luofeng-ambusher-d': 'aggressive',
|
||||
'luofeng-leader-zhang-ren': 'guard'
|
||||
'luofeng-leader-zhang-ren': 'guard',
|
||||
'luo-main-scout-a': 'aggressive',
|
||||
'luo-main-scout-b': 'aggressive',
|
||||
'luo-main-infantry-a': 'guard',
|
||||
'luo-main-infantry-b': 'guard',
|
||||
'luo-main-infantry-c': 'guard',
|
||||
'luo-main-infantry-d': 'guard',
|
||||
'luo-main-infantry-e': 'guard',
|
||||
'luo-main-archer-a': 'hold',
|
||||
'luo-main-archer-b': 'hold',
|
||||
'luo-main-archer-c': 'hold',
|
||||
'luo-main-archer-d': 'hold',
|
||||
'luo-main-cavalry-a': 'aggressive',
|
||||
'luo-main-cavalry-b': 'aggressive',
|
||||
'luo-main-cavalry-c': 'aggressive',
|
||||
'luo-main-guard-a': 'guard',
|
||||
'luo-main-guard-b': 'guard',
|
||||
'luo-main-guard-c': 'guard',
|
||||
'luo-main-strategist-a': 'hold',
|
||||
'luo-main-strategist-b': 'hold',
|
||||
'luo-main-ambusher-a': 'aggressive',
|
||||
'luo-main-ambusher-b': 'aggressive',
|
||||
'luo-main-ambusher-c': 'aggressive',
|
||||
'luo-main-veteran-yan-yan': 'hold',
|
||||
'luo-main-officer-a': 'guard',
|
||||
'luo-main-leader-zhang-ren': 'guard'
|
||||
};
|
||||
|
||||
const defaultEnemyAiByClass: Partial<Record<UnitClassKey, EnemyAiBehavior>> = {
|
||||
|
||||
@@ -16,6 +16,7 @@ import sixteenthBattleMapUrl from '../../assets/images/battle/sixteenth-battle-m
|
||||
import seventeenthBattleMapUrl from '../../assets/images/battle/seventeenth-battle-map.svg';
|
||||
import tenthBattleMapUrl from '../../assets/images/battle/tenth-battle-map.svg';
|
||||
import thirteenthBattleMapUrl from '../../assets/images/battle/thirteenth-battle-map.svg';
|
||||
import thirtyFirstBattleMapUrl from '../../assets/images/battle/thirty-first-battle-map.svg';
|
||||
import thirtiethBattleMapUrl from '../../assets/images/battle/thirtieth-battle-map.svg';
|
||||
import thirdBattleMapUrl from '../../assets/images/battle/third-battle-map.svg';
|
||||
import twentyEighthBattleMapUrl from '../../assets/images/battle/twenty-eighth-battle-map.svg';
|
||||
@@ -118,6 +119,7 @@ export class BootScene extends Phaser.Scene {
|
||||
this.load.image('battle-map-twenty-eighth', twentyEighthBattleMapUrl);
|
||||
this.load.image('battle-map-twenty-ninth', twentyNinthBattleMapUrl);
|
||||
this.load.image('battle-map-thirtieth', thirtiethBattleMapUrl);
|
||||
this.load.image('battle-map-thirty-first', thirtyFirstBattleMapUrl);
|
||||
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,
|
||||
luoCastleProperRecruitBonds,
|
||||
luoCastleProperRecruitUnits,
|
||||
luoCastleRecruitBonds,
|
||||
luoCastleRecruitUnits,
|
||||
wulingRecruitBonds,
|
||||
@@ -119,6 +121,8 @@ type SortieUnitTacticalSummary = {
|
||||
terrainLine: string;
|
||||
};
|
||||
|
||||
type SortieTerrainCounts = Partial<Record<TerrainType, number>>;
|
||||
|
||||
type SortieRecommendation = {
|
||||
unitId: string;
|
||||
reason: string;
|
||||
@@ -317,7 +321,8 @@ const campaignTimelineChapters: CampaignTimelineChapter[] = [
|
||||
'twenty-seventh-battle-yizhou-relief-road',
|
||||
'twenty-eighth-battle-fu-pass-entry',
|
||||
'twenty-ninth-battle-luo-outer-wall',
|
||||
'thirtieth-battle-luofeng-ambush'
|
||||
'thirtieth-battle-luofeng-ambush',
|
||||
'thirty-first-battle-luo-main-gate'
|
||||
],
|
||||
nextHints: ['형주 방위', '익주 진입', '방통·법정 합류']
|
||||
},
|
||||
@@ -361,7 +366,8 @@ const campBattleIds = {
|
||||
twentySeventh: 'twenty-seventh-battle-yizhou-relief-road',
|
||||
twentyEighth: 'twenty-eighth-battle-fu-pass-entry',
|
||||
twentyNinth: 'twenty-ninth-battle-luo-outer-wall',
|
||||
thirtieth: 'thirtieth-battle-luofeng-ambush'
|
||||
thirtieth: 'thirtieth-battle-luofeng-ambush',
|
||||
thirtyFirst: 'thirty-first-battle-luo-main-gate'
|
||||
} as const;
|
||||
|
||||
const requiredSortieUnitIds = new Set(['liu-bei']);
|
||||
@@ -696,6 +702,18 @@ const sortieRulesByBattleId: Partial<Record<BattleScenarioId, SortieRuleDefiniti
|
||||
{ unitId: 'huang-zhong', reason: '고지 궁병과 매복 부대를 안정적으로 견제하는 원거리 전력입니다.' }
|
||||
],
|
||||
note: '낙봉파 매복전은 열여섯 명 중 여섯 명만 출전합니다. 오의가 새로 후보에 들어오며, 방통 생존과 매복 대응 때문에 책사와 기동 무장 사이의 선택이 더 중요해집니다.'
|
||||
},
|
||||
'thirty-first-battle-luo-main-gate': {
|
||||
maxUnits: 6,
|
||||
recommended: [
|
||||
{ unitId: 'liu-bei', reason: '낙성 본성의 항복 명분과 패배 조건의 중심입니다.' },
|
||||
{ unitId: 'pang-tong', reason: '성문 돌파와 퇴로 확보를 동시에 계산하는 핵심 책사입니다.' },
|
||||
{ unitId: 'fa-zheng', reason: '익주 장수들의 마음을 읽고 엄안 설득의 말길을 여는 역할입니다.' },
|
||||
{ unitId: 'wu-yi', reason: '낙성 내부 지형과 성문 방어 습관을 아는 새 합류 장수입니다.' },
|
||||
{ unitId: 'huang-zhong', reason: '성벽 궁병과 노장 엄안의 원거리 압박에 대응하기 좋습니다.' },
|
||||
{ unitId: 'zhang-fei', reason: '성문 앞 친위대를 짧게 무너뜨리는 돌파력이 필요합니다.' }
|
||||
],
|
||||
note: '낙성 본성 공략은 열여섯 명 중 여섯 명만 출전합니다. 설득을 노리면 책사와 오의를, 빠른 돌파를 노리면 장비와 황충 같은 전투 무장을 우선하십시오.'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3210,6 +3228,87 @@ const campDialogues: CampDialogue[] = [
|
||||
rewardExp: 11
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liu-yan-after-luomain',
|
||||
title: '노장의 항복',
|
||||
availableAfterBattleIds: [campBattleIds.thirtyFirst],
|
||||
unitIds: ['liu-bei', 'yan-yan'],
|
||||
bondId: 'liu-bei__yan-yan',
|
||||
rewardExp: 34,
|
||||
lines: [
|
||||
'엄안: 성문을 잃었으나 백성을 잃지 않았습니다. 패장은 목숨을 구걸하지 않지만, 그 뜻만은 보았습니다.',
|
||||
'유비: 노장의 절개를 꺾으려 온 것이 아니오. 익주의 백성과 장수들이 함께 살 길을 열고자 왔소.',
|
||||
'엄안: 그렇다면 이 활은 성벽 위에서가 아니라 유비공의 진영에서 백성을 지키겠습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'honor-yan-yan-resolve',
|
||||
label: '엄안의 절개를 예우한다',
|
||||
response: '유비가 포박을 풀게 하자 엄안은 고개를 숙이고도 눈빛을 잃지 않았습니다.',
|
||||
rewardExp: 13
|
||||
},
|
||||
{
|
||||
id: 'ask-yan-yan-yizhou-road',
|
||||
label: '익주 안쪽 길을 묻는다',
|
||||
response: '엄안은 성도까지 이어지는 창고와 물길을 짚어 주며, 무리한 약탈을 피해야 한다고 조언했습니다.',
|
||||
rewardExp: 12
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'huang-yan-after-luomain',
|
||||
title: '노장 쌍궁',
|
||||
availableAfterBattleIds: [campBattleIds.thirtyFirst],
|
||||
unitIds: ['huang-zhong', 'yan-yan'],
|
||||
bondId: 'huang-zhong__yan-yan',
|
||||
rewardExp: 32,
|
||||
lines: [
|
||||
'황충: 성벽 위 활이 흔들리지 않더군. 적으로 만났으나 노장의 손맛은 분명했습니다.',
|
||||
'엄안: 황 장군의 활도 고지의 바람을 거슬렀습니다. 이제 같은 편이라면 서로의 사각을 메울 수 있겠지요.',
|
||||
'황충: 다음 성벽은 함께 바라봅시다. 젊은 장수들에게도 노장의 활이 아직 살아 있음을 보여 줘야겠소.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'compare-old-bow-stance',
|
||||
label: '활 자세를 비교한다',
|
||||
response: '두 노장이 말없이 활시위를 당기자 군영 뒤편의 표적이 거의 동시에 흔들렸습니다.',
|
||||
rewardExp: 12
|
||||
},
|
||||
{
|
||||
id: 'plan-wall-archery-luomain',
|
||||
label: '성벽 사격을 연구한다',
|
||||
response: '황충과 엄안은 다음 전장의 고지와 성벽을 나눠 맡는 방법을 병사들에게 가르쳤습니다.',
|
||||
rewardExp: 11
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'fa-wu-after-luomain',
|
||||
title: '성도 압박의 정보',
|
||||
availableAfterBattleIds: [campBattleIds.thirtyFirst],
|
||||
unitIds: ['fa-zheng', 'wu-yi'],
|
||||
bondId: 'fa-zheng__wu-yi',
|
||||
rewardExp: 32,
|
||||
lines: [
|
||||
'법정: 낙성이 열렸으니 유장의 마음도 흔들릴 것입니다. 하지만 성도는 겁만으로 열리지 않습니다.',
|
||||
'오의: 익주 장수들은 유비공이 약속을 지키는지 보고 있습니다. 엄안의 합류가 그 증거가 될 수 있습니다.',
|
||||
'법정: 그렇다면 다음 길은 성문보다 말문을 먼저 열어야겠군요.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'write-chengdu-pressure-letter',
|
||||
label: '성도에 보낼 글을 쓴다',
|
||||
response: '법정은 위협 대신 약속을 앞세우고, 오의는 익주 장수들이 믿을 만한 이름들을 덧붙였습니다.',
|
||||
rewardExp: 12
|
||||
},
|
||||
{
|
||||
id: 'mark-inner-yizhou-route',
|
||||
label: '익주 안쪽 길을 표시한다',
|
||||
response: '오의가 군량 길을 긋고 법정이 사람의 마음길을 덧대자, 성도 압박의 첫 윤곽이 잡혔습니다.',
|
||||
rewardExp: 11
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -4139,6 +4238,66 @@ const campVisits: CampVisitDefinition[] = [
|
||||
itemRewards: ['낙성 수로도 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'luo-main-gate-relief',
|
||||
title: '낙성 성문 구호',
|
||||
location: '낙성 본성 성문',
|
||||
availableAfterBattleIds: [campBattleIds.thirtyFirst],
|
||||
bondId: 'liu-bei__yan-yan',
|
||||
description: '유비와 엄안이 열린 성문 앞의 백성을 달래고, 전투 뒤 무너진 성문과 창고를 정리합니다.',
|
||||
lines: [
|
||||
'엄안: 성문을 지키던 병사들도 결국 익주의 백성입니다. 이들을 함부로 다루면 다음 성도 길은 닫힙니다.',
|
||||
'유비: 부상자는 먼저 치료하고, 창고의 곡식은 명단을 적어 돌려주시오.',
|
||||
'낙성 백성들은 아직 두려움 속에 있었지만, 군영의 약탈 금지 명령을 들으며 문틈으로 고개를 내밀기 시작했습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'treat-luo-gate-wounded',
|
||||
label: '성문 부상자를 치료한다',
|
||||
response: '상처약이 성문 양쪽에 나뉘어 쓰이자 엄안은 말없이 유비에게 한 번 더 예를 표했습니다.',
|
||||
bondExp: 26,
|
||||
itemRewards: ['상처약 4']
|
||||
},
|
||||
{
|
||||
id: 'publish-no-looting-order',
|
||||
label: '약탈 금지 명령을 붙인다',
|
||||
response: '성문 앞에 붙은 명령문은 낙성 안쪽으로 빠르게 퍼졌고, 다음 항복 권고의 근거가 되었습니다.',
|
||||
bondExp: 24,
|
||||
gold: 380,
|
||||
itemRewards: ['낙성 안정문 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'chengdu-pressure-council',
|
||||
title: '성도 압박 회의',
|
||||
location: '낙성 군영 본막',
|
||||
availableAfterBattleIds: [campBattleIds.thirtyFirst],
|
||||
bondId: 'fa-zheng__wu-yi',
|
||||
description: '법정, 오의, 엄안이 성도까지 이어지는 길과 유장의 흔들리는 장수들을 정리합니다.',
|
||||
lines: [
|
||||
'법정: 낙성이 열렸다는 소식은 성도까지 하루면 닿을 것입니다. 그 소식이 공포가 아니라 약속으로 들려야 합니다.',
|
||||
'오의: 익주의 길을 아는 장수들이 이제 우리 군영에 있습니다. 길은 좁아도 말은 넓게 보내야 합니다.',
|
||||
'엄안: 노장 하나가 항복했다고 모든 성이 열리지는 않습니다. 하지만 백성을 살렸다는 말은 오래 갑니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'send-chengdu-parley-envoy',
|
||||
label: '성도에 사자를 보낸다',
|
||||
response: '사자는 항복 권고문과 낙성 안정문을 함께 들고 떠났고, 군영에는 다음 전장 후보지가 표시되었습니다.',
|
||||
bondExp: 26,
|
||||
itemRewards: ['성도 권고문 초안 1']
|
||||
},
|
||||
{
|
||||
id: 'survey-inner-yizhou-storehouses',
|
||||
label: '익주 창고를 조사한다',
|
||||
response: '창고와 물길을 먼저 장악하자는 의견이 모이며, 다음 전투의 보급 목표가 분명해졌습니다.',
|
||||
bondExp: 24,
|
||||
gold: 400,
|
||||
itemRewards: ['익주 창고 장부 1']
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -4155,6 +4314,7 @@ export class CampScene extends Phaser.Scene {
|
||||
private tabButtons: CampTabButtonView[] = [];
|
||||
private visitedTabs = new Set<CampTab>();
|
||||
private selectedSortieUnitIds: string[] = [];
|
||||
private terrainCountCache = new Map<BattleScenarioId, SortieTerrainCounts>();
|
||||
|
||||
constructor() {
|
||||
super('CampScene');
|
||||
@@ -4224,6 +4384,41 @@ export class CampScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.thirtyFirst) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[
|
||||
...xuzhouRecruitUnits,
|
||||
...caoBreakRecruitUnits,
|
||||
...liuBiaoRecruitUnits,
|
||||
...zhugeRecruitUnits,
|
||||
...jingzhouRecruitUnits,
|
||||
...guiyangRecruitUnits,
|
||||
...wulingRecruitUnits,
|
||||
...changshaRecruitUnits,
|
||||
...yizhouRecruitUnits,
|
||||
...fuPassRecruitUnits,
|
||||
...luoCastleRecruitUnits,
|
||||
...luoCastleProperRecruitUnits
|
||||
],
|
||||
[
|
||||
...xuzhouRecruitBonds,
|
||||
...caoBreakRecruitBonds,
|
||||
...liuBiaoRecruitBonds,
|
||||
...zhugeRecruitBonds,
|
||||
...jingzhouRecruitBonds,
|
||||
...guiyangRecruitBonds,
|
||||
...wulingRecruitBonds,
|
||||
...changshaRecruitBonds,
|
||||
...yizhouRecruitBonds,
|
||||
...fuPassRecruitBonds,
|
||||
...luoCastleRecruitBonds,
|
||||
...luoCastleProperRecruitBonds
|
||||
]
|
||||
);
|
||||
this.report = this.campaign.firstBattleReport ?? this.report;
|
||||
return;
|
||||
}
|
||||
|
||||
if (battleId === campBattleIds.thirtieth || battleId === campBattleIds.twentyNinth) {
|
||||
this.campaign = ensureCampaignRosterUnits(
|
||||
[
|
||||
@@ -4465,6 +4660,9 @@ export class CampScene extends Phaser.Scene {
|
||||
|
||||
private currentCampTitle() {
|
||||
const battleId = this.currentCampBattleId();
|
||||
if (battleId === campBattleIds.thirtyFirst) {
|
||||
return '낙성 본성 공략 후 군영';
|
||||
}
|
||||
if (battleId === campBattleIds.thirtieth) {
|
||||
return '낙봉파 매복전 후 군영';
|
||||
}
|
||||
@@ -4848,7 +5046,7 @@ export class CampScene extends Phaser.Scene {
|
||||
const column = index % 2;
|
||||
const row = Math.floor(index / 2);
|
||||
const rowX = x + 18 + column * 176;
|
||||
const rowY = y + 218 + row * 28;
|
||||
const rowY = y + 208 + row * 24;
|
||||
const names = slot.unitNames.length > 0 ? slot.unitNames.join(', ') : '미배치';
|
||||
const color = slot.unitNames.length > 0 ? '#a8ffd0' : '#9fb0bf';
|
||||
this.trackSortie(this.add.text(rowX, rowY, slot.label, this.textStyle(12, color, true))).setDepth(depth + 1);
|
||||
@@ -4857,7 +5055,7 @@ export class CampScene extends Phaser.Scene {
|
||||
});
|
||||
|
||||
const warning = plan.warnings[0] ?? plan.reserveLine;
|
||||
this.trackSortie(this.add.text(x + 18, y + height - 28, this.compactText(`조언: ${warning}`, 42), this.textStyle(12, plan.warnings.length > 0 ? '#ffdf7b' : '#a8ffd0', true))).setDepth(depth + 1);
|
||||
this.trackSortie(this.add.text(x + 18, y + height - 24, this.compactText(`조언: ${warning}`, 42), this.textStyle(12, plan.warnings.length > 0 ? '#ffdf7b' : '#a8ffd0', true))).setDepth(depth + 1);
|
||||
}
|
||||
|
||||
private renderSortieEquipmentIcons(unit: UnitData, x: number, y: number, selected: boolean, depth: number) {
|
||||
@@ -4947,8 +5145,13 @@ export class CampScene extends Phaser.Scene {
|
||||
return `지형 ${grade}${bestTerrains ? ` · ${bestTerrains}` : ''}`;
|
||||
}
|
||||
|
||||
private passableTerrainCounts(scenario: BattleScenarioDefinition) {
|
||||
const counts = {} as Record<TerrainType, number>;
|
||||
private passableTerrainCounts(scenario: BattleScenarioDefinition): SortieTerrainCounts {
|
||||
const cached = this.terrainCountCache.get(scenario.id);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const counts: SortieTerrainCounts = {};
|
||||
scenario.map.terrain.forEach((row) => {
|
||||
row.forEach((terrain) => {
|
||||
if (terrainRules[terrain].passable === false) {
|
||||
@@ -4957,6 +5160,7 @@ export class CampScene extends Phaser.Scene {
|
||||
counts[terrain] = (counts[terrain] ?? 0) + 1;
|
||||
});
|
||||
});
|
||||
this.terrainCountCache.set(scenario.id, counts);
|
||||
return counts;
|
||||
}
|
||||
|
||||
@@ -5065,7 +5269,7 @@ export class CampScene extends Phaser.Scene {
|
||||
warnings.push(`아직 ${maxCount - selectedUnits.length}명 더 출전할 수 있습니다.`);
|
||||
}
|
||||
if (missingRecommended.length > 0) {
|
||||
warnings.push(`추천 무장 ${missingRecommended.map((entry) => this.unitName(entry.unitId)).join(', ')}이 대기 중입니다.`);
|
||||
warnings.push(`추천 무장 ${missingRecommended.map((entry) => this.unitName(entry.unitId)).join(', ')} 대기 중입니다.`);
|
||||
}
|
||||
if (roleCounts.front <= 0) {
|
||||
warnings.push('전열 병과가 없어 길목을 버티기 어렵습니다.');
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
seventeenthBattleScenario,
|
||||
tenthBattleScenario,
|
||||
thirteenthBattleScenario,
|
||||
thirtyFirstBattleScenario,
|
||||
thirtiethBattleScenario,
|
||||
twentyEighthBattleScenario,
|
||||
twentyFirstBattleScenario,
|
||||
@@ -359,7 +360,8 @@ export class TitleScene extends Phaser.Scene {
|
||||
campaign.step === 'twenty-seventh-camp' ||
|
||||
campaign.step === 'twenty-eighth-camp' ||
|
||||
campaign.step === 'twenty-ninth-camp' ||
|
||||
campaign.step === 'thirtieth-camp'
|
||||
campaign.step === 'thirtieth-camp' ||
|
||||
campaign.step === 'thirty-first-camp'
|
||||
) {
|
||||
this.scene.start('CampScene');
|
||||
return;
|
||||
@@ -515,6 +517,11 @@ export class TitleScene extends Phaser.Scene {
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'thirty-first-battle') {
|
||||
this.scene.start('BattleScene', { battleId: thirtyFirstBattleScenario.id });
|
||||
return;
|
||||
}
|
||||
|
||||
if (campaign.step === 'first-victory-story') {
|
||||
this.scene.start('StoryScene', { pages: firstBattleVictoryPages, nextScene: 'TitleScene' });
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user