diff --git a/lib/src/core/engine/test_character_service.dart b/lib/src/core/engine/test_character_service.dart index 1039f2c..2125ff5 100644 --- a/lib/src/core/engine/test_character_service.dart +++ b/lib/src/core/engine/test_character_service.dart @@ -142,16 +142,8 @@ class TestCharacterService { 'Exception Handler', 'Null Guard', ], - EquipmentSlot.helm => [ - 'Neural Helm', - 'Thought Processor', - 'Mind Buffer', - ], - EquipmentSlot.hauberk => [ - 'Matrix Armor', - 'Byte Mail', - 'Kernel Plate', - ], + EquipmentSlot.helm => ['Neural Helm', 'Thought Processor', 'Mind Buffer'], + EquipmentSlot.hauberk => ['Matrix Armor', 'Byte Mail', 'Kernel Plate'], EquipmentSlot.brassairts => [ 'Bit Guards', 'Stream Bracers', @@ -167,11 +159,7 @@ class TestCharacterService { 'Handler Mitts', 'Pointer Grips', ], - EquipmentSlot.gambeson => [ - 'Layer Vest', - 'Cache Coat', - 'Buffer Jacket', - ], + EquipmentSlot.gambeson => ['Layer Vest', 'Cache Coat', 'Buffer Jacket'], EquipmentSlot.cuisses => [ 'Register Guards', 'Stack Protectors', diff --git a/lib/src/core/l10n/game_data_l10n.dart b/lib/src/core/l10n/game_data_l10n.dart index b81ec55..e7a2ac7 100644 --- a/lib/src/core/l10n/game_data_l10n.dart +++ b/lib/src/core/l10n/game_data_l10n.dart @@ -450,7 +450,9 @@ class GameDataL10n { final special = words.last; // Attrib와 Special이 유효한지 확인 - final attribMap = isKo ? itemAttribTranslationsKo : itemAttribTranslationsJa; + final attribMap = isKo + ? itemAttribTranslationsKo + : itemAttribTranslationsJa; final specialMap = isKo ? specialTranslationsKo : specialTranslationsJa; if (!attribMap.containsKey(attrib) && !specialMap.containsKey(special)) { return null; @@ -472,7 +474,9 @@ class GameDataL10n { static String? _tryTranslateMonsterDrop(String itemString, bool isKo) { // 드롭 아이템 번역 맵 선택 (통합 맵 사용) final dropMap = isKo ? allDropTranslationsKo : allDropTranslationsJa; - final monsterMap = isKo ? allMonsterTranslationsKo : allMonsterTranslationsJa; + final monsterMap = isKo + ? allMonsterTranslationsKo + : allMonsterTranslationsJa; // (대소문자 무시, 아이템 문자열 끝에서 매칭) for (final entry in dropMap.entries) { diff --git a/lib/src/core/model/save_data.dart b/lib/src/core/model/save_data.dart index eb16d81..56788fb 100644 --- a/lib/src/core/model/save_data.dart +++ b/lib/src/core/model/save_data.dart @@ -181,7 +181,10 @@ class GameSave { ) .toList(), ), - equipment: _equipmentFromJson(equipmentJson, json['version'] as int? ?? 2), + equipment: _equipmentFromJson( + equipmentJson, + json['version'] as int? ?? 2, + ), skillBook: SkillBook( skills: skillsJson .map( @@ -333,10 +336,7 @@ Equipment _equipmentFromJson(Map json, int version) { } } - return Equipment( - items: items, - bestIndex: json['bestIndex'] as int? ?? 0, - ); + return Equipment(items: items, bestIndex: json['bestIndex'] as int? ?? 0); } // v2 이하: 레거시 형식 (문자열 기반) diff --git a/lib/src/features/arena/widgets/arena_result_panel.dart b/lib/src/features/arena/widgets/arena_result_panel.dart index ab01ac0..99cb681 100644 --- a/lib/src/features/arena/widgets/arena_result_panel.dart +++ b/lib/src/features/arena/widgets/arena_result_panel.dart @@ -96,7 +96,8 @@ class _ArenaResultPanelState extends State try { // macOS: Downloads 폴더에 저장 (사용자가 쉽게 찾을 수 있도록) - final directory = await getDownloadsDirectory() ?? + final directory = + await getDownloadsDirectory() ?? await getApplicationDocumentsDirectory(); final timestamp = DateTime.now().toIso8601String().replaceAll(':', '-'); final challenger = widget.result.match.challenger.characterName; @@ -164,13 +165,15 @@ class _ArenaResultPanelState extends State 'class': entry.klass, 'combatStats': entry.finalStats?.toJson(), 'equipment': entry.finalEquipment - ?.map((EquipmentItem e) => { - 'slot': e.slot.name, - 'name': e.name, - 'level': e.level, - 'rarity': e.rarity.name, - 'stats': e.stats.toJson(), - }) + ?.map( + (EquipmentItem e) => { + 'slot': e.slot.name, + 'name': e.name, + 'level': e.level, + 'rarity': e.rarity.name, + 'stats': e.stats.toJson(), + }, + ) .toList(), 'skills': entry.finalSkills, }; diff --git a/lib/src/features/front/front_screen.dart b/lib/src/features/front/front_screen.dart index 673a4ed..ee71eac 100644 --- a/lib/src/features/front/front_screen.dart +++ b/lib/src/features/front/front_screen.dart @@ -142,7 +142,8 @@ class _FrontScreenState extends State with RouteAware { onHallOfFame: widget.onHallOfFame != null ? () => widget.onHallOfFame!(context) : null, - onLocalArena: widget.onLocalArena != null && + onLocalArena: + widget.onLocalArena != null && widget.hallOfFameCount >= 2 ? () => widget.onLocalArena!(context) : null, diff --git a/lib/src/features/settings/settings_screen.dart b/lib/src/features/settings/settings_screen.dart index 49ecd23..3a09923 100644 --- a/lib/src/features/settings/settings_screen.dart +++ b/lib/src/features/settings/settings_screen.dart @@ -206,7 +206,9 @@ class _SettingsScreenState extends State { Widget _buildDebugSection() { return Card( - color: Theme.of(context).colorScheme.errorContainer.withValues(alpha: 0.3), + color: Theme.of( + context, + ).colorScheme.errorContainer.withValues(alpha: 0.3), child: Padding( padding: const EdgeInsets.all(16), child: Column( diff --git a/test/core/util/balance_analysis_test.dart b/test/core/util/balance_analysis_test.dart index f8b9bcf..5115f3b 100644 --- a/test/core/util/balance_analysis_test.dart +++ b/test/core/util/balance_analysis_test.dart @@ -64,7 +64,9 @@ void main() { final diagnosis = sim.winRate >= targetWinRate ? '✓ 적정' : '✗ 조정필요 (목표: ${(targetWinRate * 100).toStringAsFixed(0)}%)'; - print('레벨 $level (${tier.name}): 승률 ${(sim.winRate * 100).toStringAsFixed(0)}% $diagnosis'); + print( + '레벨 $level (${tier.name}): 승률 ${(sim.winRate * 100).toStringAsFixed(0)}% $diagnosis', + ); } print('\n${'=' * 80}'); @@ -88,7 +90,9 @@ void main() { final minDamage = (monster.atk * 0.8 - player.def * 0.3).round(); final maxDamage = (monster.atk * 1.2 - player.def * 0.3).round(); print('- 몬스터 데미지: $minDamage ~ $maxDamage'); - print('- 플레이어 생존 히트: ${(player.hp / maxDamage).floor()} ~ ${(player.hp / minDamage).ceil()}'); + print( + '- 플레이어 생존 히트: ${(player.hp / maxDamage).floor()} ~ ${(player.hp / minDamage).ceil()}', + ); print('\n#### 적용된 밸런스 수정'); print('1. 플레이어 HP 스케일링 상향:'); @@ -136,7 +140,8 @@ _PlayerEstimate _estimatePlayerStats(int level) { // 장비 스탯 추정 (레벨 * 0.8 수준의 common 장비 10개) final equipLevel = (level * 0.8).round().clamp(1, level); - final equipBaseValue = (equipLevel * 1.2 * ItemRarity.common.multiplier).round(); + final equipBaseValue = (equipLevel * 1.2 * ItemRarity.common.multiplier) + .round(); // 무기 ATK (speedMultiplier 1.0 가정) final weaponAtk = equipBaseValue; @@ -182,8 +187,14 @@ _CombatSimulation _simulateCombat(int level) { // 데미지 계산 (combat_calculator 평균) // damage = ATK * 1.0 - DEF * 0.5 (DEF 감산율 상향) - final monsterDamage = (monster.atk * 1.0 - player.def * 0.5).round().clamp(1, 9999); - final playerDamage = (player.atk * 1.0 - monster.def * 0.5).round().clamp(1, 9999); + final monsterDamage = (monster.atk * 1.0 - player.def * 0.5).round().clamp( + 1, + 9999, + ); + final playerDamage = (player.atk * 1.0 - monster.def * 0.5).round().clamp( + 1, + 9999, + ); // 생존 히트 수 final playerHits = (player.hp / monsterDamage).ceil(); @@ -194,8 +205,8 @@ _CombatSimulation _simulateCombat(int level) { final winRate = playerHits > monsterHits ? 0.95 // 압도적 유리 : playerHits == monsterHits - ? 0.65 // 동등 (선공 이점) - : (playerHits / monsterHits).clamp(0.2, 0.9); + ? 0.65 // 동등 (선공 이점) + : (playerHits / monsterHits).clamp(0.2, 0.9); return _CombatSimulation( monsterDamage: monsterDamage, diff --git a/test/core/util/balance_constants_test.dart b/test/core/util/balance_constants_test.dart index 8fc7fde..86b5cf4 100644 --- a/test/core/util/balance_constants_test.dart +++ b/test/core/util/balance_constants_test.dart @@ -55,8 +55,16 @@ void main() { final oldAtk = 10 + level * 12; final newAtk = MonsterBaseStats.forLevel(level).atk; final ratio = newAtk / oldAtk; - expect(ratio, lessThan(0.45), reason: 'Level $level should be < 45% of old'); - expect(ratio, greaterThan(0.25), reason: 'Level $level should be > 25% of old'); + expect( + ratio, + lessThan(0.45), + reason: 'Level $level should be < 45% of old', + ); + expect( + ratio, + greaterThan(0.25), + reason: 'Level $level should be > 25% of old', + ); } // 레벨 1~5는 추가 완화 (기존 대비 더 낮음) @@ -64,8 +72,16 @@ void main() { final oldAtk = 10 + level * 12; final newAtk = MonsterBaseStats.forLevel(level).atk; final ratio = newAtk / oldAtk; - expect(ratio, lessThan(0.35), reason: 'Early level $level should be < 35% of old'); - expect(ratio, greaterThan(0.15), reason: 'Early level $level should be > 15% of old'); + expect( + ratio, + lessThan(0.35), + reason: 'Early level $level should be < 35% of old', + ); + expect( + ratio, + greaterThan(0.15), + reason: 'Early level $level should be > 15% of old', + ); } }); });