feat: carry camp scouting into battle deployment
This commit is contained in:
@@ -34,6 +34,10 @@ import {
|
||||
resolveFirstBattleCamaraderieMemory,
|
||||
type FirstBattleCamaraderieMemory
|
||||
} from '../data/firstBattleCamaraderieMemory';
|
||||
import {
|
||||
firstPursuitScoutVisitId,
|
||||
resolveFirstPursuitScoutMemory
|
||||
} from '../data/firstPursuitScoutMemory';
|
||||
import {
|
||||
findCityStayAfterBattle,
|
||||
type CityEquipmentOffer,
|
||||
@@ -8396,6 +8400,35 @@ const campDialogues: CampDialogue[] = [
|
||||
];
|
||||
|
||||
const campVisits: CampVisitDefinition[] = [
|
||||
{
|
||||
id: 'first-pursuit-scout-tent',
|
||||
title: '북문 추격로 정찰',
|
||||
location: '탁현 북문 정찰막',
|
||||
availableAfterBattleIds: [campBattleIds.first],
|
||||
bondId: 'liu-bei__jian-yong',
|
||||
description: '간옹과 황건 잔당의 두 갈래 길을 살피고 정찰 기록을 출진 준비에 올립니다.',
|
||||
lines: [
|
||||
'간옹: 발자국이 강가와 마을길로 갈렸습니다.',
|
||||
'유비: 매복도 찾고 백성의 길도 지켜야 하오.',
|
||||
'정찰 지도에 두 길을 나란히 표시했습니다.'
|
||||
],
|
||||
choices: [
|
||||
{
|
||||
id: 'trace-river-ambush',
|
||||
label: '강가 매복 흔적을 쫓는다',
|
||||
response: '간옹: 강변의 꺾인 갈대와 버려진 횃불을 표시했습니다. 상처약도 챙겨 이 기록을 출진 준비에 올리겠습니다.',
|
||||
bondExp: 10,
|
||||
itemRewards: ['상처약 1']
|
||||
},
|
||||
{
|
||||
id: 'mark-village-relief',
|
||||
label: '마을 구호 길을 표시한다',
|
||||
response: '간옹: 피난민이 돌아올 샛길과 군량을 나눌 곳을 적었습니다. 콩 한 자루와 이 기록을 다음 전투 준비에 보태겠습니다.',
|
||||
bondExp: 10,
|
||||
itemRewards: ['콩 1']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'jingzhou-scholar-rumors',
|
||||
title: '형주 선비들의 모임',
|
||||
@@ -11419,6 +11452,7 @@ export class CampScene extends Phaser.Scene {
|
||||
private sortiePrimaryActionButton?: CampActionButtonView;
|
||||
private sortieNextActionGuideBackground?: Phaser.GameObjects.Rectangle;
|
||||
private sortieNextActionGuideText?: Phaser.GameObjects.Text;
|
||||
private sortieBriefingScoutSummaryText?: Phaser.GameObjects.Text;
|
||||
private firstBattleFollowupCtaButton?: Phaser.GameObjects.Rectangle;
|
||||
private firstBattleFollowupCard?: Phaser.GameObjects.Rectangle;
|
||||
private firstBattleFollowupSummaryText?: Phaser.GameObjects.Text;
|
||||
@@ -12824,6 +12858,14 @@ export class CampScene extends Phaser.Scene {
|
||||
return resolveFirstBattleCamaraderieMemory(this.campaign);
|
||||
}
|
||||
|
||||
private firstPursuitScoutMemoryForNextSortie() {
|
||||
const campaign = this.campaign;
|
||||
const scenario = this.nextSortieScenario();
|
||||
return campaign && scenario
|
||||
? resolveFirstPursuitScoutMemory({ campaign, battleId: scenario.id })
|
||||
: undefined;
|
||||
}
|
||||
|
||||
private firstBattleCamaraderieDialogue(): CampDialogue | undefined {
|
||||
if (!this.isFirstSortiePrepSlice()) {
|
||||
return undefined;
|
||||
@@ -12926,7 +12968,7 @@ export class CampScene extends Phaser.Scene {
|
||||
this.showCampSaveSlotPanel();
|
||||
});
|
||||
const flow = this.currentSortieFlow();
|
||||
const storyButtonLabel = this.isFinalEpilogueFlow(flow) && this.campaign?.step === flow.campaignStep ? '엔딩 보기' : '다음 이야기';
|
||||
const storyButtonLabel = this.isFinalEpilogueFlow(flow) && this.campaign?.step === flow.campaignStep ? '엔딩 보기' : '출진 준비';
|
||||
this.addCommandButton(storyButtonLabel, 1152, 38, 142, () => {
|
||||
soundDirector.playSelect();
|
||||
if (this.isFinalEpilogueFlow(flow)) {
|
||||
@@ -16248,13 +16290,25 @@ export class CampScene extends Phaser.Scene {
|
||||
const objectiveLabel = hasBattle ? '목표' : '진행';
|
||||
const terrainLabel = hasBattle ? '지형' : '장소';
|
||||
const recommendationLabel = hasBattle ? '추천' : '동행';
|
||||
const scoutMemory = this.firstPursuitScoutMemoryForNextSortie();
|
||||
this.trackSortie(this.add.text(x + 18, y + 12, briefing.eyebrow, this.textStyle(15, '#9fb0bf', true))).setDepth(depth + 1);
|
||||
this.trackSortie(this.add.text(x + 18, y + 34, briefing.title, this.textStyle(22, '#f2e3bf', true))).setDepth(depth + 1);
|
||||
if (scoutMemory) {
|
||||
this.sortieBriefingScoutSummaryText = this.trackSortie(
|
||||
this.add.text(
|
||||
x + 18,
|
||||
y + 64,
|
||||
`${scoutMemory.campSummaryLine} · 배치 단계 적 의도 선공개`,
|
||||
this.textStyle(12, '#a8ffd0', true)
|
||||
)
|
||||
);
|
||||
this.sortieBriefingScoutSummaryText.setDepth(depth + 1);
|
||||
}
|
||||
this.trackSortie(
|
||||
this.add.text(x + 18, y + 65, briefing.description, {
|
||||
...this.textStyle(14, '#d4dce6'),
|
||||
this.add.text(x + 18, y + (scoutMemory ? 84 : 65), briefing.description, {
|
||||
...this.textStyle(scoutMemory ? 12 : 14, '#d4dce6'),
|
||||
wordWrap: { width: width - 36, useAdvancedWrap: true },
|
||||
lineSpacing: 3
|
||||
lineSpacing: scoutMemory ? 1 : 3
|
||||
})
|
||||
).setDepth(depth + 1);
|
||||
const chipY = y + height - 46;
|
||||
@@ -20416,6 +20470,7 @@ export class CampScene extends Phaser.Scene {
|
||||
this.sortiePrimaryActionButton = undefined;
|
||||
this.sortieNextActionGuideBackground = undefined;
|
||||
this.sortieNextActionGuideText = undefined;
|
||||
this.sortieBriefingScoutSummaryText = undefined;
|
||||
this.firstBattleFollowupCtaButton = undefined;
|
||||
this.firstBattleFollowupCard = undefined;
|
||||
this.firstBattleFollowupSummaryText = undefined;
|
||||
@@ -23225,7 +23280,7 @@ export class CampScene extends Phaser.Scene {
|
||||
bg.setStrokeStyle(1, palette.gold, 0.58);
|
||||
const locationLabel = this.currentCityStay()?.city.name ?? this.campSkinSelection?.skin.locationLabel ?? '현지';
|
||||
this.track(this.add.text(x + 24, y + 22, `${locationLabel} 방문`, this.textStyle(24, '#f2e3bf', true)));
|
||||
this.track(this.add.text(x + 24, y + 56, '군영 밖 사람들을 만나 정보, 보급, 공명 보상을 얻습니다. 각 방문은 한 번만 완료할 수 있습니다.', this.textStyle(14, '#d4dce6')));
|
||||
this.track(this.add.text(x + 24, y + 56, '획득한 정보·보급·공명은 출진 준비와 다음 전투로 이어집니다. 방문은 한 번만 완료됩니다.', this.textStyle(14, '#d4dce6')));
|
||||
|
||||
const visits = this.availableCampVisits();
|
||||
if (!visits.some((visit) => visit.id === this.selectedVisitId)) {
|
||||
@@ -23334,7 +23389,7 @@ export class CampScene extends Phaser.Scene {
|
||||
const bg = this.track(this.add.rectangle(x, y, width, 104, 0x0d141c, 0.9));
|
||||
bg.setOrigin(0);
|
||||
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 + 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 isWolongSearch = this.currentSortieFlow().nextBattleId === campBattleIds.seventeenth;
|
||||
const informationLabel = isWolongSearch
|
||||
@@ -25005,6 +25060,10 @@ export class CampScene extends Phaser.Scene {
|
||||
const firstBattleCampFollowup = this.firstBattleCampFollowup();
|
||||
const firstBattleCamaraderieMemory = this.firstBattleCamaraderieMemory();
|
||||
const firstBattleCamaraderieDialogue = this.firstBattleCamaraderieDialogue();
|
||||
const firstPursuitScoutVisit = this.availableCampVisits().find(
|
||||
(visit) => visit.id === firstPursuitScoutVisitId
|
||||
);
|
||||
const firstPursuitScoutMemory = this.firstPursuitScoutMemoryForNextSortie();
|
||||
const availableCampDialogues = this.availableCampDialogues();
|
||||
const selectedCampDialogue = availableCampDialogues.find(
|
||||
(dialogue) => dialogue.id === this.selectedDialogueId
|
||||
@@ -25164,6 +25223,25 @@ export class CampScene extends Phaser.Scene {
|
||||
}
|
||||
}
|
||||
: null,
|
||||
firstPursuitScoutMemory: {
|
||||
visitId: firstPursuitScoutVisitId,
|
||||
available: Boolean(firstPursuitScoutVisit),
|
||||
completed: this.completedCampVisits().includes(firstPursuitScoutVisitId),
|
||||
choiceId: this.campaign?.campVisitChoiceIds[firstPursuitScoutVisitId] ?? null,
|
||||
choices: firstPursuitScoutVisit?.choices.map((choice) => ({
|
||||
id: choice.id,
|
||||
label: choice.label,
|
||||
response: choice.response,
|
||||
rewardText: this.visitRewardText(choice)
|
||||
})) ?? [],
|
||||
activeForNextSortie: Boolean(firstPursuitScoutMemory),
|
||||
targetBattleId: firstPursuitScoutMemory?.targetBattleId ?? null,
|
||||
choiceLabel: firstPursuitScoutMemory?.choiceLabel ?? null,
|
||||
deploymentIntentPreview: firstPursuitScoutMemory?.deploymentIntentPreview ?? false,
|
||||
campSummaryLine: firstPursuitScoutMemory?.campSummaryLine ?? null,
|
||||
openingLines: firstPursuitScoutMemory ? [...firstPursuitScoutMemory.openingLines] : [],
|
||||
briefingSummaryBounds: this.sortieTextBoundsDebug(this.sortieBriefingScoutSummaryText)
|
||||
},
|
||||
selectedDialogue: selectedCampDialogue
|
||||
? {
|
||||
id: selectedCampDialogue.id,
|
||||
|
||||
Reference in New Issue
Block a user