style: dart format 적용
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<String, dynamic> json, int version) {
|
||||
}
|
||||
}
|
||||
|
||||
return Equipment(
|
||||
items: items,
|
||||
bestIndex: json['bestIndex'] as int? ?? 0,
|
||||
);
|
||||
return Equipment(items: items, bestIndex: json['bestIndex'] as int? ?? 0);
|
||||
}
|
||||
|
||||
// v2 이하: 레거시 형식 (문자열 기반)
|
||||
|
||||
@@ -96,7 +96,8 @@ class _ArenaResultPanelState extends State<ArenaResultPanel>
|
||||
|
||||
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<ArenaResultPanel>
|
||||
'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,
|
||||
};
|
||||
|
||||
@@ -142,7 +142,8 @@ class _FrontScreenState extends State<FrontScreen> 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,
|
||||
|
||||
@@ -206,7 +206,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
|
||||
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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user