Enable companion recommendations without next battle

This commit is contained in:
2026-07-05 05:54:04 +09:00
parent 9223b04d13
commit ba61e6ea72

View File

@@ -12562,9 +12562,11 @@ export class CampScene extends Phaser.Scene {
bg.setStrokeStyle(1, palette.gold, 0.5); bg.setStrokeStyle(1, palette.gold, 0.5);
const plan = this.sortiePlanSummary(); const plan = this.sortiePlanSummary();
const hasBattle = Boolean(this.nextSortieScenario()); const scenario = this.nextSortieScenario();
const hasBattle = Boolean(scenario);
const canRecommend = this.canApplyRecommendedSortiePlan(scenario);
this.trackSortie(this.add.text(x + 18, y + 14, hasBattle ? '출전 슬롯' : '동행 명단', this.textStyle(18, '#f2e3bf', true))).setDepth(depth + 1); this.trackSortie(this.add.text(x + 18, y + 14, hasBattle ? '출전 슬롯' : '동행 명단', this.textStyle(18, '#f2e3bf', true))).setDepth(depth + 1);
this.renderSortiePanelButton(hasBattle ? '추천 편성' : '추천 동행', x + width - 104, y + 10, 86, 22, hasBattle, false, () => this.applyRecommendedSortiePlan(), depth + 1); this.renderSortiePanelButton(hasBattle ? '추천 편성' : '추천 동행', x + width - 104, y + 10, 86, 22, canRecommend, false, () => this.applyRecommendedSortiePlan(), depth + 1);
this.trackSortie( this.trackSortie(
this.add.text( this.add.text(
x + 18, x + 18,
@@ -13390,8 +13392,9 @@ export class CampScene extends Phaser.Scene {
private applyRecommendedSortiePlan() { private applyRecommendedSortiePlan() {
const scenario = this.nextSortieScenario(); const scenario = this.nextSortieScenario();
if (!scenario) { const hasBattle = Boolean(scenario);
this.showCampNotice('다음 전투가 정해지면 추천 편성을 사용할 수 있습니다.'); if (!this.canApplyRecommendedSortiePlan(scenario)) {
this.showCampNotice(hasBattle ? '추천 편성 후보가 없습니다.' : '추천 동행 후보가 없습니다.');
return; return;
} }
@@ -13429,13 +13432,20 @@ export class CampScene extends Phaser.Scene {
this.selectedSortieUnitIds = nextSelectedIds; this.selectedSortieUnitIds = nextSelectedIds;
this.sortieFormationAssignments = this.normalizedSortieFormationAssignments(nextAssignments); this.sortieFormationAssignments = this.normalizedSortieFormationAssignments(nextAssignments);
this.sortieFocusedUnitId = nextSelectedIds[0] ?? this.sortieFocusedUnitId; this.sortieFocusedUnitId = nextSelectedIds[0] ?? this.sortieFocusedUnitId;
this.sortiePlanFeedback = this.recommendedSortieFeedback(nextSelectedIds, nextAssignments); this.sortiePlanFeedback = this.recommendedSortieFeedback(nextSelectedIds, nextAssignments, hasBattle);
this.persistSortieSelection(); this.persistSortieSelection();
soundDirector.playSelect(); soundDirector.playSelect();
this.showSortiePrep(); this.showSortiePrep();
} }
private recommendedSortieFeedback(unitIds: string[], assignments: SortieFormationAssignments) { private canApplyRecommendedSortiePlan(scenario = this.nextSortieScenario()) {
const rule = this.nextSortieRule(scenario);
const requiredCount = (rule.requiredUnitIds ?? defaultRequiredSortieUnitIds).length;
const recommendedCount = rule.recommended.length + (rule.recommendedClasses?.length ?? 0);
return this.sortieAllies().length > 0 && this.sortieMaxUnits(scenario) > 0 && requiredCount + recommendedCount > 0;
}
private recommendedSortieFeedback(unitIds: string[], assignments: SortieFormationAssignments, hasBattle = Boolean(this.nextSortieScenario())) {
const roleCounts = unitIds.reduce( const roleCounts = unitIds.reduce(
(counts, unitId) => { (counts, unitId) => {
counts[assignments[unitId] ?? 'reserve'] += 1; counts[assignments[unitId] ?? 'reserve'] += 1;
@@ -13445,7 +13455,7 @@ export class CampScene extends Phaser.Scene {
); );
const names = unitIds.slice(0, 3).map((id) => this.unitName(id)).join(', '); const names = unitIds.slice(0, 3).map((id) => this.unitName(id)).join(', ');
const extra = unitIds.length > 3 ? `${unitIds.length - 3}` : ''; const extra = unitIds.length > 3 ? `${unitIds.length - 3}` : '';
return `추천 편성 적용 · ${names}${extra} · 전열 ${roleCounts.front} / 돌파 ${roleCounts.flank} / 후원 ${roleCounts.support}`; return `${hasBattle ? '추천 편성' : '추천 동행'} 적용 · ${names}${extra} · 전열 ${roleCounts.front} / 돌파 ${roleCounts.flank} / 후원 ${roleCounts.support}`;
} }
private sortieTerrainScore(unit: UnitData, scenario: BattleScenarioDefinition | undefined) { private sortieTerrainScore(unit: UnitData, scenario: BattleScenarioDefinition | undefined) {
@@ -15085,16 +15095,19 @@ export class CampScene extends Phaser.Scene {
delete nextItemAssignments[unitId]; delete nextItemAssignments[unitId];
this.sortieItemAssignments = nextItemAssignments; this.sortieItemAssignments = nextItemAssignments;
} else if (selected.size >= this.sortieMaxUnits()) { } else if (selected.size >= this.sortieMaxUnits()) {
this.showCampNotice(`이번 전투는 최대 ${this.sortieMaxUnits()}명까지 출전할 수 있습니다.`); const hasBattle = Boolean(this.nextSortieScenario());
this.showCampNotice(`${hasBattle ? '이번 전투' : '이번 장면'}는 최대 ${this.sortieMaxUnits()}명까지 ${hasBattle ? '출전' : '동행'}할 수 있습니다.`);
return; return;
} else { } else {
selected.add(unitId); selected.add(unitId);
} }
this.selectedSortieUnitIds = this.normalizedSortieUnitIds(Array.from(selected)); this.selectedSortieUnitIds = this.normalizedSortieUnitIds(Array.from(selected));
const hasBattle = Boolean(this.nextSortieScenario());
const selectionLabel = hasBattle ? '출전' : '동행';
this.sortiePlanFeedback = selected.has(unitId) this.sortiePlanFeedback = selected.has(unitId)
? `${unit.name} 출전 추가 · 직접 편성 중` ? `${unit.name} ${selectionLabel} 추가 · 직접 편성 중`
: `${unit.name} 출전 해제 · 직접 편성 중`; : `${unit.name} ${selectionLabel} 해제 · 직접 편성 중`;
this.persistSortieSelection(); this.persistSortieSelection();
soundDirector.playSelect(); soundDirector.playSelect();
this.showSortiePrep(); this.showSortiePrep();
@@ -15350,10 +15363,13 @@ export class CampScene extends Phaser.Scene {
getDebugState() { getDebugState() {
const sortieChecklist = this.sortieChecklist(); const sortieChecklist = this.sortieChecklist();
const sortieScenario = this.nextSortieScenario();
return { return {
scene: this.scene.key, scene: this.scene.key,
activeTab: this.activeTab, activeTab: this.activeTab,
sortieVisible: this.sortieObjects.length > 0, sortieVisible: this.sortieObjects.length > 0,
sortieHasBattle: Boolean(sortieScenario),
sortieRecommendationEnabled: this.canApplyRecommendedSortiePlan(sortieScenario),
selectedUnitId: this.selectedUnitId, selectedUnitId: this.selectedUnitId,
selectedDialogueId: this.selectedDialogueId, selectedDialogueId: this.selectedDialogueId,
selectedVisitId: this.selectedVisitId, selectedVisitId: this.selectedVisitId,