Files
asciinevrdie/lib/data/game_text_l10n.dart
JiWoong Sul 3fdca904a2 refactor(l10n): 동정 유발 표현을 위협적 표현으로 변경
- 몬스터 수식어 수정 (영어/한국어 모두)
  - dead→fallen, crippled→twisted, sick→tainted
  - undernourished→ravenous, baby→fledgling 등
- 고아/기아 관련 표현 개선
  - orphan→이탈, starvation→고갈, hungry→탐욕스러운
  - parentless→떠도는, Exploited→침해당한
- 일시정지 시 ASCII 애니메이션도 함께 정지하도록 수정
2025-12-15 19:24:32 +09:00

336 lines
14 KiB
Dart

// 게임 텍스트 로컬라이제이션 (BuildContext 없이 사용)
// progress_service.dart, pq_logic.dart 등에서 사용
import 'package:askiineverdie/data/game_translations_ko.dart';
/// 현재 게임 로케일 설정 (전역)
String _currentLocale = 'en';
/// 현재 로케일 가져오기
String get currentGameLocale => _currentLocale;
/// 로케일 설정 (앱 시작 시 호출)
void setGameLocale(String locale) {
_currentLocale = locale;
}
/// 한국어 여부 확인
bool get isKoreanLocale => _currentLocale == 'ko';
// ============================================================================
// 프롤로그 텍스트
// ============================================================================
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) 왕국을 향한 위험한 여정을 시작하다',
];
List<String> get prologueTexts =>
isKoreanLocale ? _prologueTextsKo : _prologueTextsEn;
// ============================================================================
// 태스크 캡션
// ============================================================================
String get taskCompiling => isKoreanLocale ? '컴파일 중' : 'Compiling';
String get taskPrologue => isKoreanLocale ? '프롤로그' : 'Prologue';
String taskHeadingToMarket() =>
isKoreanLocale ? '전리품을 팔기 위해 데이터 마켓으로 이동 중' : 'Heading to the Data Market to trade loot';
String taskUpgradingHardware() =>
isKoreanLocale ? '테크 샵에서 하드웨어 업그레이드 중' : 'Upgrading hardware at the Tech Shop';
String taskEnteringDebugZone() =>
isKoreanLocale ? '디버그 존 진입 중' : 'Entering the Debug Zone';
String taskDebugging(String monsterName) =>
isKoreanLocale ? '$monsterName 디버깅 중' : 'Debugging $monsterName';
String taskSelling(String itemDescription) =>
isKoreanLocale ? '$itemDescription 판매 중' : 'Selling $itemDescription';
// ============================================================================
// 퀘스트 캡션
// ============================================================================
String questPatch(String name) =>
isKoreanLocale ? '$name 패치하기' : 'Patch $name';
String questLocate(String item) =>
isKoreanLocale ? '$item 찾기' : 'Locate $item';
String questTransfer(String item) =>
isKoreanLocale ? '$item 전송하기' : 'Transfer this $item';
String questDownload(String item) =>
isKoreanLocale ? '$item 다운로드하기' : 'Download $item';
String questStabilize(String name) =>
isKoreanLocale ? '$name 안정화하기' : 'Stabilize $name';
// ============================================================================
// Act 제목
// ============================================================================
String actTitle(String romanNumeral) =>
isKoreanLocale ? '$romanNumeral막' : 'Act $romanNumeral';
// ============================================================================
// 시네마틱 텍스트 - 시나리오 1: 캐시 존
// ============================================================================
String cinematicCacheZone1() => isKoreanLocale
? '지쳐서 손상된 네트워크의 안전한 캐시 존에 도착하다'
: 'Exhausted, you reach a safe Cache Zone in the corrupted network';
String cinematicCacheZone2() => isKoreanLocale
? '옛 동맹들과 재연결하고 새로운 동료들을 포크하다'
: 'You reconnect with old allies and fork new ones';
String cinematicCacheZone3() => isKoreanLocale
? '디버거 기사단 회의에 참석하다'
: 'You attend a council of the Debugger Knights';
String cinematicCacheZone4() => isKoreanLocale
? '많은 버그들이 기다린다. 당신이 패치하도록 선택되었다!'
: 'Many bugs await. You are chosen to patch them!';
// ============================================================================
// 시네마틱 텍스트 - 시나리오 2: 전투
// ============================================================================
String cinematicCombat1() => isKoreanLocale
? '목표가 눈앞에 있지만, 치명적인 버그가 길을 막는다!'
: 'Your target is in sight, but a critical bug blocks your path!';
String cinematicCombat2(String nemesis) => isKoreanLocale
? '$nemesis와의 필사적인 디버깅 세션이 시작되다'
: 'A desperate debugging session begins with $nemesis';
String cinematicCombatLocked(String nemesis) => isKoreanLocale
? '$nemesis와 치열한 디버깅 중'
: 'Locked in intense debugging with $nemesis';
String cinematicCombatCorrupts(String nemesis) => isKoreanLocale
? '$nemesis가 당신의 스택 트레이스를 손상시키다'
: '$nemesis corrupts your stack trace';
String cinematicCombatWorking(String nemesis) => isKoreanLocale
? '당신의 패치가 $nemesis에게 효과를 보이는 것 같다'
: 'Your patch seems to be working against $nemesis';
String cinematicCombatVictory(String nemesis) => isKoreanLocale
? '승리! $nemesis가 패치되었다! 복구를 위해 시스템이 재부팅된다'
: 'Victory! $nemesis is patched! System reboots for recovery';
String cinematicCombatWakeUp() => isKoreanLocale
? '안전 모드에서 깨어나지만, 커널이 기다린다'
: 'You wake up in a Safe Mode, but the kernel awaits';
// ============================================================================
// 시네마틱 텍스트 - 시나리오 3: 배신
// ============================================================================
String cinematicBetrayal1(String guy) => isKoreanLocale
? '안도감! $guy의 보안 서버에 도착하다'
: 'What relief! You reach the secure server of $guy';
String cinematicBetrayal2(String guy) => isKoreanLocale
? '축하가 이어지고, $guy와 수상한 비밀 핸드셰이크를 나누다'
: 'There is celebration, and a suspicious private handshake with $guy';
String cinematicBetrayal3(String item) => isKoreanLocale
? '$item을 잊고 다시 가져오러 돌아가다'
: 'You forget your $item and go back to retrieve it';
String cinematicBetrayal4() => isKoreanLocale
? '이게 뭐지!? 손상된 패킷을 가로채다!'
: 'What is this!? You intercept a corrupted packet!';
String cinematicBetrayal5(String guy) => isKoreanLocale
? '$guy가 글리치 신의 백도어일 수 있을까?'
: 'Could $guy be a backdoor for the Glitch God?';
String cinematicBetrayal6() => isKoreanLocale
? '이 정보를 누구에게 맡길 수 있을까!? -- 바이너리 신전이다'
: 'Who can be trusted with this intel!? -- The Binary Temple, of course';
// ============================================================================
// 몬스터 수식어
// ============================================================================
String modifierDead(String s) => isKoreanLocale ? '쓰러진 $s' : 'fallen $s';
String modifierComatose(String s) => isKoreanLocale ? '잠복하는 $s' : 'lurking $s';
String modifierCrippled(String s) => isKoreanLocale ? '흉측한 $s' : 'twisted $s';
String modifierSick(String s) => isKoreanLocale ? '오염된 $s' : 'tainted $s';
String modifierUndernourished(String s) =>
isKoreanLocale ? '굶주린 $s' : 'ravenous $s';
String modifierFoetal(String s) => isKoreanLocale ? '태동기 $s' : 'nascent $s';
String modifierBaby(String s) => isKoreanLocale ? '초기형 $s' : 'fledgling $s';
String modifierPreadolescent(String s) =>
isKoreanLocale ? '진화 중인 $s' : 'evolving $s';
String modifierTeenage(String s) => isKoreanLocale ? '하급 $s' : 'lesser $s';
String modifierUnderage(String s) => isKoreanLocale ? '불완전한 $s' : 'incomplete $s';
String modifierGreater(String s) => isKoreanLocale ? '상위 $s' : 'greater $s';
String modifierMassive(String s) => isKoreanLocale ? '거대한 $s' : 'massive $s';
String modifierEnormous(String s) => isKoreanLocale ? '초거대 $s' : 'enormous $s';
String modifierGiant(String s) => isKoreanLocale ? '자이언트 $s' : 'giant $s';
String modifierTitanic(String s) => isKoreanLocale ? '타이타닉 $s' : 'titanic $s';
String modifierVeteran(String s) => isKoreanLocale ? '베테랑 $s' : 'veteran $s';
String modifierBattle(String s) => isKoreanLocale ? '전투-$s' : 'Battle-$s';
String modifierCursed(String s) => isKoreanLocale ? '저주받은 $s' : 'cursed $s';
String modifierWarrior(String s) => isKoreanLocale ? '전사 $s' : 'warrior $s';
String modifierWere(String s) => isKoreanLocale ? '늑대인간-$s' : 'Were-$s';
String modifierUndead(String s) => isKoreanLocale ? '언데드 $s' : 'undead $s';
String modifierDemon(String s) => isKoreanLocale ? '데몬 $s' : 'demon $s';
String modifierMessianic(String s) => isKoreanLocale ? '메시아닉 $s' : 'messianic $s';
String modifierImaginary(String s) => isKoreanLocale ? '상상의 $s' : 'imaginary $s';
String modifierPassing(String s) => isKoreanLocale ? '지나가는 $s' : 'passing $s';
// ============================================================================
// 시간 표시
// ============================================================================
String roughTimeSeconds(int seconds) =>
isKoreanLocale ? '$seconds초' : '$seconds seconds';
String roughTimeMinutes(int minutes) =>
isKoreanLocale ? '$minutes분' : '$minutes minutes';
String roughTimeHours(int hours) =>
isKoreanLocale ? '$hours시간' : '$hours hours';
String roughTimeDays(int days) =>
isKoreanLocale ? '$days일' : '$days days';
// ============================================================================
// 영어 문법 함수 (한국어에서는 단순화)
// ============================================================================
/// 관사 + 명사 (한국어: 수량만 표시)
String indefiniteL10n(String s, int qty) {
if (isKoreanLocale) {
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) {
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) => isKoreanLocale
// ignore: unnecessary_brace_in_string_interps
? '${race}들의 $title' // 한국어 조사 연결을 위해 중괄호 필요
: 'the $title of the ${_pluralize(race)}';
String impressiveGuyPattern2(String title, String name1, String name2) =>
isKoreanLocale
? '$name2의 $title $name1'
: '$title $name1 of $name2';
// ============================================================================
// namedMonster 관련
// ============================================================================
String namedMonsterFormat(String generatedName, String monsterType) =>
isKoreanLocale
? '$monsterType $generatedName'
: '$generatedName the $monsterType';
// ============================================================================
// 게임 데이터 번역 함수 (BuildContext 없이 사용)
// ============================================================================
/// 몬스터 이름 번역
String translateMonster(String englishName) =>
isKoreanLocale ? (monsterTranslationsKo[englishName] ?? englishName) : englishName;
/// 종족 이름 번역
String translateRace(String englishName) =>
isKoreanLocale ? (raceTranslationsKo[englishName] ?? englishName) : englishName;
/// 직업 이름 번역
String translateKlass(String englishName) =>
isKoreanLocale ? (klassTranslationsKo[englishName] ?? englishName) : englishName;
/// 칭호 이름 번역
String translateTitle(String englishName) =>
isKoreanLocale ? (titleTranslationsKo[englishName] ?? englishName) : englishName;
/// 인상적인 칭호 번역 (impressiveTitles용)
String translateImpressiveTitle(String englishName) =>
isKoreanLocale ? (impressiveTitleTranslationsKo[englishName] ?? englishName) : englishName;
/// 특수 아이템 이름 번역
String translateSpecial(String englishName) =>
isKoreanLocale ? (specialTranslationsKo[englishName] ?? englishName) : englishName;
/// 아이템 속성 이름 번역
String translateItemAttrib(String englishName) =>
isKoreanLocale ? (itemAttribTranslationsKo[englishName] ?? englishName) : englishName;
/// 아이템 "~의" 접미사 번역
String translateItemOf(String englishName) =>
isKoreanLocale ? (itemOfsTranslationsKo[englishName] ?? englishName) : englishName;
/// 단순 아이템 번역
String translateBoringItem(String englishName) =>
isKoreanLocale ? (boringItemTranslationsKo[englishName] ?? englishName) : englishName;
/// interestingItem 번역 (attrib + special 조합)
/// 예: "Golden Iterator" → "황금 이터레이터"
String translateInterestingItem(String attrib, String special) {
if (!isKoreanLocale) return '$attrib $special';
final translatedAttrib = itemAttribTranslationsKo[attrib] ?? attrib;
final translatedSpecial = specialTranslationsKo[special] ?? special;
return '$translatedAttrib $translatedSpecial';
}