feat(game): 게임 시스템 전면 개편 및 다국어 지원 확장

## 스킬 시스템 개선
- skill_data.dart: 스킬 데이터 구조 전면 개편 (+1176 라인)
- skill_service.dart: 스킬 발동 로직 확장 및 버프 시스템 연동
- skill.dart: 스킬 모델 개선, 쿨다운/효과 타입 추가

## Canvas 애니메이션 리팩토링
- battle_composer.dart 삭제 (레거시 위젯 기반 렌더러)
- monster_colors.dart 삭제 (AsciiCell 색상 시스템으로 통합)
- canvas_battle_composer.dart: z-index 정렬 (몬스터 z=1, 캐릭터 z=2, 이펙트 z=3)
- ascii_cell.dart, ascii_layer.dart: 코드 정리

## UI/UX 개선
- hp_mp_bar.dart: l10n 적용, 몬스터 HP 바 컴팩트화
- death_overlay.dart: 사망 화면 개선
- equipment_stats_panel.dart: 장비 스탯 표시 확장
- active_buff_panel.dart: 버프 패널 개선
- notification_overlay.dart: 알림 시스템 개선

## 다국어 지원 확장
- game_text_l10n.dart: 게임 텍스트 통합 (+758 라인)
- 한국어/일본어/영어/중국어 번역 업데이트
- ARB 파일 동기화

## 게임 로직 개선
- progress_service.dart: 진행 로직 리팩토링
- combat_calculator.dart: 전투 계산 로직 개선
- stat_calculator.dart: 스탯 계산 시스템 개선
- story_service.dart: 스토리 진행 로직 개선

## 기타
- theme_preferences.dart 삭제 (미사용)
- 테스트 파일 업데이트
- class_data.dart: 클래스 데이터 정리
This commit is contained in:
JiWoong Sul
2025-12-22 19:00:58 +09:00
parent f606fca063
commit 99f5b74802
63 changed files with 3403 additions and 2740 deletions

View File

@@ -99,6 +99,362 @@ String taskSelling(String itemDescription) {
return 'Selling $itemDescription';
}
// ============================================================================
// 부활 시퀀스 메시지
// ============================================================================
String get taskReturningToTown {
if (isKoreanLocale) return '마을로 귀환 중...';
if (isJapaneseLocale) return '町に戻っている...';
return 'Returning to town...';
}
String get taskRestockingAtShop {
if (isKoreanLocale) return '상점에서 장비 정비 중...';
if (isJapaneseLocale) return 'ショップで装備を整備中...';
return 'Restocking at shop...';
}
String get taskHeadingToHuntingGrounds {
if (isKoreanLocale) return '사냥터로 이동 중...';
if (isJapaneseLocale) return '狩り場へ向かっている...';
return 'Heading to hunting grounds...';
}
// ============================================================================
// 사망 화면 메시지
// ============================================================================
String get deathYouDied {
if (isKoreanLocale) return '사망';
if (isJapaneseLocale) return '死亡';
return 'YOU DIED';
}
String get deathSacrificedToResurrect {
if (isKoreanLocale) return '부활 대가로 희생됨';
if (isJapaneseLocale) return '復活のために犠牲';
return 'Sacrificed to Resurrect';
}
String get deathEquipment {
if (isKoreanLocale) return '장비';
if (isJapaneseLocale) return '装備';
return 'Equipment';
}
String get deathNoSacrificeNeeded {
if (isKoreanLocale) return '희생 없이 부활';
if (isJapaneseLocale) return '犠牲なしで復活';
return 'No sacrifice needed';
}
String get deathGoldRemaining {
if (isKoreanLocale) return '남은 골드';
if (isJapaneseLocale) return '残りゴールド';
return 'Gold Remaining';
}
String get deathResurrect {
if (isKoreanLocale) return '부활';
if (isJapaneseLocale) return '復活';
return 'Resurrect';
}
String get deathCombatLog {
if (isKoreanLocale) return '전투 기록';
if (isJapaneseLocale) return '戦闘ログ';
return 'Combat Log';
}
String deathKilledBy(String killerName) {
if (isKoreanLocale) return '$killerName에게 사망';
if (isJapaneseLocale) return '$killerNameに倒された';
return 'Killed by $killerName';
}
String get deathEnvironmentalHazard {
if (isKoreanLocale) return '환경 피해로 사망';
if (isJapaneseLocale) return '環境ダメージで死亡';
return 'Environmental hazard';
}
// ============================================================================
// UI 일반 메시지
// ============================================================================
String get uiNoPotions {
if (isKoreanLocale) return '포션 없음';
if (isJapaneseLocale) return 'ポーションなし';
return 'No potions';
}
String get uiTapToContinue {
if (isKoreanLocale) return '탭하여 계속';
if (isJapaneseLocale) return 'タップして続行';
return 'Tap to continue';
}
String get uiNoSkills {
if (isKoreanLocale) return '습득한 스킬이 없습니다';
if (isJapaneseLocale) return 'スキルなし';
return 'No skills';
}
String get uiNoBonusStats {
if (isKoreanLocale) return '추가 스탯 없음';
if (isJapaneseLocale) return 'ボーナスステータスなし';
return 'No bonus stats';
}
String get uiNoActiveBuffs {
if (isKoreanLocale) return '활성 버프 없음';
if (isJapaneseLocale) return 'アクティブバフなし';
return 'No active buffs';
}
String get uiReady {
if (isKoreanLocale) return '준비';
if (isJapaneseLocale) return '準備完了';
return 'Ready';
}
String get uiPotions {
if (isKoreanLocale) return '포션';
if (isJapaneseLocale) return 'ポーション';
return 'Potions';
}
String get uiBuffs {
if (isKoreanLocale) return '버프';
if (isJapaneseLocale) return 'バフ';
return 'Buffs';
}
// ============================================================================
// 스탯 약어
// ============================================================================
String get statStr {
if (isKoreanLocale) return '';
if (isJapaneseLocale) return '筋力';
return 'STR';
}
String get statCon {
if (isKoreanLocale) return '체력';
if (isJapaneseLocale) return '耐久';
return 'CON';
}
String get statDex {
if (isKoreanLocale) return '민첩';
if (isJapaneseLocale) return '敏捷';
return 'DEX';
}
String get statInt {
if (isKoreanLocale) return '지능';
if (isJapaneseLocale) return '知力';
return 'INT';
}
String get statWis {
if (isKoreanLocale) return '지혜';
if (isJapaneseLocale) return '精神';
return 'WIS';
}
String get statCha {
if (isKoreanLocale) return '매력';
if (isJapaneseLocale) return '魅力';
return 'CHA';
}
// ============================================================================
// 패시브 능력 설명
// ============================================================================
String passiveHpBonus(int percent) {
if (isKoreanLocale) return 'HP +$percent%';
if (isJapaneseLocale) return 'HP +$percent%';
return 'HP +$percent%';
}
String passiveMpBonus(int percent) {
if (isKoreanLocale) return 'MP +$percent%';
if (isJapaneseLocale) return 'MP +$percent%';
return 'MP +$percent%';
}
String passivePhysicalBonus(int percent) {
if (isKoreanLocale) return '물리 공격 +$percent%';
if (isJapaneseLocale) return '物理攻撃 +$percent%';
return 'Physical +$percent%';
}
String passiveDefenseBonus(int percent) {
if (isKoreanLocale) return '방어력 +$percent%';
if (isJapaneseLocale) return '防御力 +$percent%';
return 'Defense +$percent%';
}
String passiveMagicBonus(int percent) {
if (isKoreanLocale) return '마법 공격 +$percent%';
if (isJapaneseLocale) return '魔法攻撃 +$percent%';
return 'Magic +$percent%';
}
String passiveEvasionBonus(int percent) {
if (isKoreanLocale) return '회피율 +$percent%';
if (isJapaneseLocale) return '回避率 +$percent%';
return 'Evasion +$percent%';
}
String passiveCritBonus(int percent) {
if (isKoreanLocale) return '크리티컬 +$percent%';
if (isJapaneseLocale) return 'クリティカル +$percent%';
return 'Critical +$percent%';
}
String passiveHpRegen(int percent) {
if (isKoreanLocale) return '전투 후 HP $percent% 회복';
if (isJapaneseLocale) return '戦闘後HP $percent%回復';
return 'Recover $percent% HP after combat';
}
String passiveMpRegen(int percent) {
if (isKoreanLocale) return '전투 후 MP $percent% 회복';
if (isJapaneseLocale) return '戦闘後MP $percent%回復';
return 'Recover $percent% MP after combat';
}
// ============================================================================
// 전투 로그 메시지
// ============================================================================
String combatYouHit(String targetName, int damage) {
if (isKoreanLocale) return '$targetName에게 $damage 데미지';
if (isJapaneseLocale) return '$targetNameに$damageダメージ';
return 'You hit $targetName for $damage damage';
}
String combatYouEvaded(String targetName) {
if (isKoreanLocale) return '$targetName의 공격 회피!';
if (isJapaneseLocale) return '$targetNameの攻撃を回避!';
return 'You evaded $targetName\'s attack!';
}
String combatEvadedAttackFrom(String targetName) {
if (isKoreanLocale) return '$targetName의 공격 회피';
if (isJapaneseLocale) return '$targetNameの攻撃を回避';
return 'Evaded attack from $targetName';
}
String combatHealedFor(int amount) {
if (isKoreanLocale) return 'HP $amount 회복';
if (isJapaneseLocale) return 'HP $amount回復';
return 'Healed for $amount HP';
}
String combatCritical(int damage, String targetName) {
if (isKoreanLocale) return '크리티컬! $targetName에게 $damage 데미지!';
if (isJapaneseLocale) return 'クリティカル! $targetNameに$damageダメージ!';
return 'CRITICAL! $damage damage to $targetName!';
}
String combatMonsterHitsYou(String monsterName, int damage) {
if (isKoreanLocale) return '$monsterName이(가) $damage 데미지';
if (isJapaneseLocale) return '$monsterNameが$damageダメージを与えた';
return '$monsterName hits you for $damage damage';
}
String combatMonsterEvaded(String monsterName) {
if (isKoreanLocale) return '$monsterName이(가) 공격 회피!';
if (isJapaneseLocale) return '$monsterNameが攻撃を回避!';
return '$monsterName evaded your attack!';
}
String combatBlocked(int damage) {
if (isKoreanLocale) return '방어! $damage 데미지로 감소';
if (isJapaneseLocale) return 'ブロック! $damageダメージに軽減';
return 'Blocked! Reduced to $damage damage';
}
String combatParried(int damage) {
if (isKoreanLocale) return '패리! $damage 데미지로 감소';
if (isJapaneseLocale) return 'パリィ! $damageダメージに軽減';
return 'Parried! Reduced to $damage damage';
}
// 스킬 관련 전투 메시지
String combatSkillCritical(String skillName, int damage) {
if (isKoreanLocale) return '크리티컬 $skillName! $damage 데미지!';
if (isJapaneseLocale) return 'クリティカル$skillName! $damageダメージ!';
return 'CRITICAL $skillName! $damage damage!';
}
String combatSkillDamage(String skillName, int damage) {
if (isKoreanLocale) return '$skillName: $damage 데미지';
if (isJapaneseLocale) return '$skillName: $damageダメージ';
return '$skillName: $damage damage';
}
String combatSkillHeal(String skillName, int amount) {
if (isKoreanLocale) return '$skillName: +$amount HP';
if (isJapaneseLocale) return '$skillName: +$amount HP';
return '$skillName: +$amount HP';
}
String get uiHeal {
if (isKoreanLocale) return '';
if (isJapaneseLocale) return 'ヒール';
return 'Heal';
}
String combatBuffActivated(String skillName) {
if (isKoreanLocale) return '$skillName 발동!';
if (isJapaneseLocale) return '$skillName 発動!';
return '$skillName activated!';
}
String combatDotTick(String skillName, int damage) {
if (isKoreanLocale) return '$skillName: $damage 지속 데미지';
if (isJapaneseLocale) return '$skillName: $damage 継続ダメージ';
return '$skillName ticks for $damage damage';
}
String combatPotionUsed(String potionName, int amount, String statName) {
if (isKoreanLocale) return '$potionName: +$amount $statName';
if (isJapaneseLocale) return '$potionName: +$amount $statName';
return '$potionName: +$amount $statName';
}
String combatPotionDrop(String potionName) {
if (isKoreanLocale) return '획득: $potionName';
if (isJapaneseLocale) return '獲得: $potionName';
return 'Dropped: $potionName';
}
// 사망 화면 전투 로그 (death overlay)
String combatBlockedAttack(String monsterName, int reducedDamage) {
if (isKoreanLocale) return '$monsterName의 공격 방어 ($reducedDamage 감소)';
if (isJapaneseLocale) return '$monsterNameの攻撃を防御 ($reducedDamage軽減)';
return 'Blocked $monsterName\'s attack ($reducedDamage reduced)';
}
String combatParriedAttack(String monsterName, int reducedDamage) {
if (isKoreanLocale) return '$monsterName의 공격 패리 ($reducedDamage 감소)';
if (isJapaneseLocale) return '$monsterNameの攻撃をパリィ ($reducedDamage軽減)';
return 'Parried $monsterName\'s attack ($reducedDamage reduced)';
}
String get deathSelfInflicted {
if (isKoreanLocale) return '자해 데미지로 사망';
if (isJapaneseLocale) return '自傷ダメージで死亡';
return 'Self-inflicted damage';
}
// ============================================================================
// 퀘스트 캡션
// ============================================================================
@@ -572,7 +928,8 @@ String translateImpressiveTitle(String englishName) {
/// 특수 아이템 이름 번역
String translateSpecial(String englishName) {
if (isKoreanLocale) return specialTranslationsKo[englishName] ?? englishName;
if (isJapaneseLocale) return specialTranslationsJa[englishName] ?? englishName;
if (isJapaneseLocale)
return specialTranslationsJa[englishName] ?? englishName;
return englishName;
}
@@ -627,14 +984,16 @@ String translateBoringItem(String englishName) {
/// 예: "Golden Iterator" → "황금 이터레이터" / "黄金のイテレーター"
String translateInterestingItem(String attrib, String special) {
if (isKoreanLocale) {
final translatedAttrib = itemAttribTranslationsKo[attrib] ??
final translatedAttrib =
itemAttribTranslationsKo[attrib] ??
additionalItemAttribTranslationsKo[attrib] ??
attrib;
final translatedSpecial = specialTranslationsKo[special] ?? special;
return '$translatedAttrib $translatedSpecial';
}
if (isJapaneseLocale) {
final translatedAttrib = itemAttribTranslationsJa[attrib] ??
final translatedAttrib =
itemAttribTranslationsJa[attrib] ??
additionalItemAttribTranslationsJa[attrib] ??
attrib;
final translatedSpecial = specialTranslationsJa[special] ?? special;
@@ -643,48 +1002,419 @@ String translateInterestingItem(String attrib, String special) {
return '$attrib $special';
}
/// 아이템 이름 문자열 전체 번역 (판매, 로그 등에 사용)
/// 예: "Golden Iterator of Compilation" → "컴파일의 황금 이터레이터"
/// 예: "Syntax Error fragment" → "구문 오류 조각"
String translateItemNameL10n(String itemString) {
if (!isKoreanLocale && !isJapaneseLocale) return itemString;
if (itemString.isEmpty) return itemString;
// 1. specialItem 형식: "Attrib Special of ItemOf"
final ofMatch = RegExp(r'^(.+)\s+of\s+(.+)$').firstMatch(itemString);
if (ofMatch != null) {
final beforeOf = ofMatch.group(1)!;
final afterOf = ofMatch.group(2)!;
// afterOf가 itemOfs 목록에 있는지 확인
final itemOfKo =
itemOfsTranslationsKo[afterOf] ??
additionalItemOfsTranslationsKo[afterOf];
final itemOfJa =
itemOfsTranslationsJa[afterOf] ??
additionalItemOfsTranslationsJa[afterOf];
if (itemOfKo != null || itemOfJa != null) {
// beforeOf를 interestingItem으로 분리 (attrib + special)
final beforeWords = beforeOf.split(' ');
if (beforeWords.length >= 2) {
final attrib = beforeWords[0];
final special = beforeWords.sublist(1).join(' ');
final translatedBefore = translateInterestingItem(attrib, special);
if (isKoreanLocale) {
return '$itemOfKo의 $translatedBefore';
} else if (isJapaneseLocale) {
return '$itemOfJaの$translatedBefore';
}
}
}
}
// 2. 몬스터 드롭 형식: "{monster} {drop}" (예: "syntax error fragment")
final words = itemString.split(' ');
if (words.length >= 2) {
// 마지막 단어가 드롭 아이템인지 확인
final lastWord = words.last.toLowerCase();
final dropKo =
dropItemTranslationsKo[lastWord] ??
additionalDropTranslationsKo[lastWord];
final dropJa =
dropItemTranslationsJa[lastWord] ??
additionalDropTranslationsJa[lastWord];
if (dropKo != null || dropJa != null) {
// 앞 부분은 몬스터 이름
final monsterPart = words.sublist(0, words.length - 1).join(' ');
final translatedMonster = translateMonster(monsterPart);
if (isKoreanLocale && dropKo != null) {
return '$translatedMonster $dropKo';
} else if (isJapaneseLocale && dropJa != null) {
return '$translatedMonsterの$dropJa';
}
}
// 3. interestingItem 형식: "Attrib Special" (2단어)
if (words.length == 2) {
return translateInterestingItem(words[0], words[1]);
}
}
// 4. 단일 단어 - boringItem 번역 시도
return translateBoringItem(itemString);
}
// ============================================================================
// 스토리/시네마틱 번역 함수 (Story/Cinematic Translation Functions)
// ============================================================================
/// Act 제목 번역
String translateActTitle(String englishTitle) {
if (isKoreanLocale) return actTitleTranslationsKo[englishTitle] ?? englishTitle;
if (isJapaneseLocale) return actTitleTranslationsJa[englishTitle] ?? englishTitle;
if (isKoreanLocale)
return actTitleTranslationsKo[englishTitle] ?? englishTitle;
if (isJapaneseLocale)
return actTitleTranslationsJa[englishTitle] ?? englishTitle;
return englishTitle;
}
/// Act 보스 이름 번역
String translateActBoss(String englishBoss) {
if (isKoreanLocale) return actBossTranslationsKo[englishBoss] ?? englishBoss;
if (isJapaneseLocale) return actBossTranslationsJa[englishBoss] ?? englishBoss;
if (isJapaneseLocale)
return actBossTranslationsJa[englishBoss] ?? englishBoss;
return englishBoss;
}
/// Act 퀘스트 번역
String translateActQuest(String englishQuest) {
if (isKoreanLocale) return actQuestTranslationsKo[englishQuest] ?? englishQuest;
if (isJapaneseLocale) return actQuestTranslationsJa[englishQuest] ?? englishQuest;
if (isKoreanLocale)
return actQuestTranslationsKo[englishQuest] ?? englishQuest;
if (isJapaneseLocale)
return actQuestTranslationsJa[englishQuest] ?? englishQuest;
return englishQuest;
}
/// 시네마틱 텍스트 번역
String translateCinematic(String englishText) {
if (isKoreanLocale) return cinematicTranslationsKo[englishText] ?? englishText;
if (isJapaneseLocale) return cinematicTranslationsJa[englishText] ?? englishText;
if (isKoreanLocale)
return cinematicTranslationsKo[englishText] ?? englishText;
if (isJapaneseLocale)
return cinematicTranslationsJa[englishText] ?? englishText;
return englishText;
}
/// 지역 이름 번역
String translateLocation(String englishLocation) {
if (isKoreanLocale) return locationTranslationsKo[englishLocation] ?? englishLocation;
if (isJapaneseLocale) return locationTranslationsJa[englishLocation] ?? englishLocation;
if (isKoreanLocale)
return locationTranslationsKo[englishLocation] ?? englishLocation;
if (isJapaneseLocale)
return locationTranslationsJa[englishLocation] ?? englishLocation;
return englishLocation;
}
/// 세력/조직 이름 번역
String translateFaction(String englishFaction) {
if (isKoreanLocale) return factionTranslationsKo[englishFaction] ?? englishFaction;
if (isJapaneseLocale) return factionTranslationsJa[englishFaction] ?? englishFaction;
if (isKoreanLocale)
return factionTranslationsKo[englishFaction] ?? englishFaction;
if (isJapaneseLocale)
return factionTranslationsJa[englishFaction] ?? englishFaction;
return englishFaction;
}
// ============================================================================
// 프론트 화면 텍스트
// ============================================================================
String get uiHallOfFame {
if (isKoreanLocale) return '명예의 전당';
if (isJapaneseLocale) return '栄誉の殿堂';
return 'Hall of Fame';
}
String get frontDescription {
if (isKoreanLocale) return 'Flutter로 재구축된 오프라인 Progress Quest (PQ 6.4)';
if (isJapaneseLocale) return 'Flutterで再構築されたオフラインProgress Quest (PQ 6.4)';
return 'Offline Progress Quest (PQ 6.4) rebuilt with Flutter.';
}
String get frontTodayFocus {
if (isKoreanLocale) return '오늘의 중점';
if (isJapaneseLocale) return '今日のフォーカス';
return "Today's focus";
}
// ============================================================================
// 명예의 전당 화면 텍스트
// ============================================================================
String get hofNoHeroes {
if (isKoreanLocale) return '영웅이 아직 없습니다';
if (isJapaneseLocale) return 'まだ英雄がいません';
return 'No heroes yet';
}
String get hofDefeatGlitchGod {
if (isKoreanLocale) return '글리치 신을 처치하여 전설을 남기세요!';
if (isJapaneseLocale) return 'グリッチゴッドを倒して伝説を刻もう!';
return 'Defeat the Glitch God to enshrine your legend!';
}
String get hofVictory {
if (isKoreanLocale) return '승리!';
if (isJapaneseLocale) return '勝利!';
return 'VICTORY!';
}
String get hofDefeatedGlitchGod {
if (isKoreanLocale) return '글리치 신을 처치했습니다!';
if (isJapaneseLocale) return 'グリッチゴッドを倒しました!';
return 'You have defeated the Glitch God!';
}
String get hofLegendEnshrined {
if (isKoreanLocale) return '당신의 전설이 명예의 전당에 기록되었습니다!';
if (isJapaneseLocale) return 'あなたの伝説が栄誉の殿堂に刻まれました!';
return 'Your legend has been enshrined in the Hall of Fame!';
}
String get hofViewHallOfFame {
if (isKoreanLocale) return '명예의 전당 보기';
if (isJapaneseLocale) return '栄誉の殿堂を見る';
return 'View Hall of Fame';
}
String get hofNewGame {
if (isKoreanLocale) return '새 게임';
if (isJapaneseLocale) return '新しいゲーム';
return 'New Game';
}
String get hofLevel {
if (isKoreanLocale) return '레벨';
if (isJapaneseLocale) return 'レベル';
return 'Level';
}
String get hofTime {
if (isKoreanLocale) return '시간';
if (isJapaneseLocale) return '時間';
return 'Time';
}
String get hofDeaths {
if (isKoreanLocale) return '사망';
if (isJapaneseLocale) return '死亡';
return 'Deaths';
}
String get hofQuests {
if (isKoreanLocale) return '퀘스트';
if (isJapaneseLocale) return 'クエスト';
return 'Quests';
}
String uiLevel(int level) {
if (isKoreanLocale) return 'Lv.$level';
if (isJapaneseLocale) return 'Lv.$level';
return 'Lv.$level';
}
// ============================================================================
// 시네마틱 뷰 텍스트
// ============================================================================
String get uiSkip {
if (isKoreanLocale) return '건너뛰기';
if (isJapaneseLocale) return 'スキップ';
return 'SKIP';
}
// ============================================================================
// 게임 플레이 화면 텍스트
// ============================================================================
String get uiLevelUp {
if (isKoreanLocale) return '레벨 업!';
if (isJapaneseLocale) return 'レベルアップ!';
return 'Level Up!';
}
String uiQuestComplete(String questName) {
if (isKoreanLocale) return '퀘스트 완료: $questName';
if (isJapaneseLocale) return 'クエスト完了: $questName';
return 'Quest Complete: $questName';
}
// ============================================================================
// 장비 패널 텍스트
// ============================================================================
String get uiEquipmentScore {
if (isKoreanLocale) return '장비 점수';
if (isJapaneseLocale) return '装備スコア';
return 'Equipment Score';
}
String get uiEmpty {
if (isKoreanLocale) return '(비어있음)';
if (isJapaneseLocale) return '(空)';
return '(empty)';
}
String uiWeight(int weight) {
if (isKoreanLocale) return '무게 $weight';
if (isJapaneseLocale) return '重量 $weight';
return 'Wt.$weight';
}
// 장비 슬롯 이름
String get slotWeapon {
if (isKoreanLocale) return '무기';
if (isJapaneseLocale) return '武器';
return 'Weapon';
}
String get slotShield {
if (isKoreanLocale) return '방패';
if (isJapaneseLocale) return '';
return 'Shield';
}
String get slotHelm {
if (isKoreanLocale) return '투구';
if (isJapaneseLocale) return '';
return 'Helm';
}
String get slotHauberk {
if (isKoreanLocale) return '갑옷';
if (isJapaneseLocale) return '';
return 'Hauberk';
}
String get slotBrassairts {
if (isKoreanLocale) return '상완갑';
if (isJapaneseLocale) return '上腕甲';
return 'Brassairts';
}
String get slotVambraces {
if (isKoreanLocale) return '전완갑';
if (isJapaneseLocale) return '前腕甲';
return 'Vambraces';
}
String get slotGauntlets {
if (isKoreanLocale) return '건틀릿';
if (isJapaneseLocale) return 'ガントレット';
return 'Gauntlets';
}
String get slotGambeson {
if (isKoreanLocale) return '패딩';
if (isJapaneseLocale) return 'パッデッドアーマー';
return 'Gambeson';
}
String get slotCuisses {
if (isKoreanLocale) return '허벅지갑';
if (isJapaneseLocale) return '腿当て';
return 'Cuisses';
}
String get slotGreaves {
if (isKoreanLocale) return '정강이갑';
if (isJapaneseLocale) return '脛当て';
return 'Greaves';
}
String get slotSollerets {
if (isKoreanLocale) return '철제부츠';
if (isJapaneseLocale) return '鉄靴';
return 'Sollerets';
}
// 스탯 약어 (장비용)
String get statAtk {
if (isKoreanLocale) return '공격';
if (isJapaneseLocale) return '攻撃';
return 'ATK';
}
String get statMAtk {
if (isKoreanLocale) return '마공';
if (isJapaneseLocale) return '魔攻';
return 'MATK';
}
String get statCri {
if (isKoreanLocale) return '치명';
if (isJapaneseLocale) return 'クリ';
return 'CRI';
}
String get statParry {
if (isKoreanLocale) return '패리';
if (isJapaneseLocale) return 'パリィ';
return 'PARRY';
}
String get statDef {
if (isKoreanLocale) return '방어';
if (isJapaneseLocale) return '防御';
return 'DEF';
}
String get statMDef {
if (isKoreanLocale) return '마방';
if (isJapaneseLocale) return '魔防';
return 'MDEF';
}
String get statBlock {
if (isKoreanLocale) return '블록';
if (isJapaneseLocale) return 'ブロック';
return 'BLOCK';
}
String get statEva {
if (isKoreanLocale) return '회피';
if (isJapaneseLocale) return '回避';
return 'EVA';
}
String get statHp {
if (isKoreanLocale) return 'HP';
if (isJapaneseLocale) return 'HP';
return 'HP';
}
String get statMp {
if (isKoreanLocale) return 'MP';
if (isJapaneseLocale) return 'MP';
return 'MP';
}
String get statSpeed {
if (isKoreanLocale) return '속도';
if (isJapaneseLocale) return '速度';
return 'SPEED';
}
// ============================================================================
// 스킬 패널 텍스트
// ============================================================================
String get uiDot {
if (isKoreanLocale) return '지속';
if (isJapaneseLocale) return 'DOT';
return 'DOT';
}