Merge branch 'localization' into chroma-intergration

This commit is contained in:
tdixon 2017-10-10 21:39:58 -03:00
commit 695d2af03a
18 changed files with 652 additions and 203 deletions

View file

@ -2,6 +2,7 @@
#include "binding-types.h"
#include "pipe.h"
#include "debugwriter.h"
#include "i18n.h"
#include <SDL.h>
@ -73,9 +74,14 @@ RB_METHOD(journalSet)
// Record message
SDL_LockMutex(mutex);
message_len = strlen(name);
memcpy((char*)message_buffer, name, message_len);
strcpy((char*)message_buffer + message_len, (char*)lang_buffer);
message_len += strlen((char*)lang_buffer);
strcpy((char*)message_buffer, name);
if (message_len > 0) {
// in the case where journal is being sent empty string
// do not append the language suffix, because empty string
// is the signifier to terminate the journal
strcpy((char*)message_buffer + message_len, (char*)lang_buffer);
message_len += strlen((char*)lang_buffer);
}
SDL_UnlockMutex(mutex);
#if defined _WIN32
@ -127,6 +133,7 @@ RB_METHOD(journalSetLang)
const char *lang;
rb_get_args(argc, argv, "z", &lang RB_ARG_END);
strcpy((char*)lang_buffer+1, lang);
loadLocale(lang);
return Qnil;
}

View file

@ -62,7 +62,7 @@ win32 {
w32/niko.c \
w32/journal.c
LIBS += -lgdi32 -lshlwapi
LIBS += -lgdi32 -lshell32 -luuid -lole32
RC_FILE = w32/resources.rc
}

View file

@ -1,5 +1,8 @@
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>
#include <objbase.h>
#include <shlobj.h>
#define DEFAULT_WIDTH 800
@ -67,7 +70,6 @@ LRESULT CALLBACK journal_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
// IPC thread
#include <stdio.h>
DWORD WINAPI ipc_thread(LPVOID lpParam)
{
(void)lpParam;
@ -110,20 +112,53 @@ DWORD WINAPI ipc_thread(LPVOID lpParam)
return 0;
}
// check if the file "My Documents/My Games/Oneshot/save_progress.oneshot" exist
// if not, load the "default" image background
// if it does exist, try to read the last 8.. or so.. bytes from the file.
// this (should) contain a string like [XX_XX] or [XX] indicating the user's
// language code. This will be apended with an underscore to "save"
// to give the localized image file IFF the lang str exists
void init_check_save(WCHAR* save_path) {
FILE* savefile = _wfopen(save_path, L"rb");
char imgfile[16] = {0};
char langbuf[9] = {0};
char* openbrace = 0;
char* closebrace = 0;
if (savefile) {
strcpy(imgfile, "save");
fseek(savefile, -8, SEEK_END);
fread(langbuf, 1, 8, savefile);
fclose(savefile);
openbrace = strchr(langbuf, '[');
closebrace = strchr(langbuf, ']');
if (openbrace && closebrace && openbrace < closebrace) {
//we very probably have a language code here.
//so, lets do some hacky string manipulation to
//name our image file
imgfile[4] = '_';
strncpy(imgfile+5, openbrace+1, closebrace-(openbrace+1));
}
loadImage(imgfile);
} else {
loadImage("default");
}
}
int do_journal()
{
// Create
HINSTANCE module = GetModuleHandleW(NULL);
// Create
HINSTANCE module = GetModuleHandleW(NULL);
// Default image
WCHAR save_path[MAX_PATH];
SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, save_path);
PWSTR folder_path = NULL;
SHGetKnownFolderPath((REFKNOWNFOLDERID)&FOLDERID_Documents, 0, NULL, &folder_path);
wcscpy(save_path, folder_path);
wcscat(save_path, L"\\My Games\\Oneshot\\save_progress.oneshot");
if (PathFileExistsW(save_path)) {
loadImage("save");
} else {
loadImage("default");
}
CoTaskMemFree(folder_path);
init_check_save(save_path);
// Initial image
char message[IN_BUFFER_SIZE];

View file

@ -161,7 +161,8 @@ HEADERS += \
chromasdk/ChromaSDKImpl.h \
chromasdk/RzChromaSDKDefines.h \
chromasdk/RzChromaSDKTypes.h \
chromasdk/RzErrors.h
chromasdk/RzErrors.h \
src/i18n.h
SOURCES += \
src/main.cpp \
@ -205,7 +206,8 @@ SOURCES += \
binding-mri/journal-binding.cpp \
chromasdk/FrameController.cpp \
chromasdk/ChromaSdkImpl.cpp \
binding-mri/chroma-binding.cpp
binding-mri/chroma-binding.cpp \
src/i18n.cpp
STEAM {
HEADERS += src/steam.h steamshim/steamshim_child.h

View file

@ -9,14 +9,26 @@ class Doc_Message
def initialize
@viewport = Viewport.new(0, 0, 640, 480)
@sprite_bg = Sprite.new(@viewport)
if $game_switches[124] == true
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red')
else
@sprite_scroll_up = Sprite.new(@viewport)
@sprite_scroll_down = Sprite.new(@viewport)
if $game_switches[124] == true
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red')
@sprite_scroll_up.bitmap = RPG::Cache.picture('scroll_up_red')
@sprite_scroll_down.bitmap = RPG::Cache.picture('scroll_down_red')
else
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_blue') #Bitmap.new(640, 480)
end
@sprite_scroll_up.bitmap = RPG::Cache.picture('scroll_up_blue')
@sprite_scroll_down.bitmap = RPG::Cache.picture('scroll_down_blue')
end
@sprite_bg.zoom_x = @sprite_bg.zoom_y = 2
@sprite_bg.x = 120
@sprite_bg.y = 24
@sprite_scroll_up.zoom_x = @sprite_scroll_up.zoom_y = 2
@sprite_scroll_up.x = 524
@sprite_scroll_up.y = 24
@sprite_scroll_down.zoom_x = @sprite_scroll_down.zoom_y = 2
@sprite_scroll_down.x = 524
@sprite_scroll_down.y = 424
#@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 128))
@sprite_text = Sprite.new(@viewport)
@contents = Bitmap.new(200, 216)
@ -33,6 +45,11 @@ class Doc_Message
@sprite_bg.opacity = 0
@sprite_text.opacity = 0
@sprite_scroll_down.opacity = 0
@sprite_scroll_up.opacity = 0
@y_offset = 0
@scroll_limit = 0
# Animation flags
@fade_in = false
@ -59,6 +76,7 @@ class Doc_Message
$game_temp.message_proc = nil
end
$game_temp.message_doc_text = nil
@y_offset = 0
end
#--------------------------------------------------------------------------
# * Refresh: Load new message text and pre-process it
@ -68,11 +86,11 @@ class Doc_Message
text = ''
y = -1
if $game_switches[124] == true
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red')
else
if $game_switches[124] == true
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red')
else
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_blue') #Bitmap.new(640, 480)
end
end
# Pre-process text
text_raw = $game_temp.message_doc_text.to_str
@ -92,7 +110,8 @@ class Doc_Message
text_raw.gsub!("\\\\", "\\")
# Now split text into lines by measuring text metrics
x = y = 0
x = 0
y = 1
maxwidth = @contents.width - HORIZ_MARGIN * 2
spacesize = @contents.text_size(' ')
for i in text_raw.split(/ /)
@ -126,6 +145,11 @@ class Doc_Message
end
end
@scroll_limit = 11 - y
if @scroll_limit > 0
@scroll_limit = 0
end
# Prepare renderer
@contents.clear
@contents.font.color = Color.new(100, 92, 255, 255)
@ -133,7 +157,7 @@ class Doc_Message
@contents.font.color = Color.new(255, 92, 100, 255)
end
x = 0
y = 0
y = 1
# Get 1 text character in c (loop until unable to get text)
while ((c = text.slice!(/./m)) != nil)
@ -155,7 +179,7 @@ class Doc_Message
next
end
# Draw text
@contents.draw_text(HORIZ_MARGIN + x, VERT_MARGIN + (y + 1) * 18 - spacesize.height, 40, 18, c)
@contents.draw_text(HORIZ_MARGIN + x, VERT_MARGIN + (y + @y_offset) * 18 - spacesize.height, 40, 18, c)
# Add x to drawn text width
x += @contents.text_size(c).width
end
@ -176,7 +200,6 @@ class Doc_Message
@viewport.visible = false
$game_temp.message_window_showing = false
end
return
end
# Handle fade-in effect
@ -189,6 +212,23 @@ class Doc_Message
@fade_in = false
$game_temp.message_window_showing = true
end
end
# set the scroll indicators to the opacity of the bg,
# or 0 if they cannot scroll further
if @y_offset < 0
@sprite_scroll_up.opacity = @sprite_bg.opacity
else
@sprite_scroll_up.opacity = 0
end
if @y_offset > @scroll_limit
@sprite_scroll_down.opacity = @sprite_bg.opacity
else
@sprite_scroll_down.opacity = 0
end
# don't perform control actions while fading msg box
if @fade_in || @fade_out
return
end
@ -197,6 +237,14 @@ class Doc_Message
terminate_message
@fade_out = true
end
if Input.trigger?(Input::UP) && @y_offset < 0
@y_offset += 1
refresh()
end
if Input.trigger?(Input::DOWN) && @y_offset > @scroll_limit
@y_offset -= 1
refresh()
end
end
# Message is over and should be hidden or advanced to next

View file

@ -32,6 +32,23 @@ end
module Wallpaper
def self.set_persistent(name, color)
if (name == 'save_w32')
case $persistent.langcode
when 'fr'
name = $persistent.langcode + "\\" + name
when 'pt_BR'
name = $persistent.langcode + "\\" + name
when 'es'
name = $persistent.langcode + "\\" + name
when 'ja'
name = $persistent.langcode + "\\" + name
when 'ko'
name = $persistent.langcode + "\\" + name
when 'zh_CN'
name = $persistent.langcode + "\\" + name
end
end
$game_oneshot.wallpaper = name
$game_oneshot.wallpaper_color = color
Wallpaper.set(name, color)

View file

@ -11,7 +11,11 @@ class Interpreter
#--------------------------------------------------------------------------
def command_101
# If other text has been set to message_text
if $game_temp.message_text != nil || $game_temp.message_ed_text != nil || $game_temp.message_doc_text != nil || $game_temp.message_desktop_text != nil || $game_temp.message_credits_text != nil
if $game_temp.message_text != nil ||
$game_temp.message_ed_text != nil ||
$game_temp.message_doc_text != nil ||
$game_temp.message_desktop_text != nil ||
$game_temp.message_credits_text != nil
# End
return false
end

View file

@ -17,14 +17,134 @@ DOCUMENT_TEXT = \
DOCUMENT_POSTGAME_TEXT = "The code you need is "
DOCUMENT_TEXT_ES = \
"Me agrada s̵̨a̴̕͠l̀͞u̵d͡a̵r̨̨̧te ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"Esta es̷̸͢ m̕͞͡i̕ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞ m͞͡e͜ǹs͜a̵j̕͜e̵͜ y me temo que ha de ser breve. \n"\
"Te hago entrega de un diario. Parte de él está escrito e҉n͟͏ ҉u͘͢n̡a l̀͢e͏͘͝n̷̷ģ͝ú͜҉a̷̛͏ ̢q̸͏u̵̕e̸ ̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"S͏҉͝i̸̡͘͟n̢͠ ̨́͜e̷m̸̶̴͡b́̕á̢r̛͢g̡̛͝o҉̀͟͏̡, ̷͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞n̕ ĺ̕͜ee̢͘ ͏͝y̵̵͟ ̶̛ sabrás qué hacer. \n"\
"También te he d͟͞e̸̴j̡a͝d̡̢͠o͡҉ u̶n͏͘ą̵̧ ̸͜má̧͘s̴c̨̛a̧r͜͠á̷̕ b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"B̶u̧şca ̧u҉n͘a ̸caj͟a̵ ̨f͡u̵e͘r̕t́e de͠ mètal̨ en̡ ͝l͏a ͝mi͝n͞a̶ ̴s͠i̡t̡úad̢a ̕al ęst͡e, ̶e̕n u͡n͟ ̀pu̡nt̢o̶ ͝e̶ntr͏e ͢el o̷céano y ̵e͟l m̢i̷ra͢d͞oŕ. \n\n"\
\
"He aquí el código: "
DOCUMENT_POSTGAME_TEXT_ES = "He aquí el código: "
DOCUMENT_TEXT_PT_BR = \
"Olá, ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"È̴̷̵͝s̕͠t͠͏͏a҉́̀̕̕ h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ ḿ̶e͘n̸͟s̵̢͞a̷̴͞g̷͟è͞m̵͝, e infelizmente preciso ser breve. \n"\
"Eu lhe deixei um diário, que contém partes escritas numa ĺ͡í̧͘͢ńg͏ua҉͠ ̴q̶u̵͠e y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞ —̨ ͞lei̧͜a͢͞-áş ͢e ̛͘͠você saberá o que fazer. \n"\
"Também lhe d̵͠ȩ̢ì̴xe͘i ̷̸ưm̀ą̸ ́͞má̵s҉͡c̸̨͟ą͠ŕa͟ b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"P̵r̡o͢cu̧r͞e͡ ͏u҉m͞ ͘cof̢re ͢de͠ ̛me̢tal na̶ pedrȩir͏a ą ҉les̷té,̴ ́e̴nt̡r̨e҉ o̕ ma͜r ę o̴ p͜on̡t́o̕ ̡de͘ o̵b̀s̴e͢r҉va̵ç̨ão̡.\n\n"\
\
"O código necessário é: "
DOCUMENT_POSTGAME_TEXT_PT_BR = "He aquí el código: "
DOCUMENT_TEXT_FR = \
"Bonjour ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"C̷͞'̡̨ȩ̀͜s̶̷̢̕t̶̸́҉ h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ ͟m͏ȩ͢͢s̴͡s̀͟҉a̵͡g͝e̸͡,̕͏̡ et j'ai bien peur de devoir être bref. \n"\
"Je vous ai laissé un carnet, en partie écrit dans u̢͏͡n͏͟ȩ ̧͜͝l҉͢àngu͝e͘ ҉̸q̕͞ue y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞ ̧͜͏L̢i̷̛se̢͏҉z͟͏-̨̕͞l͞à͜͏ ̴e̴͝t̕ ̀͝vous saurez quoi faire. \n"\
"Je vous ai aussi lai̴s̛̀̀s̢̡ȩ́̕ ͝͠ừn̛̛͠ ́͡m͜҉a̕͝s̸̶qu̴e̴̢̛,b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"Cher͞c̷he̴z un c͞o͜ff́r͞e-f̴or͟t͟ ̸en͏ ͝mé̛tal͏ ͟da̶nş ͟l͏a͠ ͝cąr͡r͠i̡èŗe à͞ l͘'͞e͜s̵t, ̷q͘uel̷q҉ue̴ ́part e͠ntre͞ ̡l'o̕c͠éań ̡et le̷ p̛os͏te ͡d̴'̕ob͟s͏er̀vat͜iòn͘.̡ ͝\n\n"\
\
"Le code nécessaire est : "
DOCUMENT_POSTGAME_TEXT_FR = "Le code nécessaire est : "
DOCUMENT_TEXT_JA = \
"親愛なる ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"君にメッセージをh̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ 手̛͜҉短̧͢に̷͏要̷̨件̧͘͜͢を̸̕͜͜͞説明しなければならない。\n"\
"1冊の日記を残̶̧́し̢͝͠た̴͘͠。̵̸̀̕ y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̕͏͏͢͞な̷̨̡͝言͠҉̡語͏҉で書かれている。\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞n̕読̵͏め̧͡ば̴̛̀͠成すべきことがわかるはずだ。\n"\
"他にマ̨̧̧ス̷́͟͜ク̧͏͏͏̛͘͞残̴̵し̧̀た́͡。̀͢҉҉b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"東͠に͡向か͜い͢、海と見͠晴し͜台̡と̡の間のど͘こかにあ̸る採石場̸で̛金͜庫͘を̶探̢すんだ̴。̸\n\n"\
\
"必要なコードは次の通りだ: "
DOCUMENT_POSTGAME_TEXT_JA = "必要なコードは次の通りだ: "
DOCUMENT_TEXT_KO = \
"안녕하십̴̵̢͟҉니̵́̕͢͞까̡́͡ ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"처̷̨̀́͞음̸̵̵̧҉h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ 간̨҉̶̡҉략̢̧하̸̷̡͠게҉̛͢͞ 써야 한다는 걱정이 앞서는군요.\n"\
"당신께 일지를 남겨두었습니다. 일̷̡̕͠지͢͜의҉̀͘͠ y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞n̕ 읽́͟어͢͡҉보̕͢͞͞시̧̕͢면̷̡͠ 무엇을 해야 할지 알게 될 것입니다.\n"\
"그리고 마̴̴̨̡스̧͘̕̕͝크̡͝͠͝도͏̶̡̡́ ̶̷͘͟͞두҉̴͘었͞͠҉͠습̧̧̨̕͢니̸̧̀͢다̨͘͟,̵̷ b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"바̶다̧와̧ ͡초소͟ ́지́역͞ ͜사이́ 동͝쪽 ̴채͞석장에̸서͠ 금̡속 금̵고를̡ ̢찾아보십시오͟.̡\n\n"\
\
"필요한 코드는 다음과 같습니다. "
DOCUMENT_POSTGAME_TEXT_KO = "필요한 코드는 다음과 같습니다. "
DOCUMENT_TEXT_ZH_CN = \
"亲爱̷̷͟͝͡的̸̀̀ ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"虽̸̛̀͡然̡́ ̨҉͟͞h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ ,҉̴̛͠但̸̨̕恐̴̡͞怕́我̡只能简短地说明情况。\n"\
"我为你准备了一本日͏̛̀͢͞志̸̡͜҉̕但̶͟是̨͘͢͡͞y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞阅̸̨̛͝读҉͠͏̧́日̶̴志̵́͢后你就知道做怎么做了。\n"\
"同时我也为你̵̛́͏准̸̴̡̀备̧͞了̶̧̢́一̧̧̕幅̴͠͡面̶͘͝具̴̸̧͡b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"在͝采石̕场东边͢寻找̀一̶个͝金͠属保̢险箱̶,̕它就̀在海洋与侦́察哨̀之间。\n\n"\
\
"你所需要的代码:"
DOCUMENT_POSTGAME_TEXT_ZH_CN = "你所需要的代码:"
def safe_puzzle_write
doc_text = DOCUMENT_TEXT
case $persistent.langcode
when 'fr'
doc_text = DOCUMENT_TEXT_FR
when 'pt_BR'
doc_text = DOCUMENT_TEXT_PT_BR
when 'es'
doc_text = DOCUMENT_TEXT_ES
when 'ja'
doc_text = DOCUMENT_TEXT_JA
when 'ko'
doc_text = DOCUMENT_TEXT_KO
when 'zh_CN'
doc_text = DOCUMENT_TEXT_ZH_CN
end
File.open(Oneshot::DOCS_PATH + "/DOCUMENT.oneshot.txt", 'w') do |file|
file.puts(DOCUMENT_TEXT + $game_variables[20].to_s)
file.puts(doc_text + $game_variables[20].to_s)
end
end
def safe_puzzle_postgame_write
doc_text = DOCUMENT_POSTGAME_TEXT
case $persistent.langcode
when 'fr'
doc_text = DOCUMENT_POSTGAME_TEXT_FR
when 'pt_BR'
doc_text = DOCUMENT_POSTGAME_TEXT_PT_BR
when 'es'
doc_text = DOCUMENT_POSTGAME_TEXT_ES
when 'ja'
doc_text = DOCUMENT_POSTGAME_TEXT_JA
when 'ko'
doc_text = DOCUMENT_POSTGAME_TEXT_KO
when 'zh_CN'
doc_text = DOCUMENT_POSTGAME_TEXT_ZH_CN
end
File.open(Oneshot::DOCS_PATH + "/DOCUMENT.oneshot.txt", 'w') do |file|
file.puts(DOCUMENT_POSTGAME_TEXT + $game_variables[20].to_s)
file.puts(doc_text + $game_variables[20].to_s)
end
end

View file

@ -42,17 +42,3 @@ class Tone
self.red == 0 && self.green == 0 && self.blue == 0 && self.gray == 0
end
end
module Graphics
class << self
alias_method :update_native, :update
def update
#if $game_map.map_id == 97
# Oneshot.allow_exit false
#elsif $game_system.map_interpreter
# Oneshot.allow_exit ($scene == nil)
#end
update_native
end
end
end

View file

@ -140,7 +140,7 @@ module Script
end
return false
end
def self.countdown_extend_over
equinox = Time.new(2017, 03, 27)
diff = equinox - Time.now
@ -149,7 +149,7 @@ module Script
end
return false
end
def self.cdown_update(equinox)
diff = equinox - Time.now
if(diff < 0)
@ -217,7 +217,7 @@ module Script
def self.countdown_update
return cdown_update(Time.new(2017, 03, 27))
end
def self.countdown_extend_update
return cdown_update(Time.new(2017, 03, 27))
end
@ -254,7 +254,7 @@ module Script
end
end
end
def self.niko_reflection_enc_update
for event in $game_map.events.values
if event.name == "niko reflection"
@ -268,7 +268,7 @@ module Script
if event.real_y > 19*128
event.real_y = 19*128
end
if event.x > 14
event.x = 14
elsif event.x < 6
@ -279,7 +279,7 @@ module Script
elsif event.real_x < (6*128) + 32
event.real_x = (6*128) + 32
end
event.direction = $game_player.direction
event.pattern = $game_player.pattern
case event.direction
@ -292,8 +292,8 @@ module Script
end
end
end
def self.niko_reflection_peng_update
for event in $game_map.events.values
if event.name == "niko reflection"
@ -307,7 +307,7 @@ module Script
if event.real_y > 19*128
event.real_y = 19*128
end
if event.x > 14
event.x = 14
elsif event.x < 6
@ -318,7 +318,7 @@ module Script
elsif event.real_x < (6*128) + 32
event.real_x = (6*128) + 32
end
return
end
end
@ -373,11 +373,11 @@ module Script
end
def self.copy_journal
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games") unless File.exists?(Oneshot::DOCS_PATH + "/My Games")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot")
begin
File.open("_______.exe", "rb") do |input|
File.open(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\_______.exe","wb") do |output|
File.open(Oneshot::DOCS_PATH + "/My Games/Oneshot/_______.exe","wb") do |output|
while buff = input.read(4096)
output.write(buff)
end
@ -388,7 +388,7 @@ module Script
end
if File.exists?("README.txt")
File.open("README.txt", "rb") do |input|
File.open(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\README.txt","wb") do |output|
File.open(Oneshot::DOCS_PATH + "/My Games/Oneshot/README.txt","wb") do |output|
while buff = input.read(4096)
output.write(buff)
end
@ -396,43 +396,43 @@ module Script
end
end
end
def self.create_boxes
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal1") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal1")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal2") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal2")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal3") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal3")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games") unless File.exists?(Oneshot::DOCS_PATH + "/My Games")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal1") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal1")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal2") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal2")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal3") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal3")
Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal")
end
def self.delete_if_exists(f_name)
File.delete(f_name) unless !File.exists?(f_name)
end
def self.clear_boxes
for i in 1..3
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal" + i.to_s
portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal" + i.to_s
case i
when 1
delete_if_exists(portal_path + "\\blue_npc_prototype.png")
delete_if_exists(portal_path + "\\proto1.png")
delete_if_exists(portal_path + "\\keyB.txt")
delete_if_exists(portal_path + "/blue_npc_prototype.png")
delete_if_exists(portal_path + "/proto1.png")
delete_if_exists(portal_path + "/keyB.txt")
when 2
delete_if_exists(portal_path + "\\green_npc_cedric.png")
delete_if_exists(portal_path + "\\cedric.png")
delete_if_exists(portal_path + "\\keyG.txt")
delete_if_exists(portal_path + "/green_npc_cedric.png")
delete_if_exists(portal_path + "/cedric.png")
delete_if_exists(portal_path + "/keyG.txt")
when 3
delete_if_exists(portal_path + "\\red_rue.png")
delete_if_exists(portal_path + "\\rue.png")
delete_if_exists(portal_path + "\\keyR.txt")
delete_if_exists(portal_path + "/red_rue.png")
delete_if_exists(portal_path + "/rue.png")
delete_if_exists(portal_path + "/keyR.txt")
end
end
delete_if_exists(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal\\keyB.txt")
delete_if_exists(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal\\keyG.txt")
delete_if_exists(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal\\keyR.txt")
delete_if_exists(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal/keyB.txt")
delete_if_exists(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal/keyG.txt")
delete_if_exists(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal/keyR.txt")
end
def self.copy_file(src, dst)
begin
File.open(src, "rb") do |input|
@ -446,79 +446,89 @@ module Script
#this probably means the file already exists and is open, so no need to create it again
end
end
def self.write_key(dst, str)
File.open(dst, 'w') do |file|
file.puts(str)
end
end
def self.put_key_in_box(numb)
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal" + numb.to_s
portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal" + numb.to_s
case numb
when 1
copy_file("Graphics\\Characters\\blue_npc_prototype.png", portal_path + "\\blue_npc_prototype.png")
copy_file("Graphics\\Faces\\proto1.png", portal_path + "\\proto1.png")
write_key(portal_path + "\\keyB.txt", PROTO_TEXT)
copy_file("Graphics/Characters/blue_npc_prototype.png", portal_path + "/blue_npc_prototype.png")
copy_file("Graphics/Faces/proto1.png", portal_path + "/proto1.png")
write_key(portal_path + "/keyB.txt", PROTO_TEXT)
when 2
copy_file("Graphics\\Characters\\green_npc_cedric.png", portal_path + "\\green_npc_cedric.png")
copy_file("Graphics\\Faces\\cedric.png", portal_path + "\\cedric.png")
write_key(portal_path + "\\keyG.txt", CEDRIC_TEXT)
copy_file("Graphics/Characters/green_npc_cedric.png", portal_path + "/green_npc_cedric.png")
copy_file("Graphics/Faces/cedric.png", portal_path + "/cedric.png")
write_key(portal_path + "/keyG.txt", CEDRIC_TEXT)
when 3
copy_file("Graphics\\Characters\\red_rue.png", portal_path + "\\red_rue.png")
copy_file("Graphics\\Faces\\rue.png", portal_path + "\\rue.png")
write_key(portal_path + "\\keyR.txt", RUE_TEXT)
copy_file("Graphics/Characters/red_rue.png", portal_path + "/red_rue.png")
copy_file("Graphics/Faces/rue.png", portal_path + "/rue.png")
write_key(portal_path + "/keyR.txt", RUE_TEXT)
end
end
def self.password1
copy_file("Graphics\\Fogs\\_\\scenario1\\pw1.png", Oneshot::DOCS_PATH + "\\ONESHOT_password1.png")
copy_file("Graphics\\Fogs\\_\\scenario1\\pw2.png", Oneshot::DOCS_PATH + "\\ONESHOT_password2.png")
copy_file("Graphics\\Fogs\\_\\scenario1\\pw3.png", Oneshot::DOCS_PATH + "\\ONESHOT_password3.png")
copy_file("Graphics\\Fogs\\_\\scenario1\\pw4.png", Oneshot::DOCS_PATH + "\\ONESHOT_password4.png")
locale = $persistent.langcode
if !Language::LANGUAGES.include? locale
locale = 'en'
end
source_dir = "Graphics/Fogs/_/scenario1/" + locale.downcase
copy_file(source_dir + "/pw1.png", Oneshot::DOCS_PATH + "/ONESHOT_password1.png")
copy_file(source_dir + "/pw2.png", Oneshot::DOCS_PATH + "/ONESHOT_password2.png")
copy_file(source_dir + "/pw3.png", Oneshot::DOCS_PATH + "/ONESHOT_password3.png")
copy_file(source_dir + "/pw4.png", Oneshot::DOCS_PATH + "/ONESHOT_password4.png")
end
def self.password2
copy_file("Graphics\\Fogs\\_\\scenario2\\pw1.png", Oneshot::DOCS_PATH + "\\ONESHOT_password1.png")
copy_file("Graphics\\Fogs\\_\\scenario2\\pw2.png", Oneshot::DOCS_PATH + "\\ONESHOT_password2.png")
copy_file("Graphics\\Fogs\\_\\scenario2\\pw3.png", Oneshot::DOCS_PATH + "\\ONESHOT_password3.png")
copy_file("Graphics\\Fogs\\_\\scenario2\\pw4.png", Oneshot::DOCS_PATH + "\\ONESHOT_password4.png")
locale = $persistent.langcode
if !Language::LANGUAGES.include? locale
locale = 'en'
end
source_dir = "Graphics/Fogs/_/scenario2/" + locale.downcase
copy_file(source_dir + "/pw1.png", Oneshot::DOCS_PATH + "/ONESHOT_password1.png")
copy_file(source_dir + "/pw2.png", Oneshot::DOCS_PATH + "/ONESHOT_password2.png")
copy_file(source_dir + "/pw3.png", Oneshot::DOCS_PATH + "/ONESHOT_password3.png")
copy_file(source_dir + "/pw4.png", Oneshot::DOCS_PATH + "/ONESHOT_password4.png")
end
=begin
def self.take_key_out_of_box(numb)
if File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Box" + numb.to_s + "\\key" + numb.to_s + ".png")
File.delete(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Box" + numb.to_s + "\\key" + numb.to_s + ".png")
if File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Box" + numb.to_s + "/key" + numb.to_s + ".png")
File.delete(Oneshot::DOCS_PATH + "/My Games/Oneshot/Box" + numb.to_s + "/key" + numb.to_s + ".png")
end
if File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigBox\\key" + numb.to_s + ".png")
File.delete(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigBox\\key" + numb.to_s + ".png")
if File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigBox/key" + numb.to_s + ".png")
File.delete(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigBox/key" + numb.to_s + ".png")
end
end
=end
def self.is_key_in_box(numb)
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal" + numb.to_s
portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal" + numb.to_s
case numb
when 1
return File.exists?(portal_path + "\\keyB.txt")
return File.exists?(portal_path + "/keyB.txt")
when 2
return File.exists?(portal_path + "\\keyG.txt")
return File.exists?(portal_path + "/keyG.txt")
when 3
return File.exists?(portal_path + "\\keyR.txt")
return File.exists?(portal_path + "/keyR.txt")
end
return false
end
def self.is_key_in_bigbox(numb)
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal"
portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal"
case numb
when 1
return File.exists?(portal_path + "\\keyB.txt")
return File.exists?(portal_path + "/keyB.txt")
when 2
return File.exists?(portal_path + "\\keyG.txt")
return File.exists?(portal_path + "/keyG.txt")
when 3
return File.exists?(portal_path + "\\keyR.txt")
return File.exists?(portal_path + "/keyR.txt")
end
return false
end
@ -559,10 +569,10 @@ def check_exit(min, max, x: -1, y: -1)
end
def loadQASave(fname)
filename = "testing_saves/" + fname + ".rxdata"
filename = "testing_saves/" + fname + ".rxdata"
# If file doesn't exist
unless FileTest.exist?(filename)
filename = "testing_saves_postgame/" + fname + ".rxdata"
filename = "testing_saves_postgame/" + fname + ".rxdata"
unless FileTest.exist?(filename)
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
@ -571,7 +581,7 @@ def loadQASave(fname)
end
# Play load SE
$game_system.se_play($data_system.load_se)
# Read save data
file = File.open(filename, "rb")
# Read character data for drawing save file

View file

@ -7,9 +7,14 @@ class Sprite_MapText < Sprite
@real_x = x * 4 * 32
@real_y = y * 4 * 32
self.zoom_x = 2
self.zoom_y = 2
self.bitmap = Bitmap.new(200, 24)
if (Language::FONT_WESTERN == Font.default_name)
self.zoom_x = 2
self.zoom_y = 2
else
self.zoom_x = 1.5
self.zoom_y = 1.5
end
#calculate text width
spacewidth = self.bitmap.text_size(' ').width

View file

@ -1,4 +1,4 @@
Font.default_name = Language::FONT_CJK
Font.default_name = Language::FONT_J
class Language
def self.create_input

View file

@ -7,14 +7,18 @@
class Language
FONT_WESTERN = 'Terminus (TTF)'
FONT_CJK = 'WenQuanYi Micro Hei'
FONT_CK = 'WenQuanYi Micro Hei'
FONT_J = 'HigashiOme Gothic regular'
LANG_WESTERN = [
'en', 'fr', 'pt_BR', 'es'
]
LANG_CJK = [
'ja', 'ko', 'zh_CN'
LANG_J = [
'ja'
]
LANGUAGES = LANG_WESTERN + LANG_CJK
LANG_CK = [
'ko', 'zh_CN'
]
LANGUAGES = LANG_WESTERN + LANG_CK + LANG_J
class << self
def set(lc)
@ -28,12 +32,15 @@ class Language
if FileTest.exist?(path)
File.open(path, "rb") do |file|
@data = Marshal.load(file)
if LANG_CJK.include? name
Font.default_name = FONT_CJK
if LANG_CK.include? name
Font.default_name = FONT_CK
elsif LANG_J.include? name
Font.default_name = FONT_J
else
Font.default_name = FONT_WESTERN
end
Journal.setLang(name)
dbg_print(Font.default_name)
end
end
end
@ -44,14 +51,13 @@ class Language
# Translate some text
def tr(string)
#dbg_print(caller_locations(1, 1).first.tap{|loc| puts "#{loc.path}:#{loc.lineno}"})
dbg_print(string)
if @data
rv = @data[Zlib::crc32(string)] || string
else
rv = string
end
dbg_print(rv)
return rv
dbg_print(string + " -> " + rv)
return String.new(rv)
end
# Turn all database items into translatable strings

86
src/i18n.cpp Normal file
View file

@ -0,0 +1,86 @@
/*
Really hacked-together naiive implementation of gettext
*/
#include "i18n.h"
#include "debugwriter.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char* LOC_HEADER = "ONELOC\x10";
char** strdict = 0;
unsigned int nStr = 0;
int family = LOCALE_FAMILY_LATIN;
int getLocaleFamily() {
Debug() << "Get family:" << family;
return family;
}
const char* findtext(unsigned int msgid, const char* fallback) {
Debug() << "Looking for msg" << msgid << fallback;
if (msgid >= nStr) {
return fallback;
} else {
Debug() << "found" << strdict[msgid];
return strdict[msgid];
}
}
void unloadLocale() {
for (unsigned int i = 0; i < nStr; i++) {
free(strdict[i]);
}
free(strdict);
strdict = 0;
nStr = 0;
}
void _setLocaleFamily(const char* locale) {
if (!strcmp(locale, "ja")
|| !strcmp(locale, "ko")
|| !strcmp(locale, "zh_CN")) {
family = LOCALE_FAMILY_ASIAN;
} else {
family = LOCALE_FAMILY_LATIN;
}
}
void loadLocale(const char* locale) {
Debug() << "Load locale:" << locale;
char pathbuf[100];
FILE* locfile;
char header[8];
unsigned int i;
int strSize = 0;
unloadLocale();
_setLocaleFamily(locale);
sprintf(pathbuf, "Languages/internal/%s.loc", locale);
locfile = fopen(pathbuf, "rb");
if (locfile) {
fread(header, 1, 8, locfile);
if (!strcmp(header, LOC_HEADER)) {
//read number of strs in this file
fread(&nStr, 4, 1, locfile);
strdict = (char**)malloc(sizeof(char*) * nStr);
for (i = 0; i < nStr; i++) {
//read the size of the next string
fread(&strSize, 4, 1, locfile);
strdict[i] = (char*)malloc(strSize+1);
if (strSize > 0) {
//read the contents of the next string
fread(strdict[i], 1, strSize, locfile);
strdict[i][strSize] = 0;
Debug() << "localization #" << i << " : " << strdict[i] << "|" << strSize;
}
strdict[i][strSize] = 0;
}
}
fclose(locfile);
}
}

14
src/i18n.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef I18N_H
#define I18N_H
#include "trstr.h"
void unloadLocale();
void loadLocale(const char* locale);
const char* findtext(unsigned int msgid, const char* fallback);
int getLocaleFamily();
#define LOCALE_FAMILY_LATIN 1
#define LOCALE_FAMILY_ASIAN 2
#endif /* end of include guard: I18N_H */

View file

@ -37,6 +37,7 @@
#include "debugwriter.h"
#include "exception.h"
#include "gl-fun.h"
#include "i18n.h"
#include "binding.h"
@ -359,6 +360,8 @@ int main(int argc, char *argv[])
Debug() << "Shutting down.";
unloadLocale();
alcCloseDevice(alcDev);
SDL_DestroyWindow(win);

View file

@ -34,6 +34,9 @@
#include "etc-internal.h"
#include "util.h"
#include "sharedstate.h"
#include "i18n.h"
#include "debugwriter.h"
#include <algorithm>
#include <assert.h>
@ -45,8 +48,11 @@ const uint8_t cBgDark = 20;
const uint8_t cLine = 0;
const uint8_t cText = 255;
const char *const fontFamily = "Terminus (TTF)";
const uint8_t fontSize = 12;
// const char *const fontFamilyLatin = "Terminus (TTF)";
const char *const fontFamilyLatin = "WenQuanYi Micro Hei";
const uint8_t fontSizeLatin = 12;
const char *const fontFamilyAsian = "WenQuanYi Micro Hei";
const uint8_t fontSizeAsian = 16;
static bool pointInRect(const SDL_Rect &r, int x, int y)
{
@ -55,51 +61,86 @@ static bool pointInRect(const SDL_Rect &r, int x, int y)
typedef SettingsMenuPrivate SMP;
#define BTN_STRING(btn) { Input:: btn, #btn }
#define BTN_STRING(btn, id) { Input:: btn, id, #btn }
struct VButton
{
Input::ButtonCode code;
int trstrId;
const char *str;
} static const vButtons[] =
{
BTN_STRING(Up),
BTN_STRING(Left),
BTN_STRING(Action),
BTN_STRING(Cancel),
BTN_STRING(Menu),
BTN_STRING(L),
BTN_STRING(Up, TRSTR_KEYBIND_UP),
BTN_STRING(Left, TRSTR_KEYBIND_LEFT),
BTN_STRING(Action, TRSTR_KEYBIND_ACTION),
BTN_STRING(Cancel, TRSTR_KEYBIND_CANCEL),
BTN_STRING(Menu, TRSTR_KEYBIND_MENU),
BTN_STRING(L, TRSTR_KEYBIND_L),
BTN_STRING(Down),
BTN_STRING(Right),
BTN_STRING(Run),
BTN_STRING(Deactivate),
BTN_STRING(Items),
BTN_STRING(R),
BTN_STRING(Down, TRSTR_KEYBIND_DOWN),
BTN_STRING(Right, TRSTR_KEYBIND_RIGHT),
BTN_STRING(Run, TRSTR_KEYBIND_RUN),
BTN_STRING(Deactivate, TRSTR_KEYBIND_DEACTIVATE),
BTN_STRING(Items, TRSTR_KEYBIND_ITEMS),
BTN_STRING(R, TRSTR_KEYBIND_R),
};
static elementsN(vButtons);
const char* getButtonName(int buttonId) {
switch (buttonId) {
case 0:
return findtext(TRSTR_KEYBIND_A, "A Button");
break;
case 1:
return findtext(TRSTR_KEYBIND_B, "B Button");
break;
case 2:
return findtext(TRSTR_KEYBIND_X, "X Button");
break;
case 3:
return findtext(TRSTR_KEYBIND_Y, "Y Button");
break;
case 4:
return findtext(TRSTR_KEYBIND_BACK, "Back Button");
break;
case 5:
return findtext(TRSTR_KEYBIND_GUIDE, "Guide Button");
break;
case 6:
return findtext(TRSTR_KEYBIND_START, "Start Button");
break;
case 7:
return findtext(TRSTR_KEYBIND_LSTICK, "Left Stick");
break;
case 8:
return findtext(TRSTR_KEYBIND_RSTICK, "Right Stick");
break;
case 9:
return findtext(TRSTR_KEYBIND_LSHOULDER, "Left Shoulder");
break;
case 10:
return findtext(TRSTR_KEYBIND_RSHOULDER, "Right Shoulder");
break;
case 11:
return findtext(TRSTR_KEYBIND_PADU, "D-Pad (Up)");
break;
case 12:
return findtext(TRSTR_KEYBIND_PADD, "D-Pad (Down)");
break;
case 13:
return findtext(TRSTR_KEYBIND_PADL, "D-Pad (Left)");
break;
case 14:
return findtext(TRSTR_KEYBIND_PADR, "D-Pad (Right)");
break;
default:
return findtext(TRSTR_KEYBIND_UNK, "Unknown key");
}
}
/* Human readable string representation */
std::string sourceDescString(const SourceDesc &src)
{
static const char *const gcButtonNames[SDL_CONTROLLER_BUTTON_MAX] = {
"A Button",
"B Button",
"X Button",
"Y Button",
"Back Button",
"Guide Button",
"Start Button",
"Left Stick",
"Right Stick",
"Left Shoulder",
"Right Shoulder",
"D-Pad (Up)",
"D-Pad (Down)",
"D-Pad (Left)",
"D-Pad (Right)",
};
char buf[128];
char pos;
@ -111,52 +152,55 @@ std::string sourceDescString(const SourceDesc &src)
case Key:
{
if (src.d.scan == SDL_SCANCODE_LSHIFT)
return "Shift";
return findtext(TRSTR_KEYBIND_SHIFT, "Shift");
SDL_Keycode key = SDL_GetKeyFromScancode(src.d.scan);
const char *str = SDL_GetKeyName(key);
if (*str == '\0')
return "Unknown key";
else
return std::string(str) + " Key";
if (*str == '\0') {
return findtext(TRSTR_KEYBIND_UNK, "Unknown key");
} else {
snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_KEYFMT, "%s Key"), str);
return buf;
}
}
case CButton:
snprintf(buf, sizeof(buf), "%s", gcButtonNames[src.d.jb]);
snprintf(buf, sizeof(buf), "%s", getButtonName(src.d.jb));
return buf;
case CAxis:
switch (src.d.ja.axis) {
case SDL_CONTROLLER_AXIS_LEFTX:
if (src.d.ja.dir == Negative)
return "Left Stick (Left)";
return findtext(TRSTR_KEYBIND_LSTICKL, "Left Stick (Left)");
else
return "Left Stick (Right)";
return findtext(TRSTR_KEYBIND_LSTICKR, "Left Stick (Right)");
case SDL_CONTROLLER_AXIS_LEFTY:
if (src.d.ja.dir == Negative)
return "Left Stick (Up)";
return findtext(TRSTR_KEYBIND_LSTICKU, "Left Stick (Up)");
else
return "Left Stick (Down)";
return findtext(TRSTR_KEYBIND_LSTICKD, "Left Stick (Down)");
case SDL_CONTROLLER_AXIS_RIGHTX:
if (src.d.ja.dir == Negative)
return "Right Stick (Left)";
return findtext(TRSTR_KEYBIND_RSTICKL, "Right Stick (Left)");
else
return "Right Stick (Right)";
return findtext(TRSTR_KEYBIND_RSTICKR, "Right Stick (Right)");
case SDL_CONTROLLER_AXIS_RIGHTY:
if (src.d.ja.dir == Negative)
return "Right Stick (Up)";
return findtext(TRSTR_KEYBIND_RSTICKU, "Right Stick (Up)");
else
return "Right Stick (Down)";
return findtext(TRSTR_KEYBIND_RSTICKD, "Right Stick (Down)");
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
return "Left Trigger";
return findtext(TRSTR_KEYBIND_LTRIGGER, "Left Trigger");
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
return "Right Trigger";
return findtext(TRSTR_KEYBIND_RTRIGGER, "Right Trigger");
}
return "";
case JButton:
snprintf(buf, sizeof(buf), "Joy Button %d", src.d.jb);
snprintf(buf, sizeof(buf),
findtext(TRSTR_KEYBIND_JOYBTTNFMT, "Joy Button %d"), src.d.jb);
return buf;
case JHat:
@ -181,12 +225,12 @@ std::string sourceDescString(const SourceDesc &src)
default:
pos = '-';
}
snprintf(buf, sizeof(buf), "Joy Hat %d:%c",
snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_JOYHATFMT, "Joy Hat %d:%c"),
src.d.jh.hat, pos);
return buf;
case JAxis:
snprintf(buf, sizeof(buf), "Joy Axis %d%c",
snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_JOYAXISFMT, "Joy Axis %d%c"),
src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
return buf;
}
@ -495,9 +539,12 @@ struct SettingsMenuPrivate
int x, int y, int alignW,
Justification just, SDL_Color c, bool bold = false)
{
Debug() << "draw text:" << str;
SDL_Surface *txt = createTextSurface(str, c, bold);
blitTextSurf(surf, x, y, alignW, txt, just);
SDL_FreeSurface(txt);
if (txt) {
blitTextSurf(surf, x, y, alignW, txt, just);
SDL_FreeSurface(txt);
}
}
void drawText(SDL_Surface *surf, const char *str,
@ -586,7 +633,9 @@ struct SettingsMenuPrivate
if (state == AwaitingInput)
{
char buf[64];
snprintf(buf, sizeof(buf), "Press key or joystick button for \"%s\"", captureName);
snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_KEYPROMPT,
"Press key or joystick button for \"%s\""),
captureName);
drawOff = Vec2i();
@ -871,7 +920,7 @@ void BindingWidget::drawHandler(SDL_Surface *surf)
p->strokeRectInner(surf, cLine, 0, 0, rect.w, rect.h, 2);
/* Virtual button name */
p->drawText(surf, vb.str, 1, rect.h/2, cellOffX, Center, true);
p->drawText(surf, findtext(vb.trstrId, vb.str), 1, rect.h/2, cellOffX, Center, true);
/* Cell frames */
p->strokeLineV(surf, cLine, cellOffX, 0, rect.h, 2);
@ -1027,13 +1076,18 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
p->hasFocus = false;
p->destroyReq = false;
p->window = SDL_CreateWindow("Key bindings",
p->window = SDL_CreateWindow(findtext(TRSTR_KEYBIND_TITLE, "Key bindings"),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
winSize.x, winSize.y, SDL_WINDOW_INPUT_FOCUS);
p->winSurf = SDL_GetWindowSurface(p->window);
p->winID = SDL_GetWindowID(p->window);
p->font = shState->fontState().getFont(fontFamily, fontSize);
if (getLocaleFamily() == LOCALE_FAMILY_ASIAN) {
p->font = shState->fontState().getFont(fontFamilyAsian, fontSizeAsian);
} else {
p->font = shState->fontState().getFont(fontFamilyLatin, fontSizeLatin);
}
p->rgb = p->winSurf->format;
@ -1067,24 +1121,24 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
IntRect btRects[] =
{
IntRect(16, buttonY, 112, buttonH),
IntRect(winSize.x-16-64*2-8, buttonY, 64, buttonH),
IntRect(winSize.x-16-64, buttonY, 64, buttonH)
IntRect(16, buttonY, 220, buttonH),
IntRect(winSize.x-16-80*2-8, buttonY, 80, buttonH),
IntRect(winSize.x-16-80, buttonY, 80, buttonH)
};
p->buttons.push_back(Button(p, btRects[0], "Reset defaults", &SMP::onResetToDefault));
p->buttons.push_back(Button(p, btRects[1], "Cancel", &SMP::onCancel));
p->buttons.push_back(Button(p, btRects[2], "Accept", &SMP::onAccept));
p->buttons.push_back(Button(p, btRects[0], findtext(TRSTR_KEYBIND_RESET, "Reset defaults"), &SMP::onResetToDefault));
p->buttons.push_back(Button(p, btRects[1], findtext(TRSTR_CANCEL, "Cancel"), &SMP::onCancel));
p->buttons.push_back(Button(p, btRects[2], findtext(TRSTR_ACCEPT, "Accept"), &SMP::onAccept));
for (size_t i = 0; i< p->buttons.size(); ++i)
p->widgets.push_back(&p->buttons[i]);
/* Labels */
const char *info = "Use left click to bind a slot, right click to clear its binding";
p->infoLabel = Label(p, IntRect(16, 16, winSize.x, 16), info, cText, cText, cText);
const char *info = findtext(TRSTR_KEYBIND_INSTRUCT, "Use left click to bind a slot, right click to clear its binding");
p->infoLabel = Label(p, IntRect(16, 16, winSize.x - 32, 16), info, cText, cText, cText);
const char *warn = "Warning: Same physical action bound to multiple slots";
p->dupWarnLabel = Label(p, IntRect(16, 40, winSize.x, 16), warn, 255, 0, 0);
const char *warn = findtext(TRSTR_KEYBIND_CONFLICT, "Warning: Same physical action bound to multiple slots");
p->dupWarnLabel = Label(p, IntRect(16, 40, winSize.x - 32, 16), warn, 255, 0, 0);
p->widgets.push_back(&p->infoLabel);
p->widgets.push_back(&p->dupWarnLabel);

52
src/trstr.h Normal file
View file

@ -0,0 +1,52 @@
#define TRSTR_EMPTY 0
#define TRSTR_JOURNAL_TITLE 1
#define TRSTR_KEYBIND_A 2
#define TRSTR_KEYBIND_B 3
#define TRSTR_KEYBIND_X 4
#define TRSTR_KEYBIND_Y 5
#define TRSTR_KEYBIND_BACK 6
#define TRSTR_KEYBIND_GUIDE 7
#define TRSTR_KEYBIND_START 8
#define TRSTR_KEYBIND_LSTICK 9
#define TRSTR_KEYBIND_RSTICK 10
#define TRSTR_KEYBIND_LSHOULDER 11
#define TRSTR_KEYBIND_RSHOULDER 12
#define TRSTR_KEYBIND_PADU 13
#define TRSTR_KEYBIND_PADD 14
#define TRSTR_KEYBIND_PADL 15
#define TRSTR_KEYBIND_PADR 16
#define TRSTR_KEYBIND_SHIFT 17
#define TRSTR_KEYBIND_UNK 18
#define TRSTR_KEYBIND_KEYFMT 19
#define TRSTR_KEYBIND_LSTICKL 20
#define TRSTR_KEYBIND_LSTICKR 21
#define TRSTR_KEYBIND_LSTICKU 22
#define TRSTR_KEYBIND_LSTICKD 23
#define TRSTR_KEYBIND_RSTICKL 24
#define TRSTR_KEYBIND_RSTICKR 25
#define TRSTR_KEYBIND_RSTICKU 26
#define TRSTR_KEYBIND_RSTICKD 27
#define TRSTR_KEYBIND_LTRIGGER 28
#define TRSTR_KEYBIND_RTRIGGER 29
#define TRSTR_KEYBIND_JOYBTTNFMT 30
#define TRSTR_KEYBIND_JOYHATFMT 31
#define TRSTR_KEYBIND_JOYAXISFMT 32
#define TRSTR_KEYBIND_KEYPROMPT 33
#define TRSTR_KEYBIND_TITLE 34
#define TRSTR_KEYBIND_RESET 35
#define TRSTR_CANCEL 36
#define TRSTR_ACCEPT 37
#define TRSTR_KEYBIND_INSTRUCT 38
#define TRSTR_KEYBIND_CONFLICT 39
#define TRSTR_KEYBIND_UP 40
#define TRSTR_KEYBIND_LEFT 41
#define TRSTR_KEYBIND_ACTION 42
#define TRSTR_KEYBIND_MENU 43
#define TRSTR_KEYBIND_CANCEL 44
#define TRSTR_KEYBIND_L 45
#define TRSTR_KEYBIND_DOWN 46
#define TRSTR_KEYBIND_RIGHT 47
#define TRSTR_KEYBIND_RUN 48
#define TRSTR_KEYBIND_DEACTIVATE 49
#define TRSTR_KEYBIND_ITEMS 50
#define TRSTR_KEYBIND_R 51