Files
asciinevrdie/lib/data/game_text_l10n.dart
JiWoong Sul 99f5b74802 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: 클래스 데이터 정리
2025-12-22 19:00:58 +09:00

1421 lines
46 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 게임 텍스트 로컬라이제이션 (BuildContext 없이 사용)
// progress_service.dart, pq_logic.dart 등에서 사용
// 지원 언어: 한국어(ko), 영어(en), 일본어(ja)
import 'package:askiineverdie/data/game_translations_ko.dart';
import 'package:askiineverdie/data/game_translations_ja.dart';
/// 현재 게임 로케일 설정 (전역)
String _currentLocale = 'en';
/// 현재 로케일 가져오기
String get currentGameLocale => _currentLocale;
/// 로케일 설정 (앱 시작 시 호출)
void setGameLocale(String locale) {
_currentLocale = locale;
}
/// 한국어 여부 확인
bool get isKoreanLocale => _currentLocale == 'ko';
/// 일본어 여부 확인
bool get isJapaneseLocale => _currentLocale == 'ja';
// ============================================================================
// 프롤로그 텍스트
// ============================================================================
const _prologueTextsEn = [
'Receiving an ominous vision from the Code God',
'The old Compiler Sage reveals a prophecy: "The Glitch God has awakened"',
'A sudden Buffer Overflow resets your village, leaving you as the sole survivor',
'With unexpected resolve, you embark on a perilous journey to the Null Kingdom',
];
const _prologueTextsKo = [
'코드의 신으로부터 불길한 환영을 받다',
'늙은 컴파일러 현자가 예언을 밝히다: "글리치 신이 깨어났다"',
'갑작스러운 버퍼 오버플로우가 마을을 초기화하고, 당신만이 유일한 생존자로 남다',
'예상치 못한 결의로 널(Null) 왕국을 향한 위험한 여정을 시작하다',
];
const _prologueTextsJa = [
'コードの神から不吉な幻影を受ける',
'老いたコンパイラー賢者が予言を明かす:「グリッチゴッドが目覚めた」',
'突然のバッファオーバーフローが村をリセットし、あなただけが唯一の生存者となる',
'予想外の決意で、ヌル(Null)王国への危険な旅に出発する',
];
List<String> get prologueTexts {
if (isKoreanLocale) return _prologueTextsKo;
if (isJapaneseLocale) return _prologueTextsJa;
return _prologueTextsEn;
}
// ============================================================================
// 태스크 캡션
// ============================================================================
String get taskCompiling {
if (isKoreanLocale) return '컴파일 중';
if (isJapaneseLocale) return 'コンパイル中';
return 'Compiling';
}
String get taskPrologue {
if (isKoreanLocale) return '프롤로그';
if (isJapaneseLocale) return 'プロローグ';
return 'Prologue';
}
String taskHeadingToMarket() {
if (isKoreanLocale) return '전리품을 팔기 위해 데이터 마켓으로 이동 중';
if (isJapaneseLocale) return '戦利品を売るためデータマーケットへ移動中';
return 'Heading to the Data Market to trade loot';
}
String taskUpgradingHardware() {
if (isKoreanLocale) return '테크 샵에서 하드웨어 업그레이드 중';
if (isJapaneseLocale) return 'テックショップでハードウェアをアップグレード中';
return 'Upgrading hardware at the Tech Shop';
}
String taskEnteringDebugZone() {
if (isKoreanLocale) return '디버그 존 진입 중';
if (isJapaneseLocale) return 'デバッグゾーンに進入中';
return 'Entering the Debug Zone';
}
String taskDebugging(String monsterName) {
if (isKoreanLocale) return '$monsterName 디버깅 중';
if (isJapaneseLocale) return '$monsterName をデバッグ中';
return 'Debugging $monsterName';
}
String taskSelling(String itemDescription) {
if (isKoreanLocale) return '$itemDescription 판매 중';
if (isJapaneseLocale) return '$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';
}
// ============================================================================
// 퀘스트 캡션
// ============================================================================
String questPatch(String name) {
if (isKoreanLocale) return '$name 패치하기';
if (isJapaneseLocale) return '$name をパッチする';
return 'Patch $name';
}
String questLocate(String item) {
if (isKoreanLocale) return '$item 찾기';
if (isJapaneseLocale) return '$item を探す';
return 'Locate $item';
}
String questTransfer(String item) {
if (isKoreanLocale) return '$item 전송하기';
if (isJapaneseLocale) return 'この$item を転送する';
return 'Transfer this $item';
}
String questDownload(String item) {
if (isKoreanLocale) return '$item 다운로드하기';
if (isJapaneseLocale) return '$item をダウンロードする';
return 'Download $item';
}
String questStabilize(String name) {
if (isKoreanLocale) return '$name 안정화하기';
if (isJapaneseLocale) return '$name を安定化する';
return 'Stabilize $name';
}
// ============================================================================
// Act 제목
// ============================================================================
String actTitle(String romanNumeral) {
if (isKoreanLocale) return '$romanNumeral막';
if (isJapaneseLocale) return '$romanNumeral幕';
return 'Act $romanNumeral';
}
// ============================================================================
// 시네마틱 텍스트 - 시나리오 1: 캐시 존
// ============================================================================
String cinematicCacheZone1() {
if (isKoreanLocale) return '지쳐서 손상된 네트워크의 안전한 캐시 존에 도착하다';
if (isJapaneseLocale) return '疲れ果てて、破損したネットワークの安全なキャッシュゾーンに到着する';
return 'Exhausted, you reach a safe Cache Zone in the corrupted network';
}
String cinematicCacheZone2() {
if (isKoreanLocale) return '옛 동맹들과 재연결하고 새로운 동료들을 포크하다';
if (isJapaneseLocale) return '古い同盟者と再接続し、新しい仲間をフォークする';
return 'You reconnect with old allies and fork new ones';
}
String cinematicCacheZone3() {
if (isKoreanLocale) return '디버거 기사단 회의에 참석하다';
if (isJapaneseLocale) return 'デバッガー騎士団の会議に参加する';
return 'You attend a council of the Debugger Knights';
}
String cinematicCacheZone4() {
if (isKoreanLocale) return '많은 버그들이 기다린다. 당신이 패치하도록 선택되었다!';
if (isJapaneseLocale) return '多くのバグが待っている。あなたがパッチを当てるよう選ばれた!';
return 'Many bugs await. You are chosen to patch them!';
}
// ============================================================================
// 시네마틱 텍스트 - 시나리오 2: 전투
// ============================================================================
String cinematicCombat1() {
if (isKoreanLocale) return '목표가 눈앞에 있지만, 치명적인 버그가 길을 막는다!';
if (isJapaneseLocale) return 'ターゲットは目の前だが、致命的なバグが道を塞ぐ!';
return 'Your target is in sight, but a critical bug blocks your path!';
}
String cinematicCombat2(String nemesis) {
if (isKoreanLocale) return '$nemesis와의 필사적인 디버깅 세션이 시작되다';
if (isJapaneseLocale) return '$nemesisとの必死のデバッグセッションが始まる';
return 'A desperate debugging session begins with $nemesis';
}
String cinematicCombatLocked(String nemesis) {
if (isKoreanLocale) return '$nemesis와 치열한 디버깅 중';
if (isJapaneseLocale) return '$nemesisと激しいデバッグ中';
return 'Locked in intense debugging with $nemesis';
}
String cinematicCombatCorrupts(String nemesis) {
if (isKoreanLocale) return '$nemesis가 당신의 스택 트레이스를 손상시키다';
if (isJapaneseLocale) return '$nemesisがあなたのスタックトレースを破損させる';
return '$nemesis corrupts your stack trace';
}
String cinematicCombatWorking(String nemesis) {
if (isKoreanLocale) return '당신의 패치가 $nemesis에게 효과를 보이는 것 같다';
if (isJapaneseLocale) return 'あなたのパッチが$nemesisに効いているようだ';
return 'Your patch seems to be working against $nemesis';
}
String cinematicCombatVictory(String nemesis) {
if (isKoreanLocale) return '승리! $nemesis가 패치되었다! 복구를 위해 시스템이 재부팅된다';
if (isJapaneseLocale) return '勝利!$nemesisはパッチされた!復旧のためシステムが再起動する';
return 'Victory! $nemesis is patched! System reboots for recovery';
}
String cinematicCombatWakeUp() {
if (isKoreanLocale) return '안전 모드에서 깨어나지만, 커널이 기다린다';
if (isJapaneseLocale) return 'セーフモードで目覚めるが、カーネルが待ち構えている';
return 'You wake up in a Safe Mode, but the kernel awaits';
}
// ============================================================================
// 시네마틱 텍스트 - 시나리오 3: 배신
// ============================================================================
String cinematicBetrayal1(String guy) {
if (isKoreanLocale) return '안도감! $guy의 보안 서버에 도착하다';
if (isJapaneseLocale) return '安堵!$guyのセキュアサーバーに到着する';
return 'What relief! You reach the secure server of $guy';
}
String cinematicBetrayal2(String guy) {
if (isKoreanLocale) return '축하가 이어지고, $guy와 수상한 비밀 핸드셰이크를 나누다';
if (isJapaneseLocale) return '祝賀が続き、$guyと怪しい秘密のハンドシェイクを交わす';
return 'There is celebration, and a suspicious private handshake with $guy';
}
String cinematicBetrayal3(String item) {
if (isKoreanLocale) return '$item을 잊고 다시 가져오러 돌아가다';
if (isJapaneseLocale) return '$itemを忘れて取りに戻る';
return 'You forget your $item and go back to retrieve it';
}
String cinematicBetrayal4() {
if (isKoreanLocale) return '이게 뭐지!? 손상된 패킷을 가로채다!';
if (isJapaneseLocale) return 'これは何だ!?破損したパケットを傍受する!';
return 'What is this!? You intercept a corrupted packet!';
}
String cinematicBetrayal5(String guy) {
if (isKoreanLocale) return '$guy가 글리치 신의 백도어일 수 있을까?';
if (isJapaneseLocale) return '$guyはグリッチゴッドのバックドアなのか';
return 'Could $guy be a backdoor for the Glitch God?';
}
String cinematicBetrayal6() {
if (isKoreanLocale) return '이 정보를 누구에게 맡길 수 있을까!? -- 바이너리 신전이다';
if (isJapaneseLocale) return 'この情報を誰に託せるか!? -- バイナリ神殿だ';
return 'Who can be trusted with this intel!? -- The Binary Temple, of course';
}
// ============================================================================
// 몬스터 수식어
// ============================================================================
String modifierDead(String s) {
if (isKoreanLocale) return '쓰러진 $s';
if (isJapaneseLocale) return '倒れた$s';
return 'fallen $s';
}
String modifierComatose(String s) {
if (isKoreanLocale) return '잠복하는 $s';
if (isJapaneseLocale) return '潜む$s';
return 'lurking $s';
}
String modifierCrippled(String s) {
if (isKoreanLocale) return '흉측한 $s';
if (isJapaneseLocale) return '歪んだ$s';
return 'twisted $s';
}
String modifierSick(String s) {
if (isKoreanLocale) return '오염된 $s';
if (isJapaneseLocale) return '汚染された$s';
return 'tainted $s';
}
String modifierUndernourished(String s) {
if (isKoreanLocale) return '굶주린 $s';
if (isJapaneseLocale) return '飢えた$s';
return 'ravenous $s';
}
String modifierFoetal(String s) {
if (isKoreanLocale) return '태동기 $s';
if (isJapaneseLocale) return '胎動期$s';
return 'nascent $s';
}
String modifierBaby(String s) {
if (isKoreanLocale) return '초기형 $s';
if (isJapaneseLocale) return '初期型$s';
return 'fledgling $s';
}
String modifierPreadolescent(String s) {
if (isKoreanLocale) return '진화 중인 $s';
if (isJapaneseLocale) return '進化中の$s';
return 'evolving $s';
}
String modifierTeenage(String s) {
if (isKoreanLocale) return '하급 $s';
if (isJapaneseLocale) return '下級$s';
return 'lesser $s';
}
String modifierUnderage(String s) {
if (isKoreanLocale) return '불완전한 $s';
if (isJapaneseLocale) return '不完全な$s';
return 'incomplete $s';
}
String modifierGreater(String s) {
if (isKoreanLocale) return '상위 $s';
if (isJapaneseLocale) return '上位$s';
return 'greater $s';
}
String modifierMassive(String s) {
if (isKoreanLocale) return '거대한 $s';
if (isJapaneseLocale) return '巨大な$s';
return 'massive $s';
}
String modifierEnormous(String s) {
if (isKoreanLocale) return '초거대 $s';
if (isJapaneseLocale) return '超巨大$s';
return 'enormous $s';
}
String modifierGiant(String s) {
if (isKoreanLocale) return '자이언트 $s';
if (isJapaneseLocale) return 'ジャイアント$s';
return 'giant $s';
}
String modifierTitanic(String s) {
if (isKoreanLocale) return '타이타닉 $s';
if (isJapaneseLocale) return 'タイタニック$s';
return 'titanic $s';
}
String modifierVeteran(String s) {
if (isKoreanLocale) return '베테랑 $s';
if (isJapaneseLocale) return 'ベテラン$s';
return 'veteran $s';
}
String modifierBattle(String s) {
if (isKoreanLocale) return '전투-$s';
if (isJapaneseLocale) return '戦闘-$s';
return 'Battle-$s';
}
String modifierCursed(String s) {
if (isKoreanLocale) return '저주받은 $s';
if (isJapaneseLocale) return '呪われた$s';
return 'cursed $s';
}
String modifierWarrior(String s) {
if (isKoreanLocale) return '전사 $s';
if (isJapaneseLocale) return '戦士$s';
return 'warrior $s';
}
String modifierWere(String s) {
if (isKoreanLocale) return '늑대인간-$s';
if (isJapaneseLocale) return '狼男-$s';
return 'Were-$s';
}
String modifierUndead(String s) {
if (isKoreanLocale) return '언데드 $s';
if (isJapaneseLocale) return 'アンデッド$s';
return 'undead $s';
}
String modifierDemon(String s) {
if (isKoreanLocale) return '데몬 $s';
if (isJapaneseLocale) return 'デーモン$s';
return 'demon $s';
}
String modifierMessianic(String s) {
if (isKoreanLocale) return '메시아닉 $s';
if (isJapaneseLocale) return 'メシアニック$s';
return 'messianic $s';
}
String modifierImaginary(String s) {
if (isKoreanLocale) return '상상의 $s';
if (isJapaneseLocale) return '想像上の$s';
return 'imaginary $s';
}
String modifierPassing(String s) {
if (isKoreanLocale) return '지나가는 $s';
if (isJapaneseLocale) return '通りすがりの$s';
return 'passing $s';
}
// ============================================================================
// 시간 표시
// ============================================================================
String roughTimeSeconds(int seconds) {
if (isKoreanLocale) return '$seconds초';
if (isJapaneseLocale) return '$seconds秒';
return '$seconds seconds';
}
String roughTimeMinutes(int minutes) {
if (isKoreanLocale) return '$minutes분';
if (isJapaneseLocale) return '$minutes分';
return '$minutes minutes';
}
String roughTimeHours(int hours) {
if (isKoreanLocale) return '$hours시간';
if (isJapaneseLocale) return '$hours時間';
return '$hours hours';
}
String roughTimeDays(int days) {
if (isKoreanLocale) return '$days일';
if (isJapaneseLocale) return '$days日';
return '$days days';
}
// ============================================================================
// 영어 문법 함수 (한국어/일본어에서는 단순화)
// ============================================================================
/// 관사 + 명사 (한국어/일본어: 수량만 표시)
String indefiniteL10n(String s, int qty) {
if (isKoreanLocale) {
return qty == 1 ? s : '$qty $s';
}
if (isJapaneseLocale) {
return qty == 1 ? s : '$qty $s';
}
// 영어 로직
if (qty == 1) {
const vowels = 'AEIOUÜaeiouü';
final first = s.isNotEmpty ? s[0] : 'a';
final article = vowels.contains(first) ? 'an' : 'a';
return '$article $s';
}
return '$qty ${_pluralize(s)}';
}
/// the + 명사 (한국어/일본어: 그냥 명사)
String definiteL10n(String s, int qty) {
if (isKoreanLocale || isJapaneseLocale) {
return s;
}
// 영어 로직
if (qty > 1) {
s = _pluralize(s);
}
return 'the $s';
}
/// 복수형 (영어만 해당)
String _pluralize(String s) {
if (s.endsWith('y')) return '${s.substring(0, s.length - 1)}ies';
if (s.endsWith('us')) return '${s.substring(0, s.length - 2)}i';
if (s.endsWith('ch') || s.endsWith('x') || s.endsWith('s')) return '${s}es';
if (s.endsWith('f')) return '${s.substring(0, s.length - 1)}ves';
if (s.endsWith('man') || s.endsWith('Man')) {
return '${s.substring(0, s.length - 2)}en';
}
return '${s}s'; // ignore: unnecessary_brace_in_string_interp
}
// ============================================================================
// impressiveGuy 관련
// ============================================================================
String impressiveGuyPattern1(String title, String race) {
if (isKoreanLocale) {
// ignore: unnecessary_brace_in_string_interps
return '${race}들의 $title'; // 한국어 조사 연결을 위해 중괄호 필요
}
if (isJapaneseLocale) {
// ignore: unnecessary_brace_in_string_interps
return '${race}たちの$title'; // 일본어 연결을 위해 중괄호 필요
}
return 'the $title of the ${_pluralize(race)}';
}
String impressiveGuyPattern2(String title, String name1, String name2) {
if (isKoreanLocale) return '$name2의 $title $name1';
if (isJapaneseLocale) return '$name2の$title $name1';
return '$title $name1 of $name2';
}
// ============================================================================
// namedMonster 관련
// ============================================================================
String namedMonsterFormat(String generatedName, String monsterType) {
if (isKoreanLocale) return '$monsterType $generatedName';
if (isJapaneseLocale) return '$monsterType $generatedName';
return '$generatedName the $monsterType';
}
// ============================================================================
// 게임 데이터 번역 함수 (BuildContext 없이 사용)
// 지원 언어: 한국어(ko), 영어(en), 일본어(ja)
// ============================================================================
/// 몬스터 이름 번역 (기본 + 고급 몬스터 포함)
String translateMonster(String englishName) {
if (isKoreanLocale) {
return monsterTranslationsKo[englishName] ??
advancedMonsterTranslationsKo[englishName] ??
englishName;
}
if (isJapaneseLocale) {
return monsterTranslationsJa[englishName] ??
advancedMonsterTranslationsJa[englishName] ??
englishName;
}
return englishName;
}
/// 종족 이름 번역
String translateRace(String englishName) {
if (isKoreanLocale) return raceTranslationsKo[englishName] ?? englishName;
if (isJapaneseLocale) return raceTranslationsJa[englishName] ?? englishName;
return englishName;
}
/// 직업 이름 번역
String translateKlass(String englishName) {
if (isKoreanLocale) return klassTranslationsKo[englishName] ?? englishName;
if (isJapaneseLocale) return klassTranslationsJa[englishName] ?? englishName;
return englishName;
}
/// 칭호 이름 번역
String translateTitle(String englishName) {
if (isKoreanLocale) return titleTranslationsKo[englishName] ?? englishName;
if (isJapaneseLocale) return titleTranslationsJa[englishName] ?? englishName;
return englishName;
}
/// 인상적인 칭호 번역 (impressiveTitles용)
String translateImpressiveTitle(String englishName) {
if (isKoreanLocale) {
return impressiveTitleTranslationsKo[englishName] ?? englishName;
}
if (isJapaneseLocale) {
return impressiveTitleTranslationsJa[englishName] ?? englishName;
}
return englishName;
}
/// 특수 아이템 이름 번역
String translateSpecial(String englishName) {
if (isKoreanLocale) return specialTranslationsKo[englishName] ?? englishName;
if (isJapaneseLocale)
return specialTranslationsJa[englishName] ?? englishName;
return englishName;
}
/// 아이템 속성 이름 번역 (기본 + 추가 속성 포함)
String translateItemAttrib(String englishName) {
if (isKoreanLocale) {
return itemAttribTranslationsKo[englishName] ??
additionalItemAttribTranslationsKo[englishName] ??
englishName;
}
if (isJapaneseLocale) {
return itemAttribTranslationsJa[englishName] ??
additionalItemAttribTranslationsJa[englishName] ??
englishName;
}
return englishName;
}
/// 아이템 "~의" 접미사 번역 (기본 + 추가 포함)
String translateItemOf(String englishName) {
if (isKoreanLocale) {
return itemOfsTranslationsKo[englishName] ??
additionalItemOfsTranslationsKo[englishName] ??
englishName;
}
if (isJapaneseLocale) {
return itemOfsTranslationsJa[englishName] ??
additionalItemOfsTranslationsJa[englishName] ??
englishName;
}
return englishName;
}
/// 단순 아이템 번역 (기본 + 추가 드롭 포함)
String translateBoringItem(String englishName) {
if (isKoreanLocale) {
return boringItemTranslationsKo[englishName] ??
dropItemTranslationsKo[englishName] ??
additionalDropTranslationsKo[englishName] ??
englishName;
}
if (isJapaneseLocale) {
return boringItemTranslationsJa[englishName] ??
dropItemTranslationsJa[englishName] ??
additionalDropTranslationsJa[englishName] ??
englishName;
}
return englishName;
}
/// interestingItem 번역 (attrib + special 조합)
/// 예: "Golden Iterator" → "황금 이터레이터" / "黄金のイテレーター"
String translateInterestingItem(String attrib, String special) {
if (isKoreanLocale) {
final translatedAttrib =
itemAttribTranslationsKo[attrib] ??
additionalItemAttribTranslationsKo[attrib] ??
attrib;
final translatedSpecial = specialTranslationsKo[special] ?? special;
return '$translatedAttrib $translatedSpecial';
}
if (isJapaneseLocale) {
final translatedAttrib =
itemAttribTranslationsJa[attrib] ??
additionalItemAttribTranslationsJa[attrib] ??
attrib;
final translatedSpecial = specialTranslationsJa[special] ?? special;
return '$translatedAttrib$translatedSpecial';
}
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;
return englishTitle;
}
/// Act 보스 이름 번역
String translateActBoss(String englishBoss) {
if (isKoreanLocale) return actBossTranslationsKo[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;
return englishQuest;
}
/// 시네마틱 텍스트 번역
String translateCinematic(String 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;
return englishLocation;
}
/// 세력/조직 이름 번역
String translateFaction(String 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';
}