feat: prioritize third-victory return dialogue

This commit is contained in:
2026-07-27 11:35:35 +09:00
parent f07a45c62b
commit b2e7c8b403
7 changed files with 2018 additions and 17 deletions

View File

@@ -0,0 +1,304 @@
export const thirdBattleReturnSourceBattleId =
'third-battle-guangzong-road';
export const thirdBattleReturnCampStep = 'third-camp';
export const thirdBattleReturnPriorityLabel = '새 이야기 · 우선';
export const thirdBattleReturnQuickVictoryTurnLimit = 30;
export const thirdBattleReturnObjectiveIds = {
fort: 'fort',
quick: 'quick'
} as const;
export const thirdBattleReturnTargetDialogueIds = {
fortRecovery: 'liu-guan-after-guangzong-road',
tempoRecovery: 'liu-zhang-after-guangzong-road',
decisiveAdvance: 'guan-zhang-after-guangzong-road'
} as const;
export type ThirdBattleReturnDialogueVariantId =
| 'fort-recovery'
| 'tempo-recovery'
| 'decisive-advance';
export type ThirdBattleReturnTargetDialogueId =
(typeof thirdBattleReturnTargetDialogueIds)[
keyof typeof thirdBattleReturnTargetDialogueIds
];
export type ThirdBattleReturnReportSource =
| 'battle-history'
| 'legacy-report';
export type ThirdBattleReturnReport = {
battleId?: unknown;
outcome?: unknown;
turnNumber?: unknown;
objectives?: unknown;
};
export type ThirdBattleReturnCampaignState = {
battleHistory?: Readonly<
Record<string, ThirdBattleReturnReport | null | undefined>
>;
firstBattleReport?: ThirdBattleReturnReport | null;
};
export type ThirdBattlePriorityReturnDialogue = {
sourceBattleId: typeof thirdBattleReturnSourceBattleId;
campStep: typeof thirdBattleReturnCampStep;
targetDialogueId: ThirdBattleReturnTargetDialogueId;
priorityLabel: typeof thirdBattleReturnPriorityLabel;
reportSource: ThirdBattleReturnReportSource;
variantId: ThirdBattleReturnDialogueVariantId;
turnNumber: number;
fortAchieved: boolean;
quickAchieved: boolean;
title: string;
summary: string;
lines: [string, string, string];
};
type VictoryReportSelection = {
report: ThirdBattleReturnReport;
source: ThirdBattleReturnReportSource;
};
export function resolveThirdBattlePriorityReturnDialogue(
campaign?: ThirdBattleReturnCampaignState | null
): ThirdBattlePriorityReturnDialogue | undefined {
const selection = selectVictoryReport(campaign);
if (!selection) {
return undefined;
}
const turnNumber = positiveInteger(selection.report.turnNumber);
const fortAchieved = readObjective(
selection.report.objectives,
thirdBattleReturnObjectiveIds.fort
);
const quickAchieved = readObjective(
selection.report.objectives,
thirdBattleReturnObjectiveIds.quick
);
if (
turnNumber === undefined ||
fortAchieved === undefined ||
quickAchieved === undefined ||
quickAchieved !==
(turnNumber <= thirdBattleReturnQuickVictoryTurnLimit)
) {
return undefined;
}
return createResultDialogue({
reportSource: selection.source,
turnNumber,
fortAchieved,
quickAchieved
});
}
function selectVictoryReport(
campaign?: ThirdBattleReturnCampaignState | null
): VictoryReportSelection | undefined {
const history = campaign?.battleHistory;
if (
history &&
Object.prototype.hasOwnProperty.call(
history,
thirdBattleReturnSourceBattleId
)
) {
const report = history[thirdBattleReturnSourceBattleId];
return validThirdBattleVictory(report)
? { report, source: 'battle-history' }
: undefined;
}
const report = campaign?.firstBattleReport;
return validThirdBattleVictory(report)
? { report, source: 'legacy-report' }
: undefined;
}
function validThirdBattleVictory(
report?: ThirdBattleReturnReport | null
): report is ThirdBattleReturnReport {
return Boolean(
report &&
report.battleId === thirdBattleReturnSourceBattleId &&
report.outcome === 'victory'
);
}
function readObjective(
rawObjectives: unknown,
objectiveId: string
): boolean | undefined {
if (!Array.isArray(rawObjectives)) {
return undefined;
}
const matches = rawObjectives.filter(
(objective) =>
isRecord(objective) &&
objective.id === objectiveId
);
if (
matches.length !== 1 ||
typeof matches[0].achieved !== 'boolean'
) {
return undefined;
}
return (
matches[0].achieved === true &&
matches[0].status !== 'failed'
);
}
function createResultDialogue(options: {
reportSource: ThirdBattleReturnReportSource;
turnNumber: number;
fortAchieved: boolean;
quickAchieved: boolean;
}): ThirdBattlePriorityReturnDialogue {
if (!options.fortAchieved) {
return createFortRecoveryDialogue(options);
}
if (!options.quickAchieved) {
return createTempoRecoveryDialogue(options);
}
return createDecisiveAdvanceDialogue(options);
}
function createFortRecoveryDialogue(options: {
reportSource: ThirdBattleReturnReportSource;
turnNumber: number;
fortAchieved: boolean;
quickAchieved: boolean;
}): ThirdBattlePriorityReturnDialogue {
const pursuitLine = options.quickAchieved
? '유비: 전령을 쫓는 속도는 늦지 않았지만, 요새를 비워 둔 탓에 다음 길이 불안해졌소.'
: '유비: 전령을 쫓는 데도 시간이 걸렸고 요새까지 남겼소. 다음에는 길목부터 확실히 끊어야 하오.';
return baseDialogue({
...options,
targetDialogueId:
thirdBattleReturnTargetDialogueIds.fortRecovery,
variantId: 'fort-recovery',
title: '남겨 둔 강가 요새',
summary:
`강가 요새 미확보 · ${quickResultText(
options.quickAchieved,
options.turnNumber
)}`,
lines: [
`관우: ${options.turnNumber}턴 만에 전령 마원은 막았으나 강가 요새를 끝내 확보하지 못했습니다.`,
pursuitLine,
'관우: 다음 본영전에서는 먼저 물러설 자리를 지우고, 그 뒤에 적장을 몰아붙이겠습니다.'
]
});
}
function createTempoRecoveryDialogue(options: {
reportSource: ThirdBattleReturnReportSource;
turnNumber: number;
fortAchieved: boolean;
quickAchieved: boolean;
}): ThirdBattlePriorityReturnDialogue {
return baseDialogue({
...options,
targetDialogueId:
thirdBattleReturnTargetDialogueIds.tempoRecovery,
variantId: 'tempo-recovery',
title: '늦어진 전령 추격',
summary:
`강가 요새 확보 · ${quickResultText(
options.quickAchieved,
options.turnNumber
)}`,
lines: [
`장비: 강가 요새는 지켰지만 마원을 꺾는 데 ${options.turnNumber}턴이 걸려, 추격의 때를 놓쳤습니다.`,
'유비: 지킬 곳을 지킨 것은 옳소. 이제 전열을 세운 뒤 곧바로 익덕의 창이 이어지게 호흡을 줄이면 되오.',
'장비: 다음 본영전에서는 형님이 길을 잡는 순간 제가 바로 돌파하겠습니다.'
]
});
}
function createDecisiveAdvanceDialogue(options: {
reportSource: ThirdBattleReturnReportSource;
turnNumber: number;
fortAchieved: boolean;
quickAchieved: boolean;
}): ThirdBattlePriorityReturnDialogue {
return baseDialogue({
...options,
targetDialogueId:
thirdBattleReturnTargetDialogueIds.decisiveAdvance,
variantId: 'decisive-advance',
title: '본영으로 잇는 승리',
summary:
`강가 요새 확보 · ${quickResultText(
options.quickAchieved,
options.turnNumber
)}`,
lines: [
`관우: ${options.turnNumber}턴 만에 전령 마원을 꺾고 강가 요새까지 확보했습니다. 광종 본영으로 가는 길이 열렸습니다.`,
'장비: 지킬 곳도 지키고 쫓을 놈도 놓치지 않았으니, 이제 장각의 본영까지 이 기세를 잇읍시다.',
'관우: 좋다. 이번 성과를 자랑으로만 남기지 말고 본영 진입의 군율로 삼자.'
]
});
}
function baseDialogue(options: {
reportSource: ThirdBattleReturnReportSource;
targetDialogueId: ThirdBattleReturnTargetDialogueId;
variantId: ThirdBattleReturnDialogueVariantId;
turnNumber: number;
fortAchieved: boolean;
quickAchieved: boolean;
title: string;
summary: string;
lines: [string, string, string];
}): ThirdBattlePriorityReturnDialogue {
return {
sourceBattleId: thirdBattleReturnSourceBattleId,
campStep: thirdBattleReturnCampStep,
targetDialogueId: options.targetDialogueId,
priorityLabel: thirdBattleReturnPriorityLabel,
reportSource: options.reportSource,
variantId: options.variantId,
turnNumber: options.turnNumber,
fortAchieved: options.fortAchieved,
quickAchieved: options.quickAchieved,
title: options.title,
summary: options.summary,
lines: [...options.lines]
};
}
function quickResultText(
quickAchieved: boolean,
turnNumber: number
) {
return quickAchieved
? `${turnNumber}턴 신속 승리`
: `${turnNumber}턴 · ${thirdBattleReturnQuickVictoryTurnLimit}턴 제한 초과`;
}
function positiveInteger(value: unknown) {
return (
typeof value === 'number' &&
Number.isInteger(value) &&
value > 0 &&
value <= 9999
)
? value
: undefined;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(
value &&
typeof value === 'object' &&
!Array.isArray(value)
);
}

View File

@@ -44,6 +44,11 @@ import {
secondBattleReliefSourceBattleId,
secondBattleReliefVisitId
} from '../data/secondBattleReliefExploration';
import {
resolveThirdBattlePriorityReturnDialogue,
thirdBattleReturnCampStep,
thirdBattleReturnSourceBattleId
} from '../data/thirdBattleReturnDialogue';
import {
findCityStayAfterBattle,
type CityEquipmentOffer,
@@ -11643,7 +11648,18 @@ export class CampScene extends Phaser.Scene {
this.selectedSortieUnitIds = this.normalizedSortieUnitIds(this.campaign.selectedSortieUnitIds);
this.sortieFormationAssignments = this.normalizedSortieFormationAssignments(this.campaign.sortieFormationAssignments);
this.sortieItemAssignments = this.normalizedSortieItemAssignments(this.campaign.sortieItemAssignments);
this.selectedDialogueId = this.availableCampDialogues()[0]?.id ?? campDialogues[0].id;
const availableCampDialogues = this.availableCampDialogues();
const priorityReturnDialogue = this.thirdBattlePriorityReturnDialogue();
const pendingPriorityReturnDialogueId =
priorityReturnDialogue &&
!this.completedCampDialogues().includes(priorityReturnDialogue.targetDialogueId) &&
availableCampDialogues.some((dialogue) => dialogue.id === priorityReturnDialogue.targetDialogueId)
? priorityReturnDialogue.targetDialogueId
: undefined;
this.selectedDialogueId =
pendingPriorityReturnDialogueId ??
availableCampDialogues[0]?.id ??
campDialogues[0].id;
this.selectedVisitId = this.availableCampVisits()[0]?.id ?? campVisits[0].id;
const cityStay = this.currentCityStay();
if (cityStay) {
@@ -12883,6 +12899,18 @@ export class CampScene extends Phaser.Scene {
return resolveFirstBattleCamaraderieMemory(this.campaign);
}
private thirdBattlePriorityReturnDialogue() {
if (
!this.campaign ||
this.retrySortieBattleId ||
this.campaign.step !== thirdBattleReturnCampStep ||
this.currentCampBattleId() !== thirdBattleReturnSourceBattleId
) {
return undefined;
}
return resolveThirdBattlePriorityReturnDialogue(this.campaign);
}
private firstPursuitScoutMemoryForNextSortie() {
const campaign = this.campaign;
const scenario = this.nextSortieScenario();
@@ -12917,6 +12945,18 @@ export class CampScene extends Phaser.Scene {
};
}
private campDialogueWithThirdBattlePriorityReturn(dialogue: CampDialogue) {
const priorityReturnDialogue = this.thirdBattlePriorityReturnDialogue();
if (!priorityReturnDialogue || dialogue.id !== priorityReturnDialogue.targetDialogueId) {
return dialogue;
}
return {
...dialogue,
title: priorityReturnDialogue.title,
lines: [...priorityReturnDialogue.lines]
};
}
private hasPendingFirstBattleCampFollowup() {
const followup = this.firstBattleCampFollowup();
return Boolean(
@@ -12933,6 +12973,14 @@ export class CampScene extends Phaser.Scene {
);
}
private hasPendingThirdBattlePriorityReturn() {
const priorityReturnDialogue = this.thirdBattlePriorityReturnDialogue();
return Boolean(
priorityReturnDialogue &&
!this.completedCampDialogues().includes(priorityReturnDialogue.targetDialogueId)
);
}
private availableCampDialogues(): CampDialogue[] {
const battleId = this.currentCampBattleId();
const battleDialogues = campDialogues.filter((dialogue) => dialogue.availableAfterBattleIds.includes(battleId));
@@ -12940,7 +12988,9 @@ export class CampScene extends Phaser.Scene {
const available = dialogues.length > 0
? dialogues
: campDialogues.filter((dialogue) => dialogue.availableAfterBattleIds.includes(defaultBattleScenario.id));
const resolved = available.map((dialogue) => this.campDialogueWithFirstBattleFollowup(dialogue));
const resolved = available
.map((dialogue) => this.campDialogueWithFirstBattleFollowup(dialogue))
.map((dialogue) => this.campDialogueWithThirdBattlePriorityReturn(dialogue));
const camaraderieDialogue = this.firstBattleCamaraderieDialogue();
return camaraderieDialogue && !resolved.some((dialogue) => dialogue.id === camaraderieDialogue.id)
? [...resolved, camaraderieDialogue]
@@ -13936,6 +13986,7 @@ export class CampScene extends Phaser.Scene {
const active = this.activeTab === tab;
const pendingFirstBattleFollowup = tab === 'dialogue' && this.hasPendingFirstBattleCampFollowup();
const pendingCamaraderieMemory = tab === 'dialogue' && this.hasPendingFirstBattleCamaraderieMemory();
const pendingThirdBattleReturn = tab === 'dialogue' && this.hasPendingThirdBattlePriorityReturn();
const pendingCampVisit = tab === 'visit' && this.availableCampVisits().some(
(visit) => !this.completedCampVisits().includes(visit.id)
);
@@ -13946,11 +13997,19 @@ export class CampScene extends Phaser.Scene {
indicator.setVisible(active || hovered);
indicator.setAlpha(active ? 1 : 0.66);
if (tab === 'dialogue' && newBadge) {
newBadge.setText(pendingFirstBattleFollowup ? '회고' : pendingCamaraderieMemory ? '전우' : '회고');
newBadge.setText(
pendingThirdBattleReturn
? '우선'
: pendingFirstBattleFollowup
? '회고'
: pendingCamaraderieMemory
? '전우'
: '회고'
);
}
newBadge?.setVisible(Boolean(
(tab === 'city' && this.hasPendingCityStayActions()) ||
(tab === 'dialogue' && (pendingFirstBattleFollowup || pendingCamaraderieMemory)) ||
(tab === 'dialogue' && (pendingThirdBattleReturn || pendingFirstBattleFollowup || pendingCamaraderieMemory)) ||
pendingCampVisit ||
(tab === 'supplies' && pendingCategories.has('supplies')) ||
(tab === 'equipment' && pendingCategories.has('equipment'))
@@ -19838,6 +19897,11 @@ export class CampScene extends Phaser.Scene {
bg.setStrokeStyle(1, palette.gold, 0.4);
const availableDialogues = this.availableCampDialogues();
const completedDialogues = this.completedAvailableDialogues().length;
const thirdBattlePriorityReturn = this.thirdBattlePriorityReturnDialogue();
const priorityDialogueCompleted = Boolean(
thirdBattlePriorityReturn &&
this.completedCampDialogues().includes(thirdBattlePriorityReturn.targetDialogueId)
);
const availableVisits = this.availableCampVisits();
const completedVisits = this.completedAvailableVisits().length;
const selectedUnits = this.selectedSortieUnits();
@@ -19852,8 +19916,14 @@ export class CampScene extends Phaser.Scene {
const sortieNote = this.nextSortieRule().note;
const recoveryHint = this.sortieRecoveryHint();
const hasBattle = Boolean(this.nextSortieScenario());
const dialogueProgress = thirdBattlePriorityReturn
? `대화 우선 ${priorityDialogueCompleted ? 1 : 0}/1 · 선택 ${Math.max(
0,
completedDialogues - Number(priorityDialogueCompleted)
)}/${Math.max(0, availableDialogues.length - 1)}`
: `대화 ${completedDialogues}/${availableDialogues.length}`;
const readyLine = [
`대화 ${completedDialogues}/${availableDialogues.length}`,
dialogueProgress,
`방문 ${completedVisits}/${availableVisits.length}`,
`${hasBattle ? '출전' : '동행'} ${selectedSummary}`,
`보유 ${inventorySummary}`
@@ -20111,6 +20181,20 @@ export class CampScene extends Phaser.Scene {
const assignedSupplyCount = campSupplies.reduce((total, supply) => total + this.totalAssignedSupplyCount(supply.usableId), 0);
const availableDialogues = this.availableCampDialogues();
const completedDialogues = this.completedAvailableDialogues().length;
const thirdBattlePriorityReturn = this.thirdBattlePriorityReturnDialogue();
const priorityDialogueCompleted = Boolean(
thirdBattlePriorityReturn &&
this.completedCampDialogues().includes(thirdBattlePriorityReturn.targetDialogueId)
);
const dialogueChecklistComplete = thirdBattlePriorityReturn
? priorityDialogueCompleted
: availableDialogues.length === 0 || completedDialogues >= availableDialogues.length;
const dialogueChecklistDetail = thirdBattlePriorityReturn
? `우선 ${priorityDialogueCompleted ? 1 : 0}/1 · 선택 ${Math.max(
0,
completedDialogues - Number(priorityDialogueCompleted)
)}/${Math.max(0, availableDialogues.length - 1)}`
: `${completedDialogues}/${availableDialogues.length} 완료`;
const availableVisits = this.availableCampVisits();
const completedVisits = this.completedAvailableVisits().length;
const selected = this.selectedSortieUnits();
@@ -20176,8 +20260,8 @@ export class CampScene extends Phaser.Scene {
},
{
label: '공명 대화',
complete: availableDialogues.length === 0 || completedDialogues >= availableDialogues.length,
detail: `${completedDialogues}/${availableDialogues.length} 완료`,
complete: dialogueChecklistComplete,
detail: dialogueChecklistDetail,
priority: 'recommended'
},
{
@@ -22740,6 +22824,7 @@ export class CampScene extends Phaser.Scene {
const dialogues = this.availableCampDialogues();
const firstBattleFollowup = this.firstBattleCampFollowup();
const camaraderieDialogue = this.firstBattleCamaraderieDialogue();
const thirdBattlePriorityReturn = this.thirdBattlePriorityReturnDialogue();
const compactDialogueList = dialogues.length > 3;
const dialogueRowGap = compactDialogueList ? 35 : 64;
const dialogueRowHeight = compactDialogueList ? 30 : 48;
@@ -22764,12 +22849,22 @@ export class CampScene extends Phaser.Scene {
});
const isFirstBattleFollowup = firstBattleFollowup?.targetDialogueId === dialogue.id;
const isCamaraderieMemory = camaraderieDialogue?.id === dialogue.id;
const title = isFirstBattleFollowup || isCamaraderieMemory
const isThirdBattlePriorityReturn =
thirdBattlePriorityReturn?.targetDialogueId === dialogue.id;
const pendingThirdBattlePriorityReturn =
isThirdBattlePriorityReturn && !completed;
const title = isFirstBattleFollowup || isCamaraderieMemory || isThirdBattlePriorityReturn
? this.compactText(dialogue.title, compactDialogueList ? 20 : 14)
: dialogue.title;
this.track(this.add.text(x + 38, rowY + (compactDialogueList ? 3 : 8), title, this.textStyle(compactDialogueList ? 11 : 15, completed ? '#a8ffd0' : '#f2e3bf', true)));
if (isFirstBattleFollowup || isCamaraderieMemory) {
const badgeLabel = completed ? '완료' : isCamaraderieMemory ? '전우 기억' : '회고';
if (isFirstBattleFollowup || isCamaraderieMemory || pendingThirdBattlePriorityReturn) {
const badgeLabel = pendingThirdBattlePriorityReturn
? thirdBattlePriorityReturn?.priorityLabel ?? '새 이야기 · 우선'
: completed
? '완료'
: isCamaraderieMemory
? '전우 기억'
: '회고';
this.track(
this.add.text(
x + 320,
@@ -22777,7 +22872,13 @@ export class CampScene extends Phaser.Scene {
badgeLabel,
{
...this.textStyle(compactDialogueList ? 8 : 9, completed ? '#a8ffd0' : '#fff2b8', true),
backgroundColor: completed ? '#21402d' : isCamaraderieMemory ? '#36507a' : '#8a3f25',
backgroundColor: completed
? '#21402d'
: pendingThirdBattlePriorityReturn
? '#8a3f25'
: isCamaraderieMemory
? '#36507a'
: '#8a3f25',
padding: { x: 4, y: 2 }
}
)
@@ -22803,12 +22904,25 @@ export class CampScene extends Phaser.Scene {
return;
}
const completed = this.completedCampDialogues().includes(dialogue.id);
const thirdBattlePriorityReturn = this.thirdBattlePriorityReturnDialogue();
const isThirdBattlePriorityReturn =
thirdBattlePriorityReturn?.targetDialogueId === dialogue.id;
const bg = this.track(this.add.rectangle(x, y, width, height, 0x0d141c, 0.92));
bg.setOrigin(0);
bg.setStrokeStyle(1, completed ? palette.green : palette.gold, 0.5);
this.track(this.add.text(x + 18, y + 16, dialogue.title, this.textStyle(20, '#f2e3bf', true)));
if (isThirdBattlePriorityReturn) {
this.track(
this.add.text(
x + 18,
y + 45,
`전투 기록 · ${thirdBattlePriorityReturn.summary}`,
this.textStyle(11, completed ? '#a8ffd0' : '#ffdf7b', true)
)
);
}
const dialogueBody = this.track(
this.add.text(x + 18, y + 52, dialogue.lines.join('\n'), {
this.add.text(x + 18, y + (isThirdBattlePriorityReturn ? 70 : 52), dialogue.lines.join('\n'), {
...this.textStyle(14, '#d4dce6'),
wordWrap: { width: width - 36, useAdvancedWrap: true },
lineSpacing: 3
@@ -24152,11 +24266,14 @@ export class CampScene extends Phaser.Scene {
private showDialogueReward(dialogue: CampDialogue, choice: CampDialogueChoice, rewardExp: number) {
const followup = this.firstBattleCampFollowup();
const camaraderieMemory = this.firstBattleCamaraderieMemory();
const thirdBattlePriorityReturn = this.thirdBattlePriorityReturnDialogue();
const preparationLine = camaraderieMemory?.dialogue.id === dialogue.id
? `\n다음 준비 · ${camaraderieMemory.unitNames.join('↔')}를 직접 핵심 공명조로 지정하면 추격 +${camaraderieMemory.bonusRate}%p · 자동 지정 없음`
: followup?.targetDialogueId === dialogue.id
? `\n다음 준비 · ${followup.recommendationTitle}`
: '';
: thirdBattlePriorityReturn?.targetDialogueId === dialogue.id
? '\n귀환 회고 완료 · 나머지 동료 대화는 자유 선택'
: '';
this.showCampNotice(`획득 내역 · ${choice.label} · 공명 +${rewardExp}\n응답 · ${choice.response}${preparationLine}`);
}
@@ -25155,6 +25272,7 @@ export class CampScene extends Phaser.Scene {
const firstBattleCampFollowup = this.firstBattleCampFollowup();
const firstBattleCamaraderieMemory = this.firstBattleCamaraderieMemory();
const firstBattleCamaraderieDialogue = this.firstBattleCamaraderieDialogue();
const thirdBattlePriorityReturn = this.thirdBattlePriorityReturnDialogue();
const firstPursuitScoutVisit = this.availableCampVisits().find(
(visit) => visit.id === firstPursuitScoutVisitId
);
@@ -25326,6 +25444,32 @@ export class CampScene extends Phaser.Scene {
}
}
: null,
thirdBattlePriorityReturn: thirdBattlePriorityReturn
? {
available: true,
sourceBattleId: thirdBattlePriorityReturn.sourceBattleId,
sourceTurn: thirdBattlePriorityReturn.turnNumber,
reportSource: thirdBattlePriorityReturn.reportSource,
fortAchieved: thirdBattlePriorityReturn.fortAchieved,
quickAchieved: thirdBattlePriorityReturn.quickAchieved,
variant: thirdBattlePriorityReturn.variantId,
targetDialogueId: thirdBattlePriorityReturn.targetDialogueId,
priorityLabel: thirdBattlePriorityReturn.priorityLabel,
summary: thirdBattlePriorityReturn.summary,
dialogueTitle: thirdBattlePriorityReturn.title,
dialogueLines: [...thirdBattlePriorityReturn.lines],
selected: this.selectedDialogueId === thirdBattlePriorityReturn.targetDialogueId,
completed: this.completedCampDialogues().includes(
thirdBattlePriorityReturn.targetDialogueId
),
pending: !this.completedCampDialogues().includes(
thirdBattlePriorityReturn.targetDialogueId
),
rowBounds: this.sortieObjectBoundsDebug(
this.campDialogueRowButtons[thirdBattlePriorityReturn.targetDialogueId]
)
}
: null,
firstPursuitScoutMemory: {
visitId: firstPursuitScoutVisitId,
available: Boolean(firstPursuitScoutVisit),
@@ -25396,6 +25540,8 @@ export class CampScene extends Phaser.Scene {
completed: this.completedCampDialogues().includes(selectedCampDialogue.id),
firstVictoryFollowup: firstBattleCampFollowup?.targetDialogueId === selectedCampDialogue.id,
camaraderieMemory: firstBattleCamaraderieMemory?.dialogue.id === selectedCampDialogue.id,
thirdBattlePriorityReturn:
thirdBattlePriorityReturn?.targetDialogueId === selectedCampDialogue.id,
rowBounds: this.sortieObjectBoundsDebug(this.campDialogueRowButtons[selectedCampDialogue.id]),
bodyBounds: this.sortieTextBoundsDebug(this.campDialogueBodyText),
choices: selectedCampDialogue.choices.map((choice) => ({