Last active
August 22, 2017 00:15
-
-
Save KyoPanda/e511af688867188800987161147a951d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*: | |
* @plugindesc | |
* Allows you assign variables to items, weapons or armors quantity in the | |
* party inventory before you open the Gameus Quest System's menu. | |
* | |
* @author Kyo Panda | |
* | |
* @param exportOnInit | |
* @text Export translation on initialization | |
* @desc | |
* Defines if the translation source should be exported as the game starts. | |
* @type boolean | |
* @default true | |
* | |
* @param addCommandToOptions | |
* @text Add command to options menu | |
* @desc Defines if the I18N option should be added to the options menu. | |
* @type boolean | |
* @default true | |
* | |
* @param menuOptions | |
* @text Menu options | |
* @desc Defines the languages that appears on the option menu. | |
* @type struct<MenuOptions>[] | |
* @default ["{\"locale\":\"en_US\",\"label\":\"English\"}"] | |
* | |
* @param extra | |
* @text Extra | |
* @desc Extra texts to be added to the source file. | |
* @type text[] | |
* @default ["Language", "ON", "OFF"] | |
* | |
* @help | |
* | |
* MIT License | |
* | |
* Copyright (c) 2017 Kyo Panda | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining | |
* a copy of this software and associated documentation files (the | |
* "Software"), to deal in the Software without restriction, including | |
* without limitation the rights to use, copy, modify, merge, publish, | |
* distribute, sublicense, and/or sell copies of the Software, and to | |
* permit persons to whom the Software is furnished to do so, subject to | |
* the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
/*~struct~MenuOptions: | |
* @param locale | |
* @text Locale | |
* @desc | |
* The language identifier used as the filename. | |
* Example: pt_BR | |
* @type text | |
* | |
* @param label | |
* @text Label | |
* @desc | |
* The text that appears in the menu. | |
* Example: Português | |
* @type text | |
*/ | |
(function() { | |
'use strict'; | |
var Imported = window.Imported || {}; | |
Imported.Kyo_I18N = true; | |
var Kyo = window.Kyo || {}; | |
Kyo.I18N = { | |
version: '1.0.0-beta' | |
}; | |
var $ = Kyo.I18N; | |
var _extends = function() { | |
var args = arguments; | |
var dest = args[0]; | |
for (var i = 1; i < args.length; i++) { | |
for (var key in args[i]) { | |
var value = args[i][key]; | |
if (value && value.constructor === Object) { | |
dest[key] = dest[key] || {}; | |
_extends(dest[key], value); | |
} else { | |
dest[key] = value; | |
} | |
} | |
} | |
return dest; | |
}; | |
var _objectify = function(arr) { | |
var obj = {}; | |
arr.forEach(function(value) { | |
if (!value) { | |
return; | |
} | |
obj[value] = ''; | |
}); | |
return obj; | |
}; | |
$.PARAMS = (function() { | |
var input = PluginManager.parameters('Kyo_I18N'); | |
var params = { | |
extra: _objectify(JSON.parse(input.extra) || []), | |
exportOnInit: input.exportOnInit === 'true', | |
addCommandToOptions: input.addCommandToOptions === 'true', | |
formatter: input.formatter || 'gettext', | |
urls: { | |
install: input.install || 'lang' | |
}, | |
menuOptions: [], | |
paths: {} | |
}; | |
JSON.parse(input.menuOptions || '[]').reduce(function(arr, curr) { | |
arr.push(JSON.parse(curr)); | |
return arr; | |
}, params.menuOptions); | |
if (Utils.isNwjs() && Utils.isOptionValid('test')) { | |
params.paths = (function() { | |
var path = require('path'); | |
var base = path.dirname(process.mainModule.filename); | |
var install = path.join(base, params.urls.install); | |
var data = path.join(base, 'data'); | |
return { | |
base: base, | |
install: install, | |
data: data | |
} | |
}()); | |
} | |
return params; | |
}()); | |
$.LanguageManager = function() { | |
throw new Error('Class can\'t be instantiated'); | |
}; | |
Object.defineProperty($.LanguageManager, 'formatter', { | |
get: function() { return this._formatter; }, | |
set: function(formatter) { this._formatter = formatter; }, | |
configurable: true | |
}); | |
$.LanguageManager._registered = {}; | |
$.LanguageManager.isBusy = function() { | |
return this._busy; | |
}; | |
$.LanguageManager.set = function(lang) { | |
if (this.isBusy()) { | |
return; | |
} | |
$gameSystem.locale = lang; | |
if (lang === $dataSystem.locale) { | |
this._source = {}; | |
return; | |
} | |
this._busy = true; | |
var xhr = new XMLHttpRequest(); | |
var urls = $.PARAMS.urls; | |
var url = [urls.install, lang].join('/'); | |
xhr.open('GET', [url, this._formatter.ext.main].join('.')); | |
xhr.onload = function() { | |
if (xhr.status < 400) { | |
this._source = this._formatter.decode(xhr.responseText); | |
} | |
this._busy = false; | |
}.bind(this); | |
xhr.onerror = function() { | |
this._busy = false; | |
}.bind(this);; | |
xhr.send(); | |
}; | |
$.LanguageManager.translate = function(text, domain) { | |
if (!this._source || !this._source[domain]) { | |
return text; | |
} | |
return this._source[domain][text] || text; | |
}; | |
$.LanguageManager.register = function(domain, data) { | |
if (!this._registered[domain]) { | |
this._registered[domain] = {}; | |
} | |
_extends(this._registered[domain], data); | |
}; | |
$.LanguageManager.export = function() { | |
if (!Utils.isNwjs() || !Utils.isOptionValid('test')) { | |
return; | |
} | |
var database; | |
database = $.DataManager.import(); | |
database = $.DataParser.parse(database); | |
database = _extends( | |
database, { Extra: $.PARAMS.extra }, $._registered | |
); | |
database = $.DataParser.clear(database); | |
database = this._formatter.encode(database); | |
$.DataManager.export(database); | |
}; | |
$.GettextFormatter = function() { | |
throw new Error('Class can\'t be instantiated'); | |
}; | |
$.GettextFormatter.ext = { | |
source: 'pot', | |
main: 'po' | |
}; | |
$.GettextFormatter.JSON_REGEXP = new RegExp([ | |
'msgctxt "([^"]*)"', | |
'msgid "([^"]*)"', | |
'msgstr "([^"]*)"\\n' | |
].join('\\n'), 'gi'); | |
$.GettextFormatter.encode = function(database) { | |
var text = [ | |
'msgid ""', | |
'msgstr ""', | |
'"MIME-Version: 1.0\\n"', | |
'"Content-Type: text/plain; charset=UTF-8\\n"', | |
'"Content-Transfer-Encoding: 8bit\\n"', | |
'', | |
'' | |
].join('\n'); | |
for (var domain in database) { | |
var data = database[domain]; | |
for (var key in data) { | |
text += [ | |
'msgctxt ' + JSON.stringify(domain), | |
'msgid ' + JSON.stringify(key), | |
'msgstr ""\n', | |
'' | |
].join('\n'); | |
} | |
} | |
return text; | |
}; | |
$.GettextFormatter.decode = function(database) { | |
var match; | |
var result = {}; | |
while ((match = this.JSON_REGEXP.exec(database)) !== null) { | |
var domain = match[1]; | |
var key = match[2]; | |
var value = match[3]; | |
result[domain] = result[domain] || {}; | |
result[domain][key] = value; | |
} | |
return result; | |
}; | |
$.JsonFormatter = function() { | |
throw new Error('Class can\'t be instantiated'); | |
}; | |
$.JsonFormatter.ext = { | |
source: 'json', | |
main: 'json' | |
}; | |
$.JsonFormatter.encode = function(database) { | |
return JSON.stringify(database, null, 4); | |
}; | |
$.JsonFormatter.decode = function(database) { | |
return JSON.parse(database); | |
}; | |
$.DataParser = function() { | |
throw new Error('Class can\'t be instantiated'); | |
}; | |
$.DataParser.MAPFILE_REGEXP = /map\d+/i; | |
$.DataParser.parse = function(database) { | |
var result = {}; | |
for (var domain in database) { | |
var data = database[domain]; | |
switch (domain) { | |
case 'Armors': | |
_extends(result, this.items(data, domain)); break; | |
case 'Classes': | |
_extends(result, this.items(data, domain)); break; | |
case 'CommonEvents': | |
_extends(result, this.pages(data, domain)); break; | |
case 'Enemies': | |
_extends(result, this.enemies(data, domain)); break; | |
case 'Items': | |
_extends(result, this.items(data, domain)); break; | |
case 'MapInfos': | |
_extends(result, this.items(data, domain)); break; | |
case 'Skills': | |
_extends(result, this.skills(data, domain)); break; | |
case 'States': | |
_extends(result, this.states(data, domain)); break; | |
case 'Animations': | |
_extends(result, this.items(data, domain)); break; | |
case 'Weapons': | |
_extends(result, this.items(data, domain)); break; | |
case 'System': | |
_extends(result, this.system(data, domain)); break; | |
case 'Troops': | |
_extends(result, this.troops(data, domain)); break; | |
default: | |
if (this.MAPFILE_REGEXP.test(domain)) { | |
_extends(result, this.events(data.events, domain)); | |
} | |
} | |
} | |
return result; | |
}; | |
$.DataParser.clear = function(database) { | |
for (var domain in database) { | |
var data = database[domain]; | |
for (var key in data) { | |
if (!key) { | |
delete data[key]; | |
} | |
} | |
} | |
return database; | |
}; | |
$.DataParser.events = function(data, domain) { | |
var result = {}; | |
data.forEach(function(event) { | |
if (event === null) { | |
return; | |
} | |
_extends(result, this.pages(event.pages, domain)); | |
}, this); | |
return result; | |
}; | |
$.DataParser.pages = function(data, domain) { | |
var commands = [102, 401, 405]; | |
var result = {}; | |
result[domain] = {}; | |
data.forEach(function(page) { | |
if (page === null) { | |
return; | |
} | |
page.list.forEach(function(command) { | |
if (commands.indexOf(command.code) === -1) { | |
return; | |
} | |
if (command.code === 102) { | |
command.parameters[0].forEach(function(param) { | |
result[domain][param] = ''; | |
}, this); | |
return; | |
} | |
command.parameters.forEach(function(param) { | |
result[domain][param] = ''; | |
}); | |
}, this); | |
}, this); | |
return result; | |
}; | |
$.DataParser.items = function(data, domain) { | |
var result = {}; | |
result[domain] = {}; | |
data.forEach(function(item) { | |
if (item === null) { | |
return; | |
} | |
result[domain][item.name] = ''; | |
if (item.description) { | |
result[domain][item.description] = ''; | |
} | |
}, this); | |
return result; | |
}; | |
$.DataParser.enemies = function(data, domain) { | |
var result = {}; | |
result[domain] = {}; | |
data.forEach(function(enemy) { | |
if (enemy !== null) { | |
result[domain][enemy.battlerName] = ''; | |
} | |
}, this); | |
return result; | |
}; | |
$.DataParser.skills = function(data, domain) { | |
var result = this.items(data, domain); | |
data.forEach(function(skill) { | |
if (skill === null) { | |
return; | |
} | |
if (skill.message1) { | |
result[domain][skill.message1] = ''; | |
} | |
if (skill.message2) { | |
result[domain][skill.message2] = ''; | |
} | |
}, this); | |
return result; | |
}; | |
$.DataParser.states = function(data, domain) { | |
var result = this.skills(data, domain); | |
data.forEach(function(state) { | |
if (state === null) { | |
return; | |
} | |
if (state.message3) { | |
result[domain][state.message3] = ''; | |
} | |
if (state.message4) { | |
result[domain][state.message4] = ''; | |
} | |
}, this); | |
return result; | |
}; | |
$.DataParser.system = function(data, domain) { | |
var result = {}; | |
result[domain + '_Types.Armors'] = _objectify(data.armorTypes); | |
result[domain + '_Types.Elements'] = _objectify(data.elements); | |
result[domain + '_Types.Equips'] = _objectify(data.equipTypes); | |
result[domain + '_Types.Skills'] = _objectify(data.skillTypes); | |
result[domain + '_Types.Weapons'] = _objectify(data.weaponTypes); | |
var terms = data.terms; | |
result[domain + '_Terms.Basic'] = _objectify(terms.basic); | |
result[domain + '_Terms.Commands'] = _objectify(terms.commands); | |
result[domain + '_Terms.Params'] = _objectify(terms.params); | |
result[domain + '_Terms.Messages'] = {}; | |
for (var key in terms.messages) { | |
result[domain + '_Terms.Messages'][terms.messages[key]] = ''; | |
} | |
return result; | |
}; | |
$.DataParser.troops = function(data, domain) { | |
return _extends( | |
this.items(data, domain), | |
this.events(data, domain) | |
); | |
} | |
$.DataManager = function() { | |
throw new Error('Class can\'t be instantiated'); | |
}; | |
$.DataManager.import = function() { | |
var fs = require('fs'); | |
var path = require('path'); | |
var dir = $.PARAMS.paths.data; | |
return fs.readdirSync(dir).reduce(function(database, filename) { | |
var ext = path.extname(filename); | |
if (ext !== '.json') { | |
return database; | |
} | |
var contents = fs.readFileSync(path.join(dir, filename)); | |
var basename = path.basename(filename, ext); | |
database[basename] = JSON.parse(contents); | |
return database; | |
}, {}); | |
}; | |
$.DataManager.export = function(data) { | |
var fs = require('fs'); | |
var path = require('path'); | |
var install = $.PARAMS.paths.install; | |
install.split(path.sep).reduce(function(base, dir) { | |
var curr = path.join(base, dir); | |
if (!fs.existsSync(curr)) { | |
fs.mkdirSync(curr); | |
} | |
return curr; | |
}, ''); | |
var output = path.join($.PARAMS.paths.install, $dataSystem.locale); | |
var ext = $.LanguageManager.formatter.ext.source; | |
fs.writeFileSync([output, ext].join('.'), data); | |
}; | |
var _Scene_Title_initialize = Scene_Title.prototype.initialize; | |
Scene_Title.prototype.initialize = function() { | |
switch ($.PARAMS.formatter) { | |
case 'json': | |
$.LanguageManager.formatter = $.JsonFormatter; | |
break; | |
default: | |
$.LanguageManager.formatter = $.GettextFormatter; | |
} | |
if ($.PARAMS.exportOnInit) { | |
$.LanguageManager.export(); | |
} | |
_Scene_Title_initialize.apply(this, arguments); | |
}; | |
var _Game_System_initialize = Game_System.prototype.initialize; | |
Game_System.prototype.initialize = function() { | |
this._locale = $dataSystem.locale; | |
_Game_System_initialize.apply(this, arguments); | |
}; | |
Object.defineProperty(Game_System.prototype, 'locale', { | |
get: function() { return this._locale; }, | |
set: function(locale) { this._locale = locale; }, | |
configurable: true | |
}); | |
if ($.PARAMS.addCommandToOptions) { | |
var _Window_Options_initialize = Window_Options.prototype.initialize; | |
Window_Options.prototype.initialize = function() { | |
this._languageIndex = 0; | |
this._languageOptions = $.PARAMS.menuOptions.reduce( | |
function(arr, curr, index) { | |
arr.push(curr.label); | |
if (curr.locale === $gameSystem.locale) { | |
this._languageIndex = index; | |
} | |
return arr; | |
}.bind(this), [] | |
); | |
return _Window_Options_initialize.apply(this, arguments); | |
}; | |
Window_Options.prototype.languageLocale = function() { | |
var label = this._languageOptions[this._languageIndex]; | |
var locale = $gameSystem.locale; | |
for (var key in $.PARAMS.menuOptions) { | |
var data = $.PARAMS.menuOptions[key]; | |
if (data.label === label) { | |
locale = data.locale; | |
break; | |
} | |
} | |
return locale; | |
}; | |
Window_Options.prototype.isLanguageSymbol = function(symbol) { | |
return symbol === 'language'; | |
}; | |
var _Window_Options_makeCommandList = | |
Window_Options.prototype.makeCommandList | |
; | |
Window_Options.prototype.makeCommandList = function() { | |
_Window_Options_makeCommandList.apply(this, arguments); | |
var text = $.LanguageManager.translate('Language', 'Extra'); | |
this.addCommand(text, 'language'); | |
}; | |
var _Window_Options_statusText = Window_Options.prototype.statusText; | |
Window_Options.prototype.statusText = function(index) { | |
var symbol = this.commandSymbol(index); | |
if (!this.isLanguageSymbol(symbol)) { | |
return _Window_Options_statusText.apply(this, arguments); | |
} | |
var index = this._languageIndex; | |
return this._languageOptions[index] || 'Default'; | |
}; | |
Window_Options.prototype.changeLanguage = function(increment) { | |
this._languageIndex += increment; | |
if (this._languageIndex >= this._languageOptions.length) { | |
this._languageIndex = 0; | |
} else if (this._languageIndex < 0) { | |
this._languageIndex = this._languageOptions.length - 1; | |
} | |
var symbol = this.commandSymbol(this.index()); | |
this.redrawItem(this.findSymbol(symbol)); | |
SoundManager.playCursor(); | |
}; | |
var _Window_Options_processOk = Window_Options.prototype.processOk; | |
Window_Options.prototype.processOk = function() { | |
var symbol = this.commandSymbol(this.index()); | |
if (!this.isLanguageSymbol(symbol)) { | |
return _Window_Options_processOk.apply(this, arguments); | |
} | |
this.changeLanguage(1); | |
}; | |
var _Window_Options_cursorRight = Window_Options.prototype.cursorRight; | |
Window_Options.prototype.cursorRight = function(wrap) { | |
var symbol = this.commandSymbol(this.index()); | |
if (!this.isLanguageSymbol(symbol)) { | |
return _Window_Options_cursorRight.apply(this, arguments); | |
} | |
this.changeLanguage(1); | |
}; | |
var _Window_Options_cursorLeft = Window_Options.prototype.cursorLeft; | |
Window_Options.prototype.cursorLeft = function(wrap) { | |
var symbol = this.commandSymbol(this.index()); | |
if (!this.isLanguageSymbol(symbol)) { | |
return _Window_Options_cursorLeft.apply(this, arguments); | |
} | |
this.changeLanguage(-1); | |
}; | |
var _Scene_Options_isBusy = Scene_Options.prototype.isBusy; | |
Scene_Options.prototype.isBusy = function() { | |
return ( | |
$.LanguageManager.isBusy() || | |
_Scene_Options_isBusy.apply(this, arguments) | |
); | |
}; | |
var _Scene_Options_update = Scene_Options.prototype.update; | |
Scene_Options.prototype.update = function() { | |
if (Input.isRepeated('cancel')) { | |
var locale = this._optionsWindow.languageLocale(); | |
if (locale !== $gameSystem.locale) { | |
$.LanguageManager.set(locale); | |
} | |
} | |
_Scene_Options_update.apply(this, arguments); | |
}; | |
} | |
var _TextManager_basic = TextManager.basic; | |
TextManager.basic = function(basicId) { | |
var text = _TextManager_basic.apply(this, arguments); | |
return $.LanguageManager.translate(text, 'System_Terms.Basic'); | |
}; | |
var _TextManager_param = TextManager.param; | |
TextManager.param = function(paramId) { | |
var text = _TextManager_param.apply(this, arguments); | |
return $.LanguageManager.translate(text, 'System_Terms.Params'); | |
}; | |
var _TextManager_command = TextManager.command; | |
TextManager.command = function(commandId) { | |
var text = _TextManager_command.apply(this, arguments); | |
return $.LanguageManager.translate(text, 'System_Terms.Commands'); | |
}; | |
var _TextManager_message = TextManager.message; | |
TextManager.message = function(messageId) { | |
var text = _TextManager_message.apply(this, arguments); | |
return $.LanguageManager.translate(text, 'System_Terms.Messages'); | |
}; | |
var _Window_Options_booleanStatusText = | |
Window_Options.prototype.booleanStatusText | |
; | |
Window_Options.prototype.booleanStatusText = function(value) { | |
var text = _Window_Options_booleanStatusText.apply(this, arguments); | |
return $.LanguageManager.translate(text, 'Extra'); | |
}; | |
var _Game_Message_add = Game_Message.prototype.add; | |
Game_Message.prototype.add = function(text) { | |
var domain; | |
var newText = text; | |
var scene = SceneManager._scene; | |
if (scene instanceof Scene_Map) { | |
domain = 'Map%1'.format($gameMap.mapId().toString(16).padZero(3)); | |
} | |
if (domain) { | |
newText = $.LanguageManager.translate(text, domain); | |
} | |
_Game_Message_add.call(this, newText); | |
}; | |
window.Imported = Imported; | |
window.Kyo = Kyo; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment