//============================================================================= // Plugin: External Text // Author: Zalerinian // Version: 1.2.1 // License: http://creativecommons.org/licenses/by/4.0/ //============================================================================= /*: * @plugindesc Use external files to load all the text in your game! Convenient for multi-language support! * @author Zalerinian * * @param Text File * @desc The default text file to load into the game. * Default: text_en.json * @default text_en.json * * @param Face File * @desc The default file to load for predefined faces. This file should be in the text folder. Default: faces.json * @default faces.json * * @param Text Folder * @desc The folder to keep your text file(s). Make sure this folder exists! Default: data/text/ * @default data/text/ * * @param Autofit Text * @desc Automatically resize text to fit on the screen. * @default true * * @param Remember Color * @desc Remember the last text color used in a conversation, in case the line wrapping puts it on a new page. * @default true * * @param Enable Name Window * @desc Enable or disable the name window from being created. Set this to false if you don't intend to use the name window. * @default true * * @param Name Window Margin * @desc Code that returns the number of pixels there should be between the name window and side of the game screen. * @default return Graphics.width / 5 - this.width / 2 * * @param No Text Warning * @desc This string will be returned if there is no text file currently loaded. * @default No text file is loaded! * * @param Asynchronous Loading * @desc Load files apart from the game loop? * @default true * * @param Choice Variable * @desc A variable used to store the index of the selected choice. Default: 1 * @default 1 * * @param Number Variable * @desc A variable used to store the value of the inputted number. Default: 2 * @default 2 * * @param Item Variable * @desc A variable used to store the item ID of the selected item, or 0 on cancel. Default: 3 * @default 3 * * @help * ============================================================================= * Introduction * ============================================================================= * * The external text script will allow you to take all the text outside of the * game editor, and put it in a nicely-formatted JSON file. To learn more about * the JSON format, online resources are available to show how to use it. For * example, https://en.wikipedia.org/wiki/JSON#Samples * * This plugin is an MV edition of Enelvon's popular External Text script for * RPG Maker VX Ace. * * ============================================================================= * Asynchronous Loading * ============================================================================= * * If this parameter is true, then files will be loaded asynchronously from the * game, meaning that the game will continue running without waiting for the * file to finish loading. This will improve game performance, as the game won't * have to wait for the files to load in before continuing. However, this also * means that the text or face data won't be accessible until after the loading * is complete, which could possibly cause some issues early on in the game, * and whenever the text file is changed. * * ============================================================================= * Using faces * ============================================================================= * * The External text plugin allows you to define a face to use with each bit of * text. In text file, in the key you wish to set up, simply add a "face" * section, with a set of curly braces( {} ) as the value. Inside these curly * braces, you must define the type (actor, party, or predefined), the ID for * the selected types (Actor and Party must be numbers, predefined depends on * they key set in the faces file). The ID for Actor and Party starts at 1. * Additionally, you must also supply an index used to determine which face in * the faceset to use. Indexes range from 0-7. * * ============================================================================= * Controlling the window * ============================================================================= * * In order to control the position and appearance of the text window, you need * to add a "window" section. In this section, you can define values for the * "background" and "position" fields. The values for these are the same as * those you would set in the editor. * * For example, "background" can be set to "dim" or "transparent" for the black * background, or no background respectively. Any other values will result in * the window looking like a regular window. The values are case-insensitive. * * ============================================================================= * Additional Inputs * ============================================================================= * * Because the full effects of the External Text script, to control faces, * position, and appearance, all come from a plugin command or call, the plugin * also includes controls for choice input, number input, and item selection. * * ============================================================================= * Setting up the choice window * ============================================================================= * * To use a choice window with a text key, the first step is to add a "choice" * field to your text file. This will hold the settings for the choice window. * The choice window supports the same values for "background" and "position" * that the regular window has. In addition, the choice window requires at * least "choice" and "variable" properties, with optional "default" and * "cancel" properties to define which what the default selection is, and what * happens if the user cancels the selection. * * The choice variable setting for the plugin refers to a variable that will * hold the index of the selected choice. Indexes start at 0, and range to * - 1. * Because the choice input is not set up directly in the editor, this variable * must be used in conditional branches so that you can perform different * actions based on the selected choice. * * The "choice" property should be an array of string values, holding the * text for each choice. By default, RPG Maker MV only supports 6 choices in a * choice selection. With External Text, however, there is no limit to the * number of choices. * * The "default" property is the index (starting at 0) that will be highlighted * by default. * * The "cancel" property is the index of the action to use when the selection is * cancelled by the player. A value of -1 will disallow the player from * cancelling the selection. * * If the "cancel" property is a valid value that allows the user to cancel the * selection (any value from 0 to the - 1), and the user * cancels the selection, this is the index that will be selected. * * ============================================================================= * Setting up the number input window * ============================================================================= * * To set up a number input, the text key must have a "number" section with at * least a "variable" and "digits" properties. There is an optional "dvar" * property that may be used if the "digits" property is set to "variable" * * The number variable setting is the variable ID that will store the value of * the number inputted. * * The "digits" field can be either a number, representing the number of digits * that may be inputted, or the string "variable", indicating that the number * of digits to be used can be found in a variable, with the ID stored in the * "dvar" property. * * The "dvar" property is used when the "digits" property is set to "variable". * "dvar" should be a variable ID that will hold the number of digits that may * be inputted. * * ============================================================================= * Setting up the item selection window * ============================================================================= * * Finally, the item input event command is also available. To use it, the text * key must have a "number" section. There is only one available option * for the item selection command, "type". * * The item variable setting is a variable ID that will hold the item ID, found * in the database, after an item is picked, or 0 if the user cancels the * selection. * * The "type" property is a string that may contain either "regular", "key", * "hidden a", or "hidden b". These are all item types that are available in the * engine by default. If you don't know what "hidden a" or "hidden b" are, * please check the engine help file, as these are new. * */ var Imported = Imported || {}; var Zale = Zale || {}; Zale.ExtText = Zale.ExtText || {}; (function(){ if(Imported["MVCommons"] && PluginManager.version("MVCommons", ">=", "1.0.3")) { var author = [{ email: "support@razelon.com", name: "Zalerinian", website: "http://www.razelon.com" }]; var v = PluginManager.register("ExternalText", "1.2.1", PluginManager.getBasicPlugin("ExternalText").description, author, "2016-3-15", ["MVCommons"], true); if(v === undefined) { throw new Error("Unable to load ExternalText due to mising dependencies!"); } else if (v === false){ PluginManager.printPlugin("ExternalText") throw new Error("Unable to load ExternalText due to registration failure! Is there another version running?"); } } else { SceneManager.stop(); throw new Error("External Text requires some functionality of the MVCommons plugin!"); } })(); (function($){ "use strict"; // ========================================================================== // // Parameter Setup // Sets up the parameters of the plugin and stores them in the ExtText // section of the Zale object. // // ========================================================================== var params = PluginManager.parameters("ExtText"); Zale.ExtText.PARAMETERS = params; Zale.ExtText.TEXTFILE = params["Text File"]; Zale.ExtText.TEXTFOLDER = params["Text Folder"]; Zale.ExtText.FACEFILE = params["Face File"]; Zale.ExtText.CHOICEVAR = params["Choice Variable"]; Zale.ExtText.ITEMVAR = params["Item Variable"]; Zale.ExtText.NUMVAR = params["Number Variable"]; Zale.ExtText.AUTOFIT = MVC.Boolean(params["Autofit Text"]); Zale.ExtText.REMCOLOR = MVC.Boolean(params["Remember Color"]) Zale.ExtText.NAMEENABLED = MVC.Boolean(params["Enable Name Window"]); Zale.ExtText.NAMEMARGIN = Function(params["Name Window Margin"]); Zale.ExtText.NOTEXTWARN = params["No Text Warning"]; Zale.ExtText.LOADASYNC = MVC.Boolean(params["Asynchronous Loading"]); Zale.ExtText.lastColor = "#ffffff"; // ========================================================================== // // String.prototype.endsWith Polyfill // This block of code ensures that if the browser using this script doesn't // support the .endsWith function, that it will be made compatible by // adding out own implementation of the function. // // ========================================================================== if (!String.prototype.endsWith) { String.prototype.endsWith = function(searchString, position) { var subjectString = this.toString(); if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { position = subjectString.length; } position -= searchString.length; var lastIndex = subjectString.indexOf(searchString, position); return lastIndex !== -1 && lastIndex === position; }; } /** * ========================================================================== * * Game_System.prototype.initialize() * * @note * Sets the default text and face files, and then loads them using * their respective methods. * * ========================================================================== */ Zale.ExtText.GSYS_init_TEng2kfuj = Game_System.prototype.initialize; Game_System.prototype.initialize = function() { Zale.ExtText.GSYS_init_TEng2kfuj.call(this); this._textFile = Zale.ExtText.TEXTFILE; this._faceFile = Zale.ExtText.FACEFILE; } /** * ========================================================================== * * Game_System.prototype.textFile * * @note * Defines the getters and setters for the textFile property of Game_System. * This does not change the file loaded, and only the file to load when * loading a save. This is called internally by TextManager.loadTextFile. * * ========================================================================== */ Object.defineProperty(Game_System.prototype, "textFile", { get: function() { return this._textFile; }, set: function(value) { this._textFile = value; }, configurable: true }); /** * ========================================================================== * Game_System.prototype.faceFile * * @note * Defines the getters and setters for the faceFile property of Game_System. * This doesn't change the faces loaded, only the file to load when loading * a save. The faces file outlines the predefined faces that may be used * with text keys, and can easily be switched to a different file for * dynamic character costumes. This is called internally by * TextManager.loadFaceFile. * * ========================================================================== */ Object.defineProperty(Game_System.prototype, "faceFile", { get: function() { return this._faceFile; }, set: function(value) { this._faceFile = value; }, configurable: true }); // ========================================================================== // DataManager // ========================================================================== /** * ========================================================================== * * DataManager.loadGameWithoutRescue() * * @note * Loads the sotred text and face files on load so that the data is ready * to go once a game is loaded! * * ========================================================================== */ Zale.ExtText.DM_lgwr_RTVIOwnoSNC4b9 = DataManager.loadGameWithoutRescue; DataManager.loadGameWithoutRescue = function(id) { var r = Zale.ExtText.DM_lgwr_RTVIOwnoSNC4b9.call(this, id); if(!r) { return r; } if(typeof $gameSystem.textFile !== 'string') { $gameSystem.textFile = Zale.ExtText.TEXTFILE; } if(typeof $gameSystem.faceFile !== 'string') { $gameSystem.faceFile = Zale.ExtText.FACEFILE; } TextManager.loadTextFile($gameSystem.textFile); TextManager.loadFaceFile($gameSystem.faceFile); return true; } /** * ========================================================================== * * DataManager.createGameObjects() * * @note * Aliases the createGameObjects function to also load in the default * text and face files into $gameSystem. * * ========================================================================== */ Zale.ExtText.DM_cgo_vpioivnOIEUV5 = DataManager.createGameObjects; DataManager.createGameObjects = function() { Zale.ExtText.DM_cgo_vpioivnOIEUV5.call(this); TextManager.loadTextFile($gameSystem.textFile); TextManager.loadFaceFile($gameSystem.faceFile); } // ========================================================================== // Window Message // ========================================================================== /** * ========================================================================== * * Window_Base.prototype.convertEscapeCharacters(string text) * * @note * This aliased function is responsible for replacing the \t[key] text codes * with the text from the given key. * * ========================================================================== */ Zale.ExtText.WBase_cec_VNOCxoiwrv1 = Window_Base.prototype.convertEscapeCharacters Window_Base.prototype.convertEscapeCharacters = function(text) { text = Zale.ExtText.WBase_cec_VNOCxoiwrv1.call(this, text); text = text.replace(/\x1bt\[(.+?)\]/gi, function(){ return TextManager.text(arguments[1]); }); return text } /* * Window_Base.prototype.drawItemName(item, x, y, width) * @param item The item we're drawing the name of. * @param {Number} x The x position to draw at. * @param {Number} y The y position to draw at. * @param {Number} width The max width to draw the name with. * @note * This function is aliased to ensure that if the name is a text key, we can * replace it with the correct value. */ Zale.ExtText.WB_din = Window_Base.prototype.drawItemName; Window_Base.prototype.drawItemName = function(item, x, y, width) { if(item) { item.name = item.name.replace(/\\t\[(.+?)\]/gi, function(m, k) { return TextManager.text(k); }); } Zale.ExtText.WB_din.call(this, item, x, y, width); } /** * ========================================================================== * * Window_Message.prototype.createSubWindows() * * @note * Aliases the createSubWindows method to additionally call the * createNameWindow function if the name window is enabled. * * ========================================================================== */ Zale.ExtText.WMessage_csw_OIcnblwkCn2rrc = Window_Message.prototype.createSubWindows; Window_Message.prototype.createSubWindows = function() { Zale.ExtText.WMessage_csw_OIcnblwkCn2rrc.call(this); if(Zale.ExtText.NAMEENABLED){ this.createNameWindow(); } } /** * ========================================================================== * * Window_Message.prototype.updatePlacement() * * @note * Aliases the updatePlacement function to also call the name subwindow's * "proprietary" updatePlacement function, but only if the name window is * enabled. * * ========================================================================== */ Zale.ExtText.WMessage_uplace_YGWfgcognvop42nc = Window_Message.prototype.updatePlacement; Window_Message.prototype.updatePlacement = function() { Zale.ExtText.WMessage_uplace_YGWfgcognvop42nc.call(this); if(Zale.ExtText.NAMEENABLED) { this._nameWindow.updatePlacement(this); } } /** * ========================================================================== * * Window_Message.prototype.terminateMessage() * * @note * Aliases the terminateMessage function to also close the name subwindow, * if the name window is enabled. * * ========================================================================== */ Zale.ExtText.WMessage_term_ZNGIOiwofnoizr222cn = Window_Message.prototype.terminateMessage; Window_Message.prototype.terminateMessage = function() { Zale.ExtText.WMessage_term_ZNGIOiwofnoizr222cn.call(this); if(Zale.ExtText.NAMEENABLED){ this._nameWindow.close(); } } /** * ========================================================================== * * Window_Message.prototype.startMessage() * * @note * Aliases the startMessage function to check if Autofit Text should be * enabled. If Autofit is enabled, the text in the textState object is * set to the text returned by the TextManager.resizeText function. * * ========================================================================== */ Zale.ExtText.WMessage_startm_NIOVnoind = Window_Message.prototype.startMessage; Window_Message.prototype.startMessage = function() { Zale.ExtText.WMessage_startm_NIOVnoind.call(this); if(Zale.ExtText.AUTOFIT) { var lines = TextManager.resizeText(this._textState.text, this.contentsWidth() - this._textState.left) this._textState.text = lines.join("\n"); } } /** * ========================================================================== * Window_Message.prototype.changeTextColor(string color) * * @note * Aliases the changeTextColor function in Window_Message. In addition to * its regular duties, if the Remember Color option was set to true in the * plugin's configuration, this will set the value Zale.ExtText.lastcolor * in order to retain the last color used in text pages. * * ========================================================================== */ Zale.ExtText.WMessage_ctc_IONciowvn8hnanovi = Window_Message.prototype.changeTextColor; Window_Message.prototype.changeTextColor = function(color) { if(Zale.ExtText.REMCOLOR) { Zale.ExtText.lastColor = this.contents.textColor; } Zale.ExtText.WMessage_ctc_IONciowvn8hnanovi.call(this, color); } /** * ========================================================================== * Window_Message.prototype.resetFontSettings() * * @note * Aliases the resetFontSettings function. After resetting all the font * settings to their defaults, the alias will check if the last text color * was remembered. If it was, the window's text color will be set to the * last color that was stored in the settings. * * ========================================================================== */ Zale.ExtText.WMessage_rfs_NOIsionwiocn240 = Window_Message.prototype.resetFontSettings; Window_Message.prototype.resetFontSettings = function() { Zale.ExtText.WMessage_rfs_NOIsionwiocn240.call(this); if(Zale.ExtText.REMCOLOR) { this.contents.textColor = Zale.ExtText.lastColor; } } /** * ========================================================================== * Window_Message.prototype.processEscapeCharacter(string code, * object textState) * * @note * Aliases the processEscapeCharacter function. This alias allows you to * set the name in the name window in the text. This will only have an * affect if the name window is enabled. * * ========================================================================== */ Zale.ExtText.WMessage_pec_NOCionoi2rgnioo = Window_Message.prototype.processEscapeCharacter; Window_Message.prototype.processEscapeCharacter = function(code, textState) { if(Zale.ExtText.NAMEENABLED && code.toLowerCase() === 'n') { var substr = textState.text.substring(textState.index); if(/<([.\s\S]*?)>/m.test(substr)) { var match = /<([.\s\S]*?)>/m.exec(substr); textState.index += match[0].length; this.setName(this.convertEscapeCharacters(match[1])); } } Zale.ExtText.WMessage_pec_NOCionoi2rgnioo.call(this, code, textState); } /** * ========================================================================== * Window_Message.prototype.newPage(object textState) * * @note * If the return value of Game_Message.prototype.characterName (defined * below) is not null, and the name window exists, then we set the name * for the name window here. * * ========================================================================== */ Zale.ExtText.WMessage_npage_NCOWOFNdoon = Window_Message.prototype.newPage; Window_Message.prototype.newPage = function(textState) { Zale.ExtText.WMessage_npage_NCOWOFNdoon.call(this, textState); if(this._nameWindow && $gameMessage.characterName()) { this.setName($gameMessage.characterName()); } } /** * ========================================================================== * Window_Message.prototype.createNamewindow() * * @note * Creates the name window and sets its initial position based on the * message window's. The window is added as a separate child from the * window layer, because the name window overlaps the message window, and * this can cause issues with windowskins that have rounded corners, as the * transparent pixels on the corners would overwrite the windows drawn * before. * This is an issue directly with Pixi.js, and thus no easy solution is * available. * * ========================================================================== */ Window_Message.prototype.createNameWindow = function() { this._nameWindow = new Window_Help(1); this._nameWindow.openness = 0; this._nameWindow.updatePlacement = function(parent) { this.x = Zale.ExtText.NAMEMARGIN.bind(this)(); if(parent.y > 0) { this.y = parent.y - this.height / 1.5; } else { this.y = parent.height - this.height / 1.5; } } SceneManager._scene.addChild(this._nameWindow); } /** * ========================================================================== * Window_Message.prototype.closeName() * * @note * If the name window exists, it is closed using Window_Base's close * function. This provides us with the little closing animation. * * ========================================================================== */ Window_Message.prototype.closeName = function() { if(this._nameWindow){ this._nameWindow.close(); } } /** * ========================================================================== * Window_Message.prototype.setName(string name) * * @note * If the messae window exists, this function sets its text to the given * string, and resizes and repositions the window to accomodate the text. * * ========================================================================== */ Window_Message.prototype.setName = function(name) { if(this._nameWindow){ this._nameWindow.width = this._nameWindow.textWidth(name) + 8 + this.padding * 2; this._nameWindow.setText(name); this._nameWindow.updatePlacement(this); this._nameWindow.open(); } } // ========================================================================== // Game Message // ========================================================================== /** * ========================================================================== * * Game_Message.prototype.clear() * * @note * Aliases Game_Message's clear method. This sets the _characterName * property to null, signalling that there should be no name window * present with the current message. * * ========================================================================== */ Zale.ExtText.GMessage_clr_Zoqbop429dncqnf = Game_Message.prototype.clear; Game_Message.prototype.clear = function() { Zale.ExtText.GMessage_clr_Zoqbop429dncqnf.call(this); this._characterName = null; } /** * ========================================================================== * * Game_Message.prototype.setCharacterName(string name) * * @note * Sets the _characterName property to the given string, which will be * displayed in the name window, if it is enabled. * * ========================================================================== */ Game_Message.prototype.setCharacterName = function(name) { this._characterName = name; } /** * ========================================================================== * * Game_Message.prototype.characterName() * * @note * Returns the current calue of the _characterName property. * * @return A string containing the current name for the name window. * * ========================================================================== */ Game_Message.prototype.characterName = function() { return this._characterName; } // ========================================================================== // Game Interpeter // ========================================================================== /** * ========================================================================== * * Game_Inptereter.prototype.pluginCommand() * * @note * Allows the game developer to show text by using a plugin command * starting with ExternalText, with the first argument being the text key * to display. * * ========================================================================== */ Zale.ExtText.GI_pcom_OISqs1cdkjz = Game_Interpreter.prototype.pluginCommand; Game_Interpreter.prototype.pluginCommand = function(command, args) { Zale.ExtText.GI_pcom_OISqs1cdkjz.call(this, command, args); if(command.match(/External[_-]*Text/i)) { if(args.length > 0){ if(args[0].toLowerCase() == "show") { TextManager.displayMessage(args.slice(1).join(" ")); this.setWaitMode('message'); } else if(args[0].toLowerCase() == "load") { if(args[1] == "text") { TextManager.loadTextFile(args.slice(2).join(" ")); } else if(args[1] == "face") { TextManager.loadFaceFile(args.slice(2).join(" ")); } } } } } /** * ========================================================================== * * Game_Interpreter.prototype.showText() * * @note * A method to add to the Game_Interpretter class so as to give people who * prefer the old way of interacting with plugins a way to use the * External Text script. * * * ========================================================================== */ Game_Interpreter.prototype.showText = function(key) { TextManager.displayMessage(key); this.setWaitMode('message'); } // ========================================================================== // TextManager // ========================================================================== /* * TextManager.basic(id) * @param {Number} id The basic text id. * @note * Aliases this function to return the term with any text keys replaced. */ Zale.ExtText.TM_basic = TextManager.basic; $.basic = function(basicId) { return Zale.ExtText.TM_basic.call(this, basicId).replace(/\\t\[(.+?)\]/gi, function(m, k) { return TextManager.text(k); }) || ''; }; /* * TextManager.param(id) * @param {Number} id The param text id. * @note * Aliases this function to return the term with any text keys replaced. */ Zale.ExtText.TM_param = TextManager.param; $.param = function(paramId) { return Zale.ExtText.TM_param.call(this, paramId).replace(/\\t\[(.+?)\]/gi, function(m, k) { return TextManager.text(k); }) || ''; }; /* * TextManager.command(id) * @param {Number} id The command text id. * @note * Aliases this function to return the term with any text keys replaced. */ Zale.ExtText.TM_command = TextManager.command; $.command = function(commandId) { return Zale.ExtText.TM_command.call(this, commandId).replace(/\\t\[(.+?)\]/gi, function(m, k) { return TextManager.text(k); }) || ''; }; /* * TextManager.message(id) * @param {Number} id The message text id. * @note * Aliases this function to return the term with any text keys replaced. */ Zale.ExtText.TM_message = TextManager.message; $.message = function(messageId) { return Zale.ExtText.TM_message.call(this, messageId).replace(/\\t\[(.+?)\]/gi, function(m, k) { return TextManager.text(k); }) || ''; }; /** * ========================================================================== * * TextManager.resizeText(string text, int maxWidth, [bitmap measure]) * * @param text The text to resize * @param maxWidth The max width that the text should fit in * @param measure A bitmap with which to meaure text size. Optional. * * @note * Takes the given text and resizes it by splitting it by word, or letter * if absolutely needed, to fit within the given width. The result is * returned as an array. * * @return An array of strings. * * ========================================================================== */ $.resizeText = function(text, maxWidth, measure) { if(!maxWidth) { throw new Error("No max width given!"); } if(!(measure instanceof Bitmap)) { measure = new Bitmap(1, 1); } var words = text.split(" "); var lines = []; var line = ""; var length = 0; for(var i = 0; i < words.length; i++) { var word = words[i]; if(measure.measureTextWidth(this.realText(word)) > maxWidth) { for(var j = 0; j < word.length; j++) { if(length + measure.measureTextWidth(this.realText(word[j]) + "-") > maxWidth) { lines.push(line + "-"); line = word[j]; length = measure.measureTextWidth(this.realText(line)); } else { length += measure.measureTextWidth(this.realText(word[j])); line += word[j]; if(word[j] === '\n') { length = 0; } } } } else if(length + measure.measureTextWidth(this.realText(word) + " ") > maxWidth) { lines.push(line.trim()); line = word + " "; length = measure.measureTextWidth(this.realText(line)); } else { length += measure.measureTextWidth(this.realText(word) + " "); line += word + " "; if(word.indexOf('\n') !== -1) { // Logically, new lines would only be at the end. length = 0; } } } lines.push(line); return lines; } /** * ========================================================================== * * TextManager.realText(string str) * * @param str The string to check for and convert escape codes. * * @note * This function takes the given string and replaces them with the text * they end up producing to the end user, so that the result can be * properly resized for autofit to process it. * * @return A string with text codes replaced. * * ========================================================================== */ $.realText = function(str) { var w = new Window_Base(0, 0, 0, 0); str = str.replace(/\\/g, '\x1b'); str = str.replace(/\x1bt\[(.+?)\]/gi); str = str.replace(/\x1b\x1b/gi, '\\'); str = str.replace(/\x1bV\[(\d+)\]/gi, function() { return $gameVariables.value(parseInt(arguments[1])); }.bind(this)); str = str.replace(/\x1bN\[(\d+)\]/gi, function() { return w.actorName(parseInt(arguments[1])); }.bind(this)); str = str.replace(/\x1bP\[(\d+)\]/gi, function() { return w.partyMemberName(parseInt(arguments[1])); }.bind(this)); str = str.replace(/\x1bG/gi, TextManager.currencyUnit); str = str.replace(/\x1b\{/g, ''); str = str.replace(/\x1b\}/g, ''); str = str.replace(/\x1b\$/g, ''); str = str.replace(/\x1b\./g, ''); str = str.replace(/\x1b\|/g, ''); str = str.replace(/\x1b\!/g, ''); str = str.replace(/\x1b\>/g, ''); str = str.replace(/\x1b\