From ba61e6ea72157d05618b37d9dd034472d9f1a196 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sun, 5 Jul 2026 05:54:04 +0900 Subject: [PATCH] Enable companion recommendations without next battle --- src/game/scenes/CampScene.ts | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/game/scenes/CampScene.ts b/src/game/scenes/CampScene.ts index 702fc06..d48f83e 100644 --- a/src/game/scenes/CampScene.ts +++ b/src/game/scenes/CampScene.ts @@ -12562,9 +12562,11 @@ export class CampScene extends Phaser.Scene { bg.setStrokeStyle(1, palette.gold, 0.5); 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.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.add.text( x + 18, @@ -13390,8 +13392,9 @@ export class CampScene extends Phaser.Scene { private applyRecommendedSortiePlan() { const scenario = this.nextSortieScenario(); - if (!scenario) { - this.showCampNotice('다음 전투가 정해지면 추천 편성을 사용할 수 있습니다.'); + const hasBattle = Boolean(scenario); + if (!this.canApplyRecommendedSortiePlan(scenario)) { + this.showCampNotice(hasBattle ? '추천 편성 후보가 없습니다.' : '추천 동행 후보가 없습니다.'); return; } @@ -13429,13 +13432,20 @@ export class CampScene extends Phaser.Scene { this.selectedSortieUnitIds = nextSelectedIds; this.sortieFormationAssignments = this.normalizedSortieFormationAssignments(nextAssignments); this.sortieFocusedUnitId = nextSelectedIds[0] ?? this.sortieFocusedUnitId; - this.sortiePlanFeedback = this.recommendedSortieFeedback(nextSelectedIds, nextAssignments); + this.sortiePlanFeedback = this.recommendedSortieFeedback(nextSelectedIds, nextAssignments, hasBattle); this.persistSortieSelection(); soundDirector.playSelect(); 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( (counts, unitId) => { 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 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) { @@ -15085,16 +15095,19 @@ export class CampScene extends Phaser.Scene { delete nextItemAssignments[unitId]; this.sortieItemAssignments = nextItemAssignments; } else if (selected.size >= this.sortieMaxUnits()) { - this.showCampNotice(`이번 전투는 최대 ${this.sortieMaxUnits()}명까지 출전할 수 있습니다.`); + const hasBattle = Boolean(this.nextSortieScenario()); + this.showCampNotice(`${hasBattle ? '이번 전투' : '이번 장면'}는 최대 ${this.sortieMaxUnits()}명까지 ${hasBattle ? '출전' : '동행'}할 수 있습니다.`); return; } else { selected.add(unitId); } this.selectedSortieUnitIds = this.normalizedSortieUnitIds(Array.from(selected)); + const hasBattle = Boolean(this.nextSortieScenario()); + const selectionLabel = hasBattle ? '출전' : '동행'; this.sortiePlanFeedback = selected.has(unitId) - ? `${unit.name} 출전 추가 · 직접 편성 중` - : `${unit.name} 출전 해제 · 직접 편성 중`; + ? `${unit.name} ${selectionLabel} 추가 · 직접 편성 중` + : `${unit.name} ${selectionLabel} 해제 · 직접 편성 중`; this.persistSortieSelection(); soundDirector.playSelect(); this.showSortiePrep(); @@ -15350,10 +15363,13 @@ export class CampScene extends Phaser.Scene { getDebugState() { const sortieChecklist = this.sortieChecklist(); + const sortieScenario = this.nextSortieScenario(); return { scene: this.scene.key, activeTab: this.activeTab, sortieVisible: this.sortieObjects.length > 0, + sortieHasBattle: Boolean(sortieScenario), + sortieRecommendationEnabled: this.canApplyRecommendedSortiePlan(sortieScenario), selectedUnitId: this.selectedUnitId, selectedDialogueId: this.selectedDialogueId, selectedVisitId: this.selectedVisitId,