code:
//=============================================================================
// Yanfly Engine Plugins - Message Core
// YEP_MessageCore.js
//=============================================================================

var Imported = Imported || {};
Imported.YEP_MessageCore = true;

var Yanfly = Yanfly || {};
Yanfly.Message = Yanfly.Message || {};
Yanfly.Message.version = 1.19;

//=============================================================================
/*:
* @plugindesc v1.19 Adds more features to the Message Window to customized
* the way your messages appear and functions.
* @author Yanfly Engine Plugins
*
* @param ---General---
* @default
*
* @param Default Rows
* @parent ---General---
* @type number
* @min 0
* @desc This is default amount of rows the message box will have.
* Default: 4
* @default 4
*
* @param Default Width
* @parent ---General---
* @desc This is default width for the message box in pixels.
* Default: Graphics.boxWidth
* @default Graphics.boxWidth
*
* @param Face Indent
* @parent ---General---
* @desc If using a face graphic, this is how much text indents by.
* Default: Window_Base._faceWidth + 24
* @default Window_Base._faceWidth + 24
*
* @param Fast Forward Key
* @parent ---General---
* @desc This is the key used for fast forwarding.
* @default pagedown
*
* @param Enable Fast Forward
* @parent ---General---
* @type boolean
* @on YES
* @off NO
* @desc Enable fast forward button for your messages by default?
* NO - false     YES - true
* @default true
*
* @param Word Wrapping
* @parent ---General---
* @type boolean
* @on YES
* @off NO
* @desc Use this to enable or disable word wrapping by default.
* OFF - false     ON - true
* @default false
*
* @param Description Wrap
* @parent ---General---
* @type boolean
* @on YES
* @off NO
* @desc Enable or disable word wrapping for descriptions.
* OFF - false     ON - true
* @default false
*
* @param Word Wrap Space
* @parent ---General---
* @type boolean
* @on YES
* @off NO
* @desc Insert a space with manual line breaks?
* NO - false     YES - true
* @default false
*
* @param Tight Wrap
* @parent ---General---
* @type boolean
* @on YES
* @off NO
* @desc If true and using a face for the message, the message will
* wrap tighter. NO - false     YES - true
* @default false
*
* @param ---Font---
* @default
*
* @param Font Name
* @parent ---Font---
* @desc This is the default font used for the Message Window.
* Default: GameFont
* @default GameFont
*
* @param Font Name CH
* @parent ---Font---
* @desc This is the default font used for the Message Window for Chinese.
* Default: SimHei, Heiti TC, sans-serif
* @default SimHei, Heiti TC, sans-serif
*
* @param Font Name KR
* @parent ---Font---
* @desc This is the default font used for the Message Window for Korean.
* Default: Dotum, AppleGothic, sans-serif
* @default Dotum, AppleGothic, sans-serif
*
* @param Font Size
* @parent ---Font---
* @type number
* @min 1
* @desc This is the default font size used for the Message Window.
* Default: 28
* @default 28
*
* @param Font Size Change
* @parent ---Font---
* @type number
* @min 1
* @desc Whenever \{ and \} are used, they adjust by this value.
* Default: 12
* @default 12
*
* @param Font Changed Max
* @parent ---Font---
* @type number
* @min 1
* @desc This is the maximum size achieved by \{.
* Default: 96
* @default 96
*
* @param Font Changed Min
* @parent ---Font---
* @type number
* @min 1
* @desc This is the minimum size achieved by \{.
* Default: 12
* @default 12
*
* @param Font Outline
* @parent ---Font---
* @type number
* @min 0
* @desc This is the default font outline width for messages.
* Default: 4
* @default 4
*
* @param Maintain Font
* @parent ---Font---
* @type boolean
* @on YES
* @off NO
* @desc When changing the font name or size, maintain for following
* messages. NO - false     YES - true
* @default false
*
* @param ---Name Box---
* @default
*
* @param Name Box Buffer X
* @parent ---Name Box---
* @type number
* @desc This is the buffer for the x location of the Name Box.
* @default -28
*
* @param Name Box Buffer Y
* @parent ---Name Box---
* @type number
* @desc This is the buffer for the y location of the Name Box.
* @default 0
*
* @param Name Box Padding
* @parent ---Name Box---
* @desc This is the value for the padding of the Name Box.
* @default this.standardPadding() * 4
*
* @param Name Box Color
* @parent ---Name Box---
* @type number
* @min 0
* @max 31
* @desc This is the text color used for the Name Box.
* @default 0
*
* @param Name Box Clear
* @parent ---Name Box---
* @type boolean
* @on YES
* @off NO
* @desc Do you wish for the Name Box window to be clear?
* NO - false     YES - true
* @default false
*
* @param Name Box Added Text
* @parent ---Name Box---
* @desc This text is always added whenever the name box is used.
* This can be used to automatically set up colors.
* @default \c[6]
*
* @param Name Box Auto Close
* @parent ---Name Box---
* @type boolean
* @on YES
* @off NO
* @desc Close the message window each time the namebox displays a
* different name? YES - true     NO - false
* @default false
*
* @help
* ============================================================================
* Introduction
* ============================================================================
*
* While RPG Maker MV Ace certainly improved the message system a whole lot, it
* wouldn't hurt to add in a few more features, such as name windows,
* converting textcodes to write out the icons and/or names of items, weapons,
* armours, and* more in quicker fashion. This script also gives the developer
* the ability to adjust the size of the message window during the game, give
* it a separate font, and to give the player a text fast-forward feature.
*
* ============================================================================
* Word Wrapping
* ============================================================================
*
* Word wrapping is now possible through the message system. You can enable and
* disable Word wrap using Plugin Commands. While using word wrap, if the word
* is to extend past the message window's area, it will automatically go to the
* following line. That said, word wrap will disable the editor's line breaks
* and will require you to use the ones provided by the plugin:
*
*
 or <line break> is text code to apply a line break. Use this before or
* after a part in which you wish to start a new line.
*
* Keep in mind word wrapping is mostly for message windows. However, in other
* places that you'd like to see word wrapping, such as item descriptions,
* insert <WordWrap> at the beginning of the text to enable it.
*
* ============================================================================
* Text Codes
* ============================================================================
*
* By using certain text codes in your messages, you can have the game replace
* them with the following:
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Text Code   Function
*   \V[n]       Replaced by the value of the nth variable.
*   \N[n]       Replaced by the name of the nth actor.
*   \P[n]       Replaced by the name of the nth party member.
*   \G          Replaced by the currency unit.
*   \C[n]       Draw the subsequent text in the nth color.
*   \I[n]       Draw the nth icon.
*   \{          Increases the text size by one step.
*   \}          Decreases the text size by one step.
*   \\          Replaced with the backslash character.
*   \$          Opens the gold window.
*   \.          Waits 1/4th seconds.
*   \|          Waits 1 second.
*   \!          Waits for button input.
*   \>          Display remaining text on same line all at once.
*   \<          Cancel the effect that displays text all at once.
*   \^          Do not wait for input after displaying text.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Wait:       Effect:
*    \w[x]     - Waits x frames (60 frames = 1 second). Message window only.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  NameWindow: Effect:
*    \n<x>     - Creates a name box with x string. Left side. *Note
*    \nc<x>    - Creates a name box with x string. Centered. *Note
*    \nr<x>    - Creates a name box with x string. Right side. *Note
*
*              *Note: Works for message window only.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Line Break  Effect:
*
      - If using word wrap mode, this will cause a line break.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Position:   Effect:
*    \px[x]    - Sets x position of text to x.
*    \py[x]    - Sets y position of text to y.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Outline:    Effect:
*   \oc[x]    - Sets outline colour to x.
*   \ow[x]    - Sets outline width to x.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Font:       Effect:
*    \fr       - Resets all font changes.
*    \fs[x]    - Changes font size to x.
*    \fn<x>    - Changes font name to x.
*    \fb       - Toggles font boldness.
*    \fi       - Toggles font italic.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Actor:      Effect:
*    \af[x]    - Shows face of actor x. *Note
*    \ac[x]    - Writes out actor's class name.
*    \an[x]    - Writes out actor's nickname.
*
*              *Note: Works for message window only.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Party:      Effect:
*    \pf[x]    - Shows face of party member x. *Note
*    \pc[x]    - Writes out party member x's class name.
*    \pn[x]    - Writes out party member x's nickname.
*
*              *Note: Works for message window only.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Names:      Effect:
*    \nc[x]    - Writes out class x's name.
*    \ni[x]    - Writes out item x's name.
*    \nw[x]    - Writes out weapon x's name.
*    \na[x]    - Writes out armour x's name.
*    \ns[x]    - Writes out skill x's name.
*    \nt[x]    - Writes out state x's name.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
*  Icon Names: Effect:
*    \ii[x]    - Writes out item x's name including icon.
*    \iw[x]    - Writes out weapon x's name including icon.
*    \ia[x]    - Writes out armour x's name including icon.
*    \is[x]    - Writes out skill x's name including icon.
*    \it[x]    - Writes out state x's name including icon.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* And those are the text codes added with this script. Keep in mind that some
* of these text codes only work for the Message Window. Otherwise, they'll
* work for help descriptions, actor biographies, and others.
*
* ============================================================================
* Plugin Commands
* ============================================================================
*
* The following are some plugin commands you can use through the Event Editor
* to change various aspects about the Message system.
*
* Plugin Comand
*   MessageRows 6
*   - Changes the Message Rows displayed to 6. If you are using continuous
*   Show Text events, this will continue displaying the following lines's
*   texts until it hits the row limit. Anything after that is cut off until
*   the next message starts to avoid accidental overlap.
*
*   MessageWidth 400
*   - Changes the Message Window Width to 400 pixels. This will cut off any
*   words that are shown too far to the right so adjust accordingly!
*
*   EnableWordWrap
*   - Enables wordwrapping. If a word extends past the window size, it will
*   automatically move onto the next line. Keep in mind, you will need to use
*   \br to perform line breaks.
*
*   DisableWordWrap
*   - This disables wordwrapping. Line breaks will be automatic at points
*   where a new line is started in the editor.
*
*   EnableFastForward
*   - Enables Fast Forward key from working with messages.
*
*   DisableFastForward
*   - Disables Fast Forward key from working with messages.
*
* ============================================================================
* Changelog
* ============================================================================
*
* Version 1.19:
* - Updated for RPG Maker MV version 1.5.0.
*
* Version 1.18:
* - Added new plugin parameters: 'Font Name CH' and 'Font Name KR'.
*
* Version 1.17:
* - Compatibility update with Message Macros for 'Name Box Auto Close' option.
*
* Version 1.16:
* - Added 'Tight Wrap' plugin parameter as a word wrap option to make the
* word wrap tighter when using faces.
*
* Version 1.15:
* - Added a failsafe where if the name box window would be off the screen, it
* will automatically reposition itself to under the main message window.
*
* Version 1.14:
* - Added 'Name Box Close' plugin parameter. If this is enabled, the message
* window will check for the Name Window speaker each time a follow up message
* occurs. If the name in the currently Name Window matches the name in the
* following Name Window, the message window will remain open. If it doesn't,
* the Name Window will close and reopen to indicate a new speaker.
*
* Version 1.13:
* - Added 'Maintain Font' plugin parameter under the Font category. This will
* allow you to use text codes \fn<x> and \fs[x] to permanently change the font
* of your messages until you use it again. \fr will reset them to the plugin's
* default parameter settings.
*
* Version 1.12:
* - 'Word Wrap Space' parameter no longer leaves a space at the beginning of
* each message.
*
* Version 1.11:
* - Added 'Font Outline' parameter for the plugin parameters. This adjusts the
* font outline width used by default for only message fonts.
*
* Version 1.10:
* - Updated the Message Row system for Extended Message Pack 1's Autosizing
* feature to work with extended heights.
*
* Version 1.09:
* - Replaced 'Fast Forward' parameter with the 'Fast Forward Key' parameter
* and 'Enable Fast Forward' parameter. Two new Plugin Commands are added. They
* are 'EnableFastForward' and 'DisableFastForward' for control over when fast
* forwarding is allowed as to not cause timed cutscenes to desynch.
*
* Version 1.08:
* - Fixed a bug regarding Input Number positioning when the Message Window's
* position was middle.
*
* Version 1.07:
* - Added 'Word Wrap Space' for word wrap users. This parameter will leave a
* space behind for those who want a space left behind.
*
* Version 1.06:
* - Fixed a bug that would cause masking problems with mobile devices.
*
* Version 1.05:
* - Fixed a bug that would cause the namebox window to appear distorted.
*
* Version 1.04:
* - Fixed a bug that captured too many text codes with the namebox window.
* - Timed Name Window's closing speed with main window's closing speed.
*
* Verison 1.03:
* - Fixed a bug with textcodes that messed up wordwrapping.
* - Fixed a bug with font reset, italic, and bold textcodes.
*
* Version 1.02:
* - Namebox Window's overlap feature that's in every MV window is now disabled
* to allow for overlapping with main message window.
* - Updated window positioning for Branch Choices, Number Input, and Item
* Selection windows.
*
* Version 1.01:
* - Added 'Description Wrap' into the parameters to allow for all item
* descriptions to be automatically processed with word wrapping.
*
* Version 1.00:
* - Finished plugin!
*/
//=============================================================================

//=============================================================================
// Parameter Variables
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_MessageCore');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.MSGDefaultRows = String(Yanfly.Parameters['Default Rows']);
Yanfly.Param.MSGDefaultWidth = String(Yanfly.Parameters['Default Width']);
Yanfly.Param.MSGFaceIndent = String(Yanfly.Parameters['Face Indent']);
Yanfly.Param.MSGFastForwardKey = String(Yanfly.Parameters['Fast Forward Key']);
Yanfly.Param.MSGFFOn = eval(String(Yanfly.Parameters['Enable Fast Forward']));
Yanfly.Param.MSGWordWrap = String(Yanfly.Parameters['Word Wrapping']);
Yanfly.Param.MSGWordWrap = eval(Yanfly.Param.MSGWordWrap);
Yanfly.Param.MSGDescWrap = String(Yanfly.Parameters['Description Wrap']);
Yanfly.Param.MSGWrapSpace = eval(String(Yanfly.Parameters['Word Wrap Space']));
Yanfly.Param.MSGTightWrap = eval(String(Yanfly.Parameters['Tight Wrap']));

Yanfly.Param.MSGFontName = String(Yanfly.Parameters['Font Name']);
Yanfly.Param.MSGCNFontName = String(Yanfly.Parameters['Font Name CH']);
Yanfly.Param.MSGKRFontName = String(Yanfly.Parameters['Font Name KR']);
Yanfly.Param.MSGFontSize = Number(Yanfly.Parameters['Font Size']);
Yanfly.Param.MSGFontSizeChange = String(Yanfly.Parameters['Font Size Change']);
Yanfly.Param.MSGFontChangeMax = String(Yanfly.Parameters['Font Changed Max']);
Yanfly.Param.MSGFontChangeMin = String(Yanfly.Parameters['Font Changed Min']);
Yanfly.Param.MSGFontOutline = Number(Yanfly.Parameters['Font Outline']) || 4;
Yanfly.Param.MSGFontMaintain = eval(String(Yanfly.Parameters['Maintain Font']));

Yanfly.Param.MSGNameBoxBufferX = String(Yanfly.Parameters['Name Box Buffer X']);
Yanfly.Param.MSGNameBoxBufferY = String(Yanfly.Parameters['Name Box Buffer Y']);
Yanfly.Param.MSGNameBoxPadding = String(Yanfly.Parameters['Name Box Padding']);
Yanfly.Param.MSGNameBoxColor = Number(Yanfly.Parameters['Name Box Color']);
Yanfly.Param.MSGNameBoxClear = String(Yanfly.Parameters['Name Box Clear']);
Yanfly.Param.MSGNameBoxText = String(Yanfly.Parameters['Name Box Added Text']);
Yanfly.Param.MSGNameBoxClose = String(Yanfly.Parameters['Name Box Auto Close']);
Yanfly.Param.MSGNameBoxClose = eval(Yanfly.Param.MSGNameBoxClose);

//=============================================================================
// Bitmap
//=============================================================================

Yanfly.Message.Bitmap_initialize = Bitmap.prototype.initialize;
Bitmap.prototype.initialize = function (width, height) {
  Yanfly.Message.Bitmap_initialize.call(this, width, height);
  this.fontBold = false;
};

Yanfly.Message.Bitmap_makeFontNameText = Bitmap.prototype._makeFontNameText;
Bitmap.prototype._makeFontNameText = function () {
  if (this.fontBold) return 'Bold ' + this.fontSize + 'px ' + this.fontFace;
  return Yanfly.Message.Bitmap_makeFontNameText.call(this);
};

//=============================================================================
// Game_System
//=============================================================================

Yanfly.Message.Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function () {
  Yanfly.Message.Game_System_initialize.call(this);
  this.initMessageSystem();
  this.initMessageFontSettings();
};

Game_System.prototype.initMessageSystem = function () {
  this._wordWrap = Yanfly.Param.MSGWordWrap;
  this._fastForward = Yanfly.Param.MSGFFOn;
};

Game_System.prototype.initMessageFontSettings = function () {
  if ($dataSystem.locale.match(/^zh/)) {
    this._msgFontName = Yanfly.Param.MSGCNFontName;
  } else if ($dataSystem.locale.match(/^ko/)) {
    this._msgFontName = Yanfly.Param.MSGKRFontName;
  } else {
    this._msgFontName = Yanfly.Param.MSGFontName;
  }
  this._msgFontSize = Yanfly.Param.MSGFontSize;
  this._msgFontOutline = Yanfly.Param.MSGFontOutline;
};

Game_System.prototype.messageRows = function () {
  var rows = eval(this._messageRows) || eval(Yanfly.Param.MSGDefaultRows);
  return Math.max(1, Number(rows));
};

Game_System.prototype.messageWidth = function () {
  return eval(this._messageWidth) || eval(Yanfly.Param.MSGDefaultWidth);
};

Game_System.prototype.wordWrap = function () {
  if (this._wordWrap === undefined) this.initMessageSystem();
  return this._wordWrap;
};

Game_System.prototype.setWordWrap = function (state) {
  if (this._wordWrap === undefined) this.initMessageSystem();
  this._wordWrap = state;
};

Game_System.prototype.isFastFowardEnabled = function () {
  if (this._fastForward === undefined) this.initMessageSystem();
  return this._fastForward;
};

Game_System.prototype.setFastFoward = function (state) {
  if (this._fastForward === undefined) this.initMessageSystem();
  this._fastForward = state;
};

Game_System.prototype.getMessageFontName = function () {
  if (this._msgFontName === undefined) this.initMessageFontSettings();
  return this._msgFontName;
};

Game_System.prototype.setMessageFontName = function (value) {
  if (this._msgFontName === undefined) this.initMessageFontSettings();
  this._msgFontName = value;
};

Game_System.prototype.getMessageFontSize = function () {
  if (this._msgFontSize === undefined) this.initMessageFontSettings();
  return this._msgFontSize;
};

Game_System.prototype.setMessageFontSize = function (value) {
  if (this._msgFontSize === undefined) this.initMessageFontSettings();
  this._msgFontSize = value;
};

Game_System.prototype.getMessageFontOutline = function () {
  if (this._msgFontOutline === undefined) this.initMessageFontSettings();
  return this._msgFontOutline;
};

Game_System.prototype.setMessageFontOutline = function (value) {
  if (this._msgFontOutline === undefined) this.initMessageFontSettings();
  this._msgFontOutline = value;
};

//=============================================================================
// Game_Message
//=============================================================================

Game_Message.prototype.addText = function (text) {
  if ($gameSystem.wordWrap()) text = '<WordWrap>' + text;
  this.add(text);
};

//=============================================================================
// Game_Interpreter
//=============================================================================

Yanfly.Message.Game_Interpreter_pluginCommand =
  Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
  Yanfly.Message.Game_Interpreter_pluginCommand.call(this, command, args);
  if (command === 'MessageRows') $gameSystem._messageRows = args[0];
  if (command === 'MessageWidth') $gameSystem._messageWidth = args[0];
  if (command === 'EnableWordWrap') $gameSystem.setWordWrap(true);
  if (command === 'DisableWordWrap') $gameSystem.setWordWrap(false);
  if (command === 'EnableFastForward') $gameSystem.setFastFoward(true);
  if (command === 'DisableFastForward') $gameSystem.setFastFoward(false);
};

Game_Interpreter.prototype.command101 = function () {
  if (!$gameMessage.isBusy()) {
    $gameMessage.setFaceImage(this._params[0], this._params[1]);
    $gameMessage.setBackground(this._params[2]);
    $gameMessage.setPositionType(this._params[3]);
    while (this.isContinueMessageString()) {
      this._index++;
      if (this._list[this._index].code === 401) {
        $gameMessage.addText(this.currentCommand().parameters[0]);
      }
      if ($gameMessage._texts.length >= $gameSystem.messageRows()) break;
    }
    switch (this.nextEventCode()) {
      case 102:
        this._index++;
        this.setupChoices(this.currentCommand().parameters);
        break;
      case 103:
        this._index++;
        this.setupNumInput(this.currentCommand().parameters);
        break;
      case 104:
        this._index++;
        this.setupItemChoice(this.currentCommand().parameters);
        break;
    }
    this._index++;
    this.setWaitMode('message');
  }
  return false;
};

Game_Interpreter.prototype.isContinueMessageString = function () {
  if (this.nextEventCode() === 101 && $gameSystem.messageRows() > 4) {
    return true;
  } else {
    return this.nextEventCode() === 401;
  }
};

//=============================================================================
// Window_Base
//=============================================================================

Yanfly.Message.Window_Base_resetFontSettings =
  Window_Base.prototype.resetFontSettings;
Window_Base.prototype.resetFontSettings = function () {
  Yanfly.Message.Window_Base_resetFontSettings.call(this);
  this.contents.fontBold = false;
  this.contents.fontItalic = false;
  this.contents.outlineColor = 'rgba(0, 0, 0, 0.5)';
  this.contents.outlineWidth = $gameSystem.getMessageFontOutline();
};

Window_Base.prototype.textWidthEx = function (text) {
  return this.drawTextEx(text, 0, this.contents.height + this.lineHeight());
};

Yanfly.Message.Window_Base_convertEscapeCharacters =
  Window_Base.prototype.convertEscapeCharacters;
Window_Base.prototype.convertEscapeCharacters = function (text) {
  text = this.setWordWrap(text);
  text = Yanfly.Message.Window_Base_convertEscapeCharacters.call(this, text);
  text = this.convertExtraEscapeCharacters(text);
  return text;
};

Window_Base.prototype.setWordWrap = function (text) {
  this._wordWrap = false;
  if (text.match(/<(?:WordWrap)>/i)) {
    this._wordWrap = true;
    text = text.replace(/<(?:WordWrap)>/gi, '');
  }
  if (this._wordWrap) {
    var replace = Yanfly.Param.MSGWrapSpace ? ' ' : '';
    text = text.replace(/[\n\r]+/g, replace);
  }
  if (this._wordWrap) {
    text = text.replace(/<(?:BR|line break)>/gi, '\n');
  } else {
    text = text.replace(/<(?:BR|line break)>/gi, '');
  }
  return text;
};

Window_Base.prototype.convertExtraEscapeCharacters = function (text) {
  // Font Codes
  text = text.replace(/\x1bFR/gi, '\x1bMSGCORE[0]');
  text = text.replace(/\x1bFB/gi, '\x1bMSGCORE[1]');
  text = text.replace(/\x1bFI/gi, '\x1bMSGCORE[2]');
  // \AC[n]
  text = text.replace(/\x1bAC\[(\d+)\]/gi, function () {
    return this.actorClassName(parseInt(arguments[1]));
  }.bind(this));
  // \AN[n]
  text = text.replace(/\x1bAN\[(\d+)\]/gi, function () {
    return this.actorNickname(parseInt(arguments[1]));
  }.bind(this));
  // \PC[n]
  text = text.replace(/\x1bPC\[(\d+)\]/gi, function () {
    return this.partyClassName(parseInt(arguments[1]));
  }.bind(this));
  // \PN[n]
  text = text.replace(/\x1bPN\[(\d+)\]/gi, function () {
    return this.partyNickname(parseInt(arguments[1]));
  }.bind(this));
  // \NC[n]
  text = text.replace(/\x1bNC\[(\d+)\]/gi, function () {
    return $dataClasses[parseInt(arguments[1])].name;
  }.bind(this));
  // \NI[n]
  text = text.replace(/\x1bNI\[(\d+)\]/gi, function () {
    return $dataItems[parseInt(arguments[1])].name;
  }.bind(this));
  // \NW[n]
  text = text.replace(/\x1bNW\[(\d+)\]/gi, function () {
    return $dataWeapons[parseInt(arguments[1])].name;
  }.bind(this));
  // \NA[n]
  text = text.replace(/\x1bNA\[(\d+)\]/gi, function () {
    return $dataArmors[parseInt(arguments[1])].name;
  }.bind(this));
  // \NE[n]
  text = text.replace(/\x1bNE\[(\d+)\]/gi, function () {
    return $dataEnemies[parseInt(arguments[1])].name;
  }.bind(this));
  // \NS[n]
  text = text.replace(/\x1bNS\[(\d+)\]/gi, function () {
    return $dataSkills[parseInt(arguments[1])].name;
  }.bind(this));
  // \NT[n]
  text = text.replace(/\x1bNT\[(\d+)\]/gi, function () {
    return $dataStates[parseInt(arguments[1])].name;
  }.bind(this));
  // \II[n]
  text = text.replace(/\x1bII\[(\d+)\]/gi, function () {
    return this.escapeIconItem(arguments[1], $dataItems);
  }.bind(this));
  // \IW[n]
  text = text.replace(/\x1bIW\[(\d+)\]/gi, function () {
    return this.escapeIconItem(arguments[1], $dataWeapons);
  }.bind(this));
  // \IA[n]
  text = text.replace(/\x1bIA\[(\d+)\]/gi, function () {
    return this.escapeIconItem(arguments[1], $dataArmors);
  }.bind(this));
  // \IS[n]
  text = text.replace(/\x1bIS\[(\d+)\]/gi, function () {
    return this.escapeIconItem(arguments[1], $dataSkills);
  }.bind(this));
  // \IT[n]
  text = text.replace(/\x1bIT\[(\d+)\]/gi, function () {
    return this.escapeIconItem(arguments[1], $dataStates);
  }.bind(this));
  // Finish
  return text;
};

Window_Base.prototype.actorClassName = function (n) {
  var actor = n >= 1 ? $gameActors.actor(n) : null;
  return actor ? actor.currentClass().name : '';
};

Window_Base.prototype.actorNickname = function (n) {
  var actor = n >= 1 ? $gameActors.actor(n) : null;
  return actor ? actor.nickname() : '';
};

Window_Base.prototype.partyClassName = function (n) {
  var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
  return actor ? actor.currentClass().name : '';
};

Window_Base.prototype.partyNickname = function (n) {
  var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
  return actor ? actor.nickname() : '';
};

Window_Base.prototype.escapeIconItem = function (n, database) {
  return '\x1bI[' + database[n].iconIndex + ']' + database[n].name;
};

Window_Base.prototype.obtainEscapeString = function (textState) {
  var arr = /^\<(.*?)\>/.exec(textState.text.slice(textState.index));
  if (arr) {
    textState.index += arr[0].length;
    return String(arr[0].slice(1, arr[0].length - 1));
  } else {
    return '';
  }
};

Yanfly.Message.Window_Base_processEscapeCharacter =
  Window_Base.prototype.processEscapeCharacter;
Window_Base.prototype.processEscapeCharacter = function (code, textState) {
  switch (code) {
    case 'MSGCORE':
      var id = this.obtainEscapeParam(textState);
      if (id === 0) {
        $gameSystem.initMessageFontSettings();
        this.resetFontSettings();
      }
      if (id === 1) this.contents.fontBold = !this.contents.fontBold;
      if (id === 2) this.contents.fontItalic = !this.contents.fontItalic;
      break;
    case 'FS':
      var size = this.obtainEscapeParam(textState);
      this.contents.fontSize = size;
      if (Yanfly.Param.MSGFontMaintain) $gameSystem.setMessageFontSize(size);
      break;
    case 'FN':
      var name = this.obtainEscapeString(textState);
      this.contents.fontFace = name;
      if (Yanfly.Param.MSGFontMaintain) $gameSystem.setMessageFontName(name);
      break;
    case 'OC':
      var id = this.obtainEscapeParam(textState);
      this.contents.outlineColor = this.textColor(id);
      break;
    case 'OW':
      this.contents.outlineWidth = this.obtainEscapeParam(textState);
      break;
    case 'PX':
      textState.x = this.obtainEscapeParam(textState);
      break;
    case 'PY':
      textState.y = this.obtainEscapeParam(textState);
      break;
    default:
      Yanfly.Message.Window_Base_processEscapeCharacter.call(this,
        code, textState);
      break;
  }
};

Window_Base.prototype.makeFontBigger = function () {
  var size = this.contents.fontSize + eval(Yanfly.Param.MSGFontSizeChange);
  this.contents.fontSize = Math.min(size, Yanfly.Param.MSGFontChangeMax);
};

Window_Base.prototype.makeFontSmaller = function () {
  var size = this.contents.fontSize - eval(Yanfly.Param.MSGFontSizeChange);
  this.contents.fontSize = Math.max(size, Yanfly.Param.MSGFontChangeMin);
};

Yanfly.Message.Window_Base_processNormalCharacter =
  Window_Base.prototype.processNormalCharacter;
Window_Base.prototype.processNormalCharacter = function (textState) {
  if (this.checkWordWrap(textState)) return this.processNewLine(textState);
  Yanfly.Message.Window_Base_processNormalCharacter.call(this, textState);
};

Window_Base.prototype.checkWordWrap = function (textState) {
  if (!textState) return false;
  if (!this._wordWrap) return false;
  if (textState.text[textState.index] === ' ') {
    var nextSpace = textState.text.indexOf(' ', textState.index + 1);
    var nextBreak = textState.text.indexOf('\n', textState.index + 1);
    if (nextSpace < 0) nextSpace = textState.text.length + 1;
    if (nextBreak > 0) nextSpace = Math.min(nextSpace, nextBreak);
    var word = textState.text.substring(textState.index, nextSpace);
    var size = this.textWidthExCheck(word);
  }
  return (size + textState.x > this.wordwrapWidth());
};

Window_Base.prototype.wordwrapWidth = function () {
  return this.contents.width;
};

Window_Base.prototype.saveCurrentWindowSettings = function () {
  this._saveFontFace = this.contents.fontFace;
  this._saveFontSize = this.contents.fontSize;
  this._savetextColor = this.contents.textColor;
  this._saveFontBold = this.contents.fontBold;
  this._saveFontItalic = this.contents.fontItalic;
  this._saveOutlineColor = this.contents.outlineColor;
  this._saveOutlineWidth = this.contents.outlineWidth;
};

Window_Base.prototype.restoreCurrentWindowSettings = function () {
  this.contents.fontFace = this._saveFontFace;
  this.contents.fontSize = this._saveFontSize;
  this.contents.textColor = this._savetextColor;
  this.contents.fontBold = this._saveFontBold;
  this.contents.fontItalic = this._saveFontItalic;
  this.contents.outlineColor = this._saveOutlineColor;
  this.contents.outlineWidth = this._saveOutlineWidth;
};

Window_Base.prototype.clearCurrentWindowSettings = function () {
  this._saveFontFace = undefined;
  this._saveFontSize = undefined;
  this._savetextColor = undefined;
  this._saveFontBold = undefined;
  this._saveFontItalic = undefined;
  this._saveOutlineColor = undefined;
  this._saveOutlineWidth = undefined;
};

Window_Base.prototype.textWidthExCheck = function (text) {
  var setting = this._wordWrap;
  this._wordWrap = false;
  this.saveCurrentWindowSettings();
  this._checkWordWrapMode = true;
  var value = this.drawTextEx(text, 0, this.contents.height);
  this._checkWordWrapMode = false;
  this.restoreCurrentWindowSettings();
  this.clearCurrentWindowSettings();
  this._wordWrap = setting;
  return value;
};

//=============================================================================
// Window_Help
//=============================================================================

Yanfly.Message.Window_Help_setItem = Window_Help.prototype.setItem;
Window_Help.prototype.setItem = function (item) {
  if (eval(Yanfly.Param.MSGDescWrap)) {
    this.setText(item ? '<WordWrap>' + item.description : '');
  } else {
    Yanfly.Message.Window_Help_setItem.call(this, item);
  }
};

//=============================================================================
// Window_ChoiceList
//=============================================================================

Window_ChoiceList.prototype.standardFontFace = function () {
  return $gameSystem.getMessageFontName();
};

Window_ChoiceList.prototype.standardFontSize = function () {
  return $gameSystem.getMessageFontSize();
};

Yanfly.Message.Window_ChoiceList_updatePlacement =
  Window_ChoiceList.prototype.updatePlacement;
Window_ChoiceList.prototype.updatePlacement = function () {
  Yanfly.Message.Window_ChoiceList_updatePlacement.call(this);
  var messagePosType = $gameMessage.positionType();
  if (messagePosType === 0) {
    this.y = this._messageWindow.height;
  } else if (messagePosType === 2) {
    this.y = Graphics.boxHeight - this._messageWindow.height - this.height;
  }
};

//=============================================================================
// Window_NumberInput
//=============================================================================

Yanfly.Message.Window_NumberInput_updatePlacement =
  Window_NumberInput.prototype.updatePlacement;
Window_NumberInput.prototype.updatePlacement = function () {
  Yanfly.Message.Window_NumberInput_updatePlacement.call(this);
  var messageY = this._messageWindow.y;
  var messagePosType = $gameMessage.positionType();
  if (messagePosType === 0) {
    this.y = this._messageWindow.height;
  } else if (messagePosType === 1) {
    if (messageY >= Graphics.boxHeight / 2) {
      this.y = messageY - this.height;
    } else {
      this.y = messageY + this._messageWindow.height;
    }
  } else if (messagePosType === 2) {
    this.y = Graphics.boxHeight - this._messageWindow.height - this.height;
  }
};

//=============================================================================
// Window_EventItem
//=============================================================================

Yanfly.Message.Window_EventItem_updatePlacement =
  Window_EventItem.prototype.updatePlacement;
Window_EventItem.prototype.updatePlacement = function () {
  Yanfly.Message.Window_EventItem_updatePlacement.call(this);
  var messagePosType = $gameMessage.positionType();
  if (messagePosType === 0) {
    this.y = Graphics.boxHeight - this.height;
  } else if (messagePosType === 2) {
    this.y = 0;
  }
};

//=============================================================================
// Window_ScrollText
//=============================================================================

Window_ScrollText.prototype.standardFontFace = function () {
  return $gameSystem.getMessageFontName();
};

Window_ScrollText.prototype.standardFontSize = function () {
  return $gameSystem.getMessageFontSize();
};

//=============================================================================
// Window_NameBox
//=============================================================================

Yanfly.DisableWebGLMask = false;

function Window_NameBox() {
  this.initialize.apply(this, arguments);
}

Window_NameBox.prototype = Object.create(Window_Base.prototype);
Window_NameBox.prototype.constructor = Window_NameBox;

Window_NameBox.prototype.initialize = function (parentWindow) {
  this._parentWindow = parentWindow;
  Window_Base.prototype.initialize.call(this, 0, 0, 240, this.windowHeight());
  this._text = '';
  this._lastNameText = '';
  this._openness = 0;
  this._closeCounter = 0;
  this.deactivate();
  if (eval(Yanfly.Param.MSGNameBoxClear)) {
    this.backOpacity = 0;
    this.opacity = 0;
  }
  this.hide();
};

Window_NameBox.prototype.windowWidth = function () {
  this.resetFontSettings();
  var dw = this.textWidthEx(this._text);
  dw += this.padding * 2;
  var width = dw + eval(Yanfly.Param.MSGNameBoxPadding)
  return Math.ceil(width);
};

Window_NameBox.prototype.textWidthEx = function (text) {
  return this.drawTextEx(text, 0, this.contents.height);
};

Window_NameBox.prototype.calcNormalCharacter = function (textState) {
  return this.textWidth(textState.text[textState.index++]);
};

Window_NameBox.prototype.windowHeight = function () {
  return this.fittingHeight(1);
};

Window_NameBox.prototype.standardFontFace = function () {
  return $gameSystem.getMessageFontName();
};

Window_NameBox.prototype.standardFontSize = function () {
  return $gameSystem.getMessageFontSize();
};

Window_NameBox.prototype.update = function () {
  Window_Base.prototype.update.call(this);
  if (this.active) return;
  if (this.isClosed()) return;
  if (this.isClosing()) return;
  if (this._closeCounter-- > 0) return;
  if (this._parentWindow.isClosing()) {
    this._openness = this._parentWindow.openness;
  }
  this.close();
};

Window_NameBox.prototype.refresh = function (text, position) {
  this.show();
  this._lastNameText = text;
  this._text = Yanfly.Param.MSGNameBoxText + text;
  this._position = position;
  this.width = this.windowWidth();
  this.createContents();
  this.contents.clear();
  this.resetFontSettings();
  this.changeTextColor(this.textColor(Yanfly.Param.MSGNameBoxColor));
  var padding = eval(Yanfly.Param.MSGNameBoxPadding) / 2;
  this.drawTextEx(this._text, padding, 0, this.contents.width);
  this._parentWindow.adjustWindowSettings();
  this._parentWindow.updatePlacement();
  this.adjustPositionX();
  this.adjustPositionY();
  this.open();
  this.activate();
  this._closeCounter = 4;
  return '';
};

Window_NameBox.prototype.adjustPositionX = function () {
  if (this._position === 1) {
    this.x = this._parentWindow.x;
    this.x += eval(Yanfly.Param.MSGNameBoxBufferX);
  } else if (this._position === 2) {
    this.x = this._parentWindow.x;
    this.x += this._parentWindow.width * 3 / 10;
    this.x -= this.width / 2;
  } else if (this._position === 3) {
    this.x = this._parentWindow.x;
    this.x += this._parentWindow.width / 2;
    this.x -= this.width / 2;
  } else if (this._position === 4) {
    this.x = this._parentWindow.x;
    this.x += this._parentWindow.width * 7 / 10;
    this.x -= this.width / 2;
  } else {
    this.x = this._parentWindow.x + this._parentWindow.width;
    this.x -= this.width;
    this.x -= eval(Yanfly.Param.MSGNameBoxBufferX);
  }
  this.x = this.x.clamp(0, Graphics.boxWidth - this.width);
};

Window_NameBox.prototype.adjustPositionY = function () {
  if ($gameMessage.positionType() === 0) {
    this.y = this._parentWindow.y + this._parentWindow.height;
    this.y -= eval(Yanfly.Param.MSGNameBoxBufferY);
  } else {
    this.y = this._parentWindow.y;
    this.y -= this.height;
    this.y += eval(Yanfly.Param.MSGNameBoxBufferY);
  }
  if (this.y < 0) {
    this.y = this._parentWindow.y + this._parentWindow.height;
    this.y -= eval(Yanfly.Param.MSGNameBoxBufferY);
  }
};

//=============================================================================
// Window_Message
//=============================================================================

Yanfly.Message.Window_Message_createSubWindows =
  Window_Message.prototype.createSubWindows;
Window_Message.prototype.createSubWindows = function () {
  Yanfly.Message.Window_Message_createSubWindows.call(this);
  this._nameWindow = new Window_NameBox(this);
  Yanfly.nameWindow = this._nameWindow;
  var scene = SceneManager._scene;
  scene.addChild(this._nameWindow);
};

Window_Message.prototype.numVisibleRows = function () {
  return $gameSystem.messageRows();
};

Window_Message.prototype.windowWidth = function () {
  return $gameSystem.messageWidth();
};

Window_Message.prototype.wordwrapWidth = function () {
  if (Yanfly.Param.MSGTightWrap && $gameMessage.faceName() !== '') {
    return this.contents.width - this.newLineX();
  }
  return Window_Base.prototype.wordwrapWidth.call(this);
};

Window_Message.prototype.adjustWindowSettings = function () {
  this.width = this.windowWidth();
  this.height = Math.min(this.windowHeight(), Graphics.boxHeight);
  if (Math.abs(Graphics.boxHeight - this.height) < this.lineHeight()) {
    this.height = Graphics.boxHeight;
  }
  this.createContents();
  this.x = (Graphics.boxWidth - this.width) / 2;
};

Yanfly.Message.Window_Message_startMessage =
  Window_Message.prototype.startMessage;
Window_Message.prototype.startMessage = function () {
  this._nameWindow.deactivate();
  Yanfly.Message.Window_Message_startMessage.call(this);
};

Yanfly.Message.Window_Message_terminateMessage =
  Window_Message.prototype.terminateMessage;
Window_Message.prototype.terminateMessage = function () {
  this._nameWindow.deactivate();
  Yanfly.Message.Window_Message_terminateMessage.call(this);
};

Yanfly.Message.Window_Message_newPage =
  Window_Message.prototype.newPage;
Window_Message.prototype.newPage = function (textState) {
  this.adjustWindowSettings();
  Yanfly.Message.Window_Message_newPage.call(this, textState);
};

Window_Message.prototype.standardFontFace = function () {
  return $gameSystem.getMessageFontName();
};

Window_Message.prototype.standardFontSize = function () {
  return $gameSystem.getMessageFontSize();
};

Window_Message.prototype.newLineX = function () {
  if ($gameMessage.faceName() === '') {
    return 0;
  } else {
    return eval(Yanfly.Param.MSGFaceIndent);
  }
};

Window_Message.prototype.isFastForward = function () {
  if (!$gameSystem.isFastFowardEnabled()) return false;
  return Input.isPressed(Yanfly.Param.MSGFastForwardKey);
};

Yanfly.Message.Window_Message_updateInput =
  Window_Message.prototype.updateInput;
Window_Message.prototype.updateInput = function () {
  if (this.pause && this.isFastForward()) {
    if (!this._textState) {
      this.pause = false;
      this.terminateMessage();
    }
  }
  return Yanfly.Message.Window_Message_updateInput.call(this);
};

Yanfly.Message.Window_Message_updateShowFast =
  Window_Message.prototype.updateShowFast;
Window_Message.prototype.updateShowFast = function () {
  if (this.isFastForward()) this._showFast = true;
  Yanfly.Message.Window_Message_updateShowFast.call(this);
};

Yanfly.Message.Window_Message_updateWait =
  Window_Message.prototype.updateWait;
Window_Message.prototype.updateWait = function () {
  if (this.isFastForward()) return false;
  return Yanfly.Message.Window_Message_updateWait.call(this);
};

Yanfly.Message.Window_Message_startWait =
  Window_Message.prototype.startWait;
Window_Message.prototype.startWait = function (count) {
  if (this._checkWordWrapMode) return;
  Yanfly.Message.Window_Message_startWait.call(this, count);
  if (this.isFastForward()) this._waitCount = 0;
};

Yanfly.Message.Window_Message_startPause =
  Window_Message.prototype.startPause;
Window_Message.prototype.startPause = function () {
  if (this._checkWordWrapMode) return;
  Yanfly.Message.Window_Message_startPause.call(this);
};

Window_Message.prototype.convertEscapeCharacters = function (text) {
  text = Window_Base.prototype.convertEscapeCharacters.call(this, text);
  text = this.convertNameBox(text);
  text = this.convertMessageCharacters(text);
  return text;
};

Window_Message.prototype.convertNameBox = function (text) {
  text = text.replace(/\x1bN\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 1);
  }, this);
  text = text.replace(/\x1bN1\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 1);
  }, this);
  text = text.replace(/\x1bN2\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 2);
  }, this);
  text = text.replace(/\x1bN3\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 3);
  }, this);
  text = text.replace(/\x1bNC\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 3);
  }, this);
  text = text.replace(/\x1bN4\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 4);
  }, this);
  text = text.replace(/\x1bN5\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 5);
  }, this);
  text = text.replace(/\x1bNR\<(.*?)\>/gi, function () {
    return Yanfly.nameWindow.refresh(arguments[1], 5);
  }, this);
  return text;
};

Window_Message.prototype.convertMessageCharacters = function (text) {
  text = text.replace(/\x1bAF\[(\d+)\]/gi, function () {
    var i = parseInt(arguments[1]);
    return this.convertActorFace($gameActors.actor(i));
  }.bind(this));
  text = text.replace(/\x1bPF\[(\d+)\]/gi, function () {
    var i = parseInt(arguments[1]);
    return this.convertActorFace($gameParty.members()[i - 1]);
  }.bind(this));
  return text;
};

Window_Message.prototype.convertActorFace = function (actor) {
  $gameMessage.setFaceImage(actor.faceName(), actor.faceIndex());
  return '';
};

Yanfly.Message.Window_Message_processEscapeCharacter =
  Window_Message.prototype.processEscapeCharacter;
Window_Message.prototype.processEscapeCharacter = function (code, textState) {
  switch (code) {
    case '!':
      if (!this.isFastForward()) this.startPause();
      break;
    case 'W':
      this.startWait(this.obtainEscapeParam(textState));
    default:
      Yanfly.Message.Window_Message_processEscapeCharacter.call(this,
        code, textState);
      break;
  }
};

if (Yanfly.Param.MSGNameBoxClose) {

  Yanfly.Message.Window_Message_doesContinue =
    Window_Message.prototype.doesContinue;
  Window_Message.prototype.doesContinue = function () {
    var value = Yanfly.Message.Window_Message_doesContinue.call(this);
    if (!value) return false;
    if (this.hasDifferentNameBoxText()) {
      return false;
    }
    return true;
  };

  Window_Message.prototype.hasDifferentNameBoxText = function () {
    var texts = $gameMessage._texts;
    var length = texts.length;
    var open = this._nameWindow.isOpen();
    for (var i = 0; i < length; ++i) {
      var text = texts[i];
      if (text.length <= 0) continue;
      if (Yanfly.MsgMacro) {
        text = this.convertMacroText(text);
        text = text.replace(/\x1b/gi, '\\');
      }
      if (text.match(/\\(?:N|N1|N2|N3|N4|N5|NC|NR)<(.*)>/i)) {
        var name = String(RegExp.$1);
      } else if (text.match(/\\(?:ND|ND1|ND2|ND3|ND4|ND5|NDC|NDR)<(.*)>/i)) {
        var name = String(RegExp.$1);
      } else if (text.match(/\\(?:NT|NT1|NT2|NT3|NT4|NT5|NTC|NTR)<(.*)>/i)) {
        var name = String(RegExp.$1);
      }
      if (name) {
        name = name.replace(/\\V\[(\d+)\]/gi, function () {
          return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this));
        name = name.replace(/\\V\[(\d+)\]/gi, function () {
          return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this));
        name = name.replace(/\\N\[(\d+)\]/gi, function () {
          return this.actorName(parseInt(arguments[1]));
        }.bind(this));
        name = name.replace(/\\P\[(\d+)\]/gi, function () {
          return this.partyMemberName(parseInt(arguments[1]));
        }.bind(this));
        name = name.replace(/\\/gi, '\x1b');
      }
      if (name && !open) return true;
      if (name && name !== this._nameWindow._lastNameText) {
        return true;
      }
    }
    if (open && !name) return true;
    return false;
  };

} // Yanfly.Param.MSGNameBoxClose

//=============================================================================
// End of File
//=============================================================================

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// Yanfly Engine Plugins - Skill Core
// YEP_SkillCore.js
//=============================================================================

var Imported = Imported || {};
Imported.YEP_SkillCore = true;

var Yanfly = Yanfly || {};
Yanfly.Skill = Yanfly.Skill || {};
Yanfly.Skill.version = 1.12;

//=============================================================================
/*:
 * @plugindesc v1.12 Skills are now given more functions and the ability
 * to require different types of costs.
 * @author Yanfly Engine Plugins
 *
 * @param ---General---
 * @default
 *
 * @param Cost Padding
 * @parent ---General---
 * @type number
 * @min 0
 * @desc If a skill has multiple costs, this is the amount of pixels
 * used as padding in between the costs.
 * @default 4
 *
 * @param Command Alignment
 * @parent ---General---
 * @type combo
 * @option left
 * @option center
 * @option right
 * @desc Adjusts the text alignment of the skill type window.
 * left     center     right
 * @default center
 *
 * @param Window Columns
 * @parent ---General---
 * @type number
 * @min 1
 * @desc Choose how many columns to use for the skill window.
 * Default: 2
 * @default 2
 *
 * @param ---HP Costs---
 * @default
 *
 * @param HP Format
 * @parent ---HP Costs---
 * @desc Adjusts the way HP cost appears in the skill list window.
 * %1 - Cost     %2 - HP
 * @default %1%2
 *
 * @param HP Font Size
 * @parent ---HP Costs---
 * @type number
 * @min 1
 * @desc Adjusts the font size used to display HP.
 * Default: 28
 * @default 20
 *
 * @param HP Text Color
 * @parent ---HP Costs---
 * @type number
 * @min 0
 * @max 31
 * @desc Adjusts the text color used from the Window skin for HP.
 * Default: 21
 * @default 18
 *
 * @param HP Icon
 * @parent ---HP Costs---
 * @type number
 * @min 0
 * @desc Choose what icon to use to represent HP costs.
 * Use 0 if you wish to not use an icon.
 * @default 162
 *
 * @param ---MP Costs---
 * @default
 *
 * @param MP Format
 * @parent ---MP Costs---
 * @desc Adjusts the way MP cost appears in the skill list window.
 * %1 - Cost     %2 - MP
 * @default %1%2
 *
 * @param MP Font Size
 * @parent ---MP Costs---
 * @type number
 * @min 1
 * @desc Adjusts the font size used to display MP.
 * Default: 28
 * @default 20
 *
 * @param MP Text Color
 * @parent ---MP Costs---
 * @type number
 * @min 0
 * @max 31
 * @desc Adjusts the text color used from the Window skin for MP.
 * Default: 23
 * @default 23
 *
 * @param MP Icon
 * @parent ---MP Costs---
 * @type number
 * @min 0
 * @desc Choose what icon to use to represent MP costs.
 * Use 0 if you wish to not use an icon.
 * @default 165
 *
 * @param ---TP Costs---
 * @default
 *
 * @param TP Format
 * @parent ---TP Costs---
 * @desc Adjusts the way TP cost appears in the skill list window.
 * %1 - Cost     %2 - TP
 * @default %1%2
 *
 * @param TP Font Size
 * @parent ---TP Costs---
 * @type number
 * @min 1
 * @desc Adjusts the font size used to display TP.
 * Default: 28
 * @default 20
 *
 * @param TP Text Color
 * @parent ---TP Costs---
 * @type number
 * @min 0
 * @max 31
 * @desc Adjusts the text color used from the Window skin for TP.
 * Default: 29
 * @default 29
 *
 * @param TP Icon
 * @parent ---TP Costs---
 * @type number
 * @min 0
 * @desc Choose what icon to use to represent TP costs.
 * Use 0 if you wish to not use an icon.
 * @default 164
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * Skills in RPG's consist of three main components: Costs, Damage, and
 * Effects. Although not all components are required for a skill, they
 * certainly make up a good chunk of it. Damage will be handled by another
 * plugin, but this plugin will provide a core handling for skill costs and
 * skill effects.
 *
 * This plugin also includes the ability for battlers to swap their HP, MP,
 * and/or TP gauges for something different if it would fit the character
 * better (for example, some classes don't use MP and/or TP).
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * These notetags can adjust either skill costs or special skill effects.
 *
 * Skill Notetags:
 *   <HP Cost: x>
 *   Changes the skill to have x as its HP cost. RPG Maker MV's editor lacks
 *   HP cost functions so this would allow skills to use HP as their cost.
 *
 *   <HP Cost: x%>
 *   Changes the skill to cost a percentage of the character's MaxHP value.
 *
 *   <MP Cost: x>
 *   Changes the skill to have x as its MP cost.
 *   This helps bypass the database's hard limit of 9999.
 *
 *   <MP Cost: x%>
 *   Changes the skill to cost a percentage of the character's MaxMP value.
 *
 *   <TP Cost: x>
 *   Changes the skill to have x as its TP cost.
 *   This helps bypass the database's hard limit of 99.
 *
 *   <TP Cost: x%>
 *   Changes the skill to cost a percentage of the character's MaxTP value.
 *   Although the default MaxTP is 100, this tag will be useful for any
 *   plugins that will alter a character's MaxTP values.
 *
 *   <Hide in Battle>
 *   This will hide and disable the skill during battle.
 *
 *   <Hide in Field>
 *   This will hide and disable the skill outside of battle.
 *
 *   <Hide if Learned Skill: x>
 *   <Hide if Learned Skill: x, x, x>
 *   <Hide if Learned Skill: x to y>
 *   Will hide and disable this skill if skill x has been learned. If multiple
 *   skills are listed, the skill will be hidden and disabled if any one of the
 *   listed skills have been learned. This will ONLY apply to skills that have
 *   been learned and not skills added through traits.
 *
 * ============================================================================
 * Gauge Swapping
 * ============================================================================
 *
 * This plugin also lets you swap around the HP, MP, and TP Gauges to any order
 * you want assuming that all the plugins you use will keep the same order of
 * HP, MP, and TP and does not override the default gauge drawing process. If
 * you use any plugin extensions, they can be swaped in as well.
 *
 * Note: If you do not have 'Display TP in Battle' checked under the System tab
 * in the database, nothing will be shown for the third slot.
 *
 * Class Notetag:
 *   <Swap Gauge x: y>
 *   This will change gauge x (1, 2, or 3) to y. Replace y with 'HP', 'MP', or
 *   'TP' to have it display that gauge type in that gauge slot. If you wish
 *   for that slot to display nothing, insert 'Nothing' or 'Null' in place of
 *   y in the notetag.
 *
 * Weapon, Armor, and State Notetags:
 *   <Swap Gauge x: y>
 *   Actors with equipment or states  that contain these notetags or enemies
 *   with states that contain these notetags will display those swapped gauges
 *   in place of the default settings or settings defined by the Class or
 *   Enemy notetags.
 *
 *   Priority will go in the following order:
 *     Weapons, Armors, States, Class, Enemy
 *
 * ============================================================================
 * Lunatic Mode - Skill Costs
 * ============================================================================
 *
 * For users who want more control over skill costs and skill effects, there
 * exists notetags that allow you to apply code to the costs and/or effects of
 * a skill. For effects, this will also extend towards item control, as well.
 *
 *   <Custom HP Cost>       Example: <Custom HP Cost>
 *    code                            cost += $gameVariables.value(1);
 *    code                           </Custom HP Cost>
 *   </Custom HP Cost>
 *   This allows the skill to have a custom HP cost based off of code. For the
 *   piece of code, 'cost' is a variable already predefined with the HP Cost
 *   and the HP percentage cost.
 *
 *   <Custom MP Cost>       Example: <Custom MP Cost>
 *    code                            cost += $gameVariables.value(1);
 *    code                           </Custom MP Cost>
 *   </Custom MP Cost>
 *   This allows the skill to have a custom MP cost based off of code. For the
 *   piece of code, 'cost' is a variable already predefined with the MP Cost
 *   and the MP percentage cost.
 *
 *   <Custom TP Cost>       Example: <Custom TP Cost>
 *    code                            cost += $gameVariables.value(1);
 *    code                           </Custom TP Cost>
 *   </Custom TP Cost>
 *   This allows the skill to have a custom TP cost based off of code. For the
 *   piece of code, 'cost' is a variable already predefined with the TP Cost
 *   and the TP percentage cost.
 *
 * ============================================================================
 * Lunatic Mode - Custom Show Requirements
 * ============================================================================
 *
 * For those who would like to show certain skills and disable them under any
 * custom conditions using their JavaScript knowledge, use the following:
 *
 * Skill Notetag:
 *   <Custom Show Eval>
 *   if (user.level > 50) {
 *     visible = true;
 *   } else {
 *     visible = false;
 *   }
 *   </Custom Show Eval>
 *   If the visible is set to true, the skill is shown (not hidden) and enabled
 *   if all other conditions are met. If visible is set to false, the skill is
 *   disabled and hidden from the list.
 *
 * ============================================================================
 * Lunatic Mode - Custom Requirements and Execution
 * ============================================================================
 *
 * For those with a bit of JavaScript experience, you can use the following
 * notetags to restrict a skill and what kind of code to process when executing
 * the said skill.
 *
 * Skill Notetags:
 *
 *   <Custom Requirement>
 *    if ($gameParty.gold() > 1000) {
 *      value = true;
 *    } else {
 *      value = false;
 *    }
 *   </Custom Requirement>
 *   If value is set to true, the skill will be useable provided that all other
 *   requirements have been met. If the value is set to false, the skill won't
 *   be useable.
 *
 *   <Custom Execution>
 *    $gameParty.loseGold(1000);
 *   </Custom Execution>
 *   This runs the code between the notetags upon using the skill.
 *
 * ============================================================================
 * Lunatic Mode - Custom Cost Display
 * ============================================================================
 *
 * For those with a bit of JavaScript experience, you can add new ways to
 * display the skill cost.
 *
 * Skill Notetags:
 *
 *   <Cost Display Eval>
 *    var variableId = 1;
 *    var value = 1000;
 *    $gameVariables.setValue(variableId, value);
 *   </Cost Display Eval>
 *   This notetag runs an eval before displaying the skill's cost. This is so
 *   you can set up variables and whatnot for your skill cost display text.
 *
 *   <Custom Cost Display>
 *    \c[4]\v[1]\c[0] Gold
 *   </Custom Cost Display>
 *   This is the custom text displayed before the rest of the skill costs. You
 *   can use text codes with this notetag.
 *
 * ============================================================================
 * Lunatic Mode - The Skill Phases
 * ============================================================================
 *
 * For this skill, multiple effects are applied and at different phases. The
 * various phases are as follows:
 *
 *    Before Effect Phase (influenced by this plugin)
 *    if skill successfully lands:
 *    - Pre-Damage Effect Phase (influenced by this plugin)
 *    - Damage Phase
 *    - Post-Damage Effect Phase (influenced by this plugin)
 *    - Item Trait Effects Phase
 *    After Effect Phase (influenced by this plugin)
 *
 * There's four phases which can be influenced by this plugin. Two of which do
 * not matter if the effect successfully lands or not, two of which do matter
 * if the skill does land.
 *
 * Skill and Item Notetags:
 *   <Before Eval>
 *    code
 *    code
 *   </Before Eval>
 *
 *   <Pre-Damage Eval>
 *    code
 *    code
 *   </Pre-Damage Eval>
 *
 *   <Post-Damage Eval>
 *    code
 *    code
 *   </Post-Damage Eval>
 *
 *   <After Eval>
 *    code
 *    code
 *   </After Eval>
 *   If you wish to use custom effects for your skill, you can insert the
 *   respective notetags into the skill (or item) noteboxes and it will run the
 *   code that appears in between the tags. However, using any form of comments
 *   in this tag will block out code that follows.
 *
 *   Those using the <Pre-Damage Eval> and <Post-Damage Eval> are able to make
 *   use of the damage to be dealt and the damage that has been dealt through
 *   the 'value' variable. The <Pre-Damage Eval> notetag is capable of altering
 *   the 'value' variable and return it to have damage affected by its code.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.12:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.11a:
 * - Lunatic Mode fail safes added.
 * - Documentation fix for the help file. Lunatic Mode tags didn't end right.
 * The help file is now updated to show the correct notetags.
 *
 * Version 1.10b:
 * - Fixed a visual bug when using text code font changing for custom skill
 * cost display.
 * - <Hide if Learned Skill: x> documentation updated.
 * - Compatibility update for future plugins.
 *
 * Version 1.09:
 * - The <Pre-Damage Eval> notetag now has the ability alter damage dealt. The
 * 'value' variable refers to and returns the damage affected by the action.
 *
 * Version 1.08:
 * - Updated for RPG Maker MV version 1.1.0.
 *
 * Version 1.07:
 * - Fixed a bug that prevented immortal actors at 0 HP from using skills.
 *
 * Version 1.06a:
 * - Added <Hide in Battle> and <Hide in Field> notetags.
 * - Added a failsafe to check for undefined skills.
 *
 * Version 1.05:
 * - Added <Hide if Learned Skill: x> notetags.
 * - Added <Custom Show Eval> Lunatic Mode notetag.
 *
 * Version 1.04:
 * - Added four Lunatic Modes notetags: Custom Requirement, Custom Execution,
 * Cost Display Eval, Custom Cost Display.
 *
 * Version 1.03:
 * - Fixed a bug with the Lunatic Mode notetags not working.
 *
 * Version 1.02:
 * - Added 'Window Columns' parameter to let users adjust the number of columns
 * used for the skill window.
 *
 * Version 1.01:
 * - Fixed a mathematical error for skill cost padding.
 * - Added return for drawSkillCost to assist others scripters when making
 * compatibility notes.
 *
 * Version 1.00:
 * - Finished plugin!
 */
//=============================================================================

//=============================================================================
// Parameter Variables
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_SkillCore');
Yanfly.Param = Yanfly.Param || {};
Yanfly.Icon = Yanfly.Icon || {};

Yanfly.Param.SCCCostPadding = Number(Yanfly.Parameters['Cost Padding']);
Yanfly.Param.SCCTextAlign = String(Yanfly.Parameters['Command Alignment']);
Yanfly.Param.SCCWindowCol = Number(Yanfly.Parameters['Window Columns']);
Yanfly.Param.SCCTpFormat = String(Yanfly.Parameters['TP Format']);
Yanfly.Param.SCCTpFontSize = Number(Yanfly.Parameters['TP Font Size']);
Yanfly.Param.SCCTpTextColor = Number(Yanfly.Parameters['TP Text Color']);
Yanfly.Icon.Tp = Number(Yanfly.Parameters['TP Icon']);
Yanfly.Param.SCCMpFormat = String(Yanfly.Parameters['MP Format']);
Yanfly.Param.SCCMpFontSize = Number(Yanfly.Parameters['MP Font Size']);
Yanfly.Param.SCCMpTextColor = Number(Yanfly.Parameters['MP Text Color']);
Yanfly.Icon.Mp = Number(Yanfly.Parameters['MP Icon']);
Yanfly.Param.SCCHpFormat = String(Yanfly.Parameters['HP Format']);
Yanfly.Param.SCCHpFontSize = Number(Yanfly.Parameters['HP Font Size']);
Yanfly.Param.SCCHpTextColor = Number(Yanfly.Parameters['HP Text Color']);
Yanfly.Icon.Hp = Number(Yanfly.Parameters['HP Icon']);

//=============================================================================
// DataManager
//=============================================================================

Yanfly.Skill.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function () {
  if (!Yanfly.Skill.DataManager_isDatabaseLoaded.call(this)) return false;
  if (!Yanfly._loaded_YEP_SkillCore) {
    this.processSkillNotetags($dataSkills);
    this.processObjectNotetags($dataSkills);
    this.processObjectNotetags($dataItems);
    this.processGSCNotetags1($dataClasses);
    this.processGSCNotetags1($dataEnemies);
    this.processGSCNotetags2($dataWeapons);
    this.processGSCNotetags2($dataArmors);
    this.processGSCNotetags2($dataStates);
    Yanfly._loaded_YEP_SkillCore = true;
  }
  return true;
};

DataManager.processSkillNotetags = function (group) {
  var note1 = /<(?:MP COST):[ ](\d+)>/i;
  var note2 = /<(?:MP COST):[ ](\d+)([%％])>/i;
  var note3 = /<(?:TP COST):[ ](\d+)>/i;
  var note4 = /<(?:TP COST):[ ](\d+)([%％])>/i;
  var note5 = /<(?:HP COST):[ ](\d+)>/i;
  var note6 = /<(?:HP COST):[ ](\d+)([%％])>/i;
  var note7a = /<(?:HIDE IF LEARNED SKILL):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var note7b = /<(?:HIDE IF LEARNED SKILL):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i;
  var note8a = /<(?:HIDE IN BATTLE|hide during battle)>/i;
  var note8b = /<(?:HIDE IN FIELD|hide during field)>/i;
  var noteMpEval1 = /<(?:MP COST EVAL|custom mp cost)>/i;
  var noteMpEval2 = /<\/(?:MP COST EVAL|custom mp cost)>/i;
  var noteTpEval1 = /<(?:TP COST EVAL|custom tp cost)>/i;
  var noteTpEval2 = /<\/(?:TP COST EVAL|custom tp cost)>/i;
  var noteHpEval1 = /<(?:HP COST EVAL|custom hp cost)>/i;
  var noteHpEval2 = /<\/(?:HP COST EVAL|custom hp cost)>/i;
  var noteEvalReq1 = /<(?:EVAL REQUIREMENT|custom requirement)>/i;
  var noteEvalReq2 = /<\/(?:EVAL REQUIREMENT|custom requirement)>/i;
  var noteEvalExe1 = /<(?:EVAL EXECUTION|custom execution)>/i;
  var noteEvalExe2 = /<\/(?:EVAL EXECUTION|custom execution)>/i;
  var noteCostEval1 = /<(?:COST DISPLAY EVAL|display cost eval)>/i;
  var noteCostEval2 = /<\/(?:COST DISPLAY EVAL|display cost eval)>/i;
  var noteCostText1 = /<(?:CUSTOM COST DISPLAY|custom display cost)>/i;
  var noteCostText2 = /<\/(?:CUSTOM COST DISPLAY|custom display cost)>/i;
  var noteShowEval1 = /<(?:CUSTOM SHOW EVAL)>/i;
  var noteShowEval2 = /<\/(?:CUSTOM SHOW EVAL)>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.hpCost = 0;
    obj.hpCostPer = 0.0;
    obj.mpCostPer = 0.0;
    obj.tpCostPer = 0.0;
    obj.hideInBattle = false;
    obj.hideInField = false;
    obj.hideIfLearnedSkill = [];
    var evalMode = 'none';
    obj.hpCostEval = '';
    obj.mpCostEval = '';
    obj.tpCostEval = '';
    obj.requireEval = '';
    obj.executeEval = '';
    obj.costdisplayEval = '';
    obj.costShowEval = '';
    obj.customCostText = '';

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(note1)) {
        obj.mpCost = parseInt(RegExp.$1);
      } else if (line.match(note2)) {
        obj.mpCostPer = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note3)) {
        obj.tpCost = parseInt(RegExp.$1);
      } else if (line.match(note4)) {
        obj.tpCostPer = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note5)) {
        obj.hpCost = parseInt(RegExp.$1);
      } else if (line.match(note6)) {
        obj.hpCostPer = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note7a)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        obj.hideIfLearnedSkill = obj.hideIfLearnedSkill.concat(array);
      } else if (line.match(note7b)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        var range = Yanfly.Util.getRange(parseInt(RegExp.$1),
          parseInt(RegExp.$2));
        obj.hideIfLearnedSkill = obj.hideIfLearnedSkill.concat(range);
      } else if (line.match(note8a)) {
        obj.hideInBattle = true;
      } else if (line.match(note8b)) {
        obj.hideInField = true;
      } else if (line.match(noteMpEval1)) {
        evalMode = 'mp';
      } else if (line.match(noteMpEval2)) {
        evalMode = 'none';
      } else if (line.match(noteTpEval1)) {
        evalMode = 'tp';
      } else if (line.match(noteTpEval2)) {
        evalMode = 'none';
      } else if (line.match(noteHpEval1)) {
        evalMode = 'hp';
      } else if (line.match(noteHpEval2)) {
        evalMode = 'none';
      } else if (line.match(noteEvalReq1)) {
        evalMode = 'custom requirement';
      } else if (line.match(noteEvalReq2)) {
        evalMode = 'none';
      } else if (line.match(noteEvalExe1)) {
        evalMode = 'custom execute';
      } else if (line.match(noteEvalExe2)) {
        evalMode = 'none';
      } else if (line.match(noteCostEval1)) {
        evalMode = 'display cost eval';
      } else if (line.match(noteCostEval2)) {
        evalMode = 'none';
      } else if (line.match(noteCostText1)) {
        evalMode = 'custom display cost';
      } else if (line.match(noteCostText2)) {
        evalMode = 'none';
      } else if (line.match(noteShowEval1)) {
        evalMode = 'custom show eval';
      } else if (line.match(noteShowEval2)) {
        evalMode = 'none';
      } else if (evalMode === 'mp') {
        obj.mpCostEval = obj.mpCostEval + line + '\n';
      } else if (evalMode === 'tp') {
        obj.tpCostEval = obj.tpCostEval + line + '\n';
      } else if (evalMode === 'hp') {
        obj.hpCostEval = obj.hpCostEval + line + '\n';
      } else if (evalMode === 'custom requirement') {
        obj.requireEval = obj.requireEval + line + '\n';
      } else if (evalMode === 'custom execute') {
        obj.executeEval = obj.executeEval + line + '\n';
      } else if (evalMode === 'display cost eval') {
        obj.costdisplayEval = obj.costdisplayEval + line + '\n';
      } else if (evalMode === 'custom display cost') {
        obj.customCostText = obj.customCostText + line;
      } else if (evalMode === 'custom show eval') {
        obj.costShowEval = obj.costShowEval + line + '\n';
      }
    }
  }
};

DataManager.processObjectNotetags = function (group) {
  var note1 = /<(?:BEFORE EVAL)>/i;
  var note2 = /<\/(?:BEFORE EVAL)>/i;
  var note3 = /<(?:PRE-DAMAGE EVAL)>/i;
  var note4 = /<\/(?:PRE-DAMAGE EVAL)>/i;
  var note5 = /<(?:POST-DAMAGE EVAL)>/i;
  var note6 = /<\/(?:POST-DAMAGE EVAL)>/i;
  var note7 = /<(?:AFTER EVAL)>/i;
  var note8 = /<\/(?:AFTER EVAL)>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    var customMode = 'none';
    obj.customBeforeEval = '';
    obj.customPreDamageEval = '';
    obj.customPostDamageEval = '';
    obj.customAfterEval = '';

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(note1)) {
        customMode = 'before';
      } else if (line.match(note2)) {
        customMode = 'none';
      } else if (line.match(note3)) {
        customMode = 'pre-damage';
      } else if (line.match(note4)) {
        customMode = 'none';
      } else if (line.match(note5)) {
        customMode = 'post-damage';
      } else if (line.match(note6)) {
        customMode = 'none';
      } else if (line.match(note7)) {
        customMode = 'after';
      } else if (line.match(note8)) {
        customMode = 'none';
      } else if (customMode === 'before') {
        obj.customBeforeEval = obj.customBeforeEval + line + '\n';
      } else if (customMode === 'pre-damage') {
        obj.customPreDamageEval = obj.customPreDamageEval + line + '\n';
      } else if (customMode === 'post-damage') {
        obj.customPostDamageEval = obj.customPostDamageEval + line + '\n';
      } else if (customMode === 'after') {
        obj.customAfterEval = obj.customAfterEval + line + '\n';
      }
    }
  }
};

DataManager.processGSCNotetags1 = function (group) {
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.gauge1 = 'HP';
    obj.gauge2 = 'MP';
    obj.gauge3 = 'TP';

    obj.gaugeIcon1 = 0;
    obj.gaugeIcon2 = 0;
    obj.gaugeIcon3 = 0;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<(?:SWAP GAUGE|gauge)[ ](\d+):[ ](.*)>/i)) {
        var gauge = parseInt(RegExp.$1);
        var text = String(RegExp.$2).toUpperCase();
        if (['HP', 'MP', 'TP', 'NOTHING', 'NULL'].contains(text)) {
          if (gauge === 1) obj.gauge1 = text;
          if (gauge === 2) obj.gauge2 = text;
          if (gauge === 3) obj.gauge3 = text;
        }
      }
    }
  }
};

DataManager.processGSCNotetags2 = function (group) {
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.gauge1 = 'UNDEFINED';
    obj.gauge2 = 'UNDEFINED';
    obj.gauge3 = 'UNDEFINED';

    obj.gaugeIcon1 = 'UNDEFINED';
    obj.gaugeIcon2 = 'UNDEFINED';
    obj.gaugeIcon3 = 'UNDEFINED';

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<(?:SWAP GAUGE|gauge)[ ](\d+):[ ](.*)>/i)) {
        var gauge = parseInt(RegExp.$1);
        var text = String(RegExp.$2).toUpperCase();
        if (['HP', 'MP', 'TP', 'NOTHING', 'NULL'].contains(text)) {
          if (gauge === 1) obj.gauge1 = text;
          if (gauge === 2) obj.gauge2 = text;
          if (gauge === 3) obj.gauge3 = text;
        }
      }
    }
  }
};

//=============================================================================
// Game_BattlerBase
//=============================================================================

Yanfly.Skill.Game_BattlerBase_mSC =
  Game_BattlerBase.prototype.meetsSkillConditions;
Game_BattlerBase.prototype.meetsSkillConditions = function (skill) {
  if (!Yanfly.Skill.Game_BattlerBase_mSC.call(this, skill)) return false;
  if (!skill) return false;
  if (!this.noHiddenSkillConditionsMet(skill)) return false;
  return this.meetsSkillConditionsEval(skill);
};

Game_BattlerBase.prototype.noHiddenSkillConditionsMet = function (skill) {
  if (!skill) return false;
  if (this.isEnemy()) return true;
  if (skill.hideIfLearnedSkill) {
    for (var i = 0; i < skill.hideIfLearnedSkill.length; ++i) {
      var skillId = skill.hideIfLearnedSkill[i];
      if (this.isLearnedSkill(skillId)) return false;
    }
  }
  if (skill.hideInBattle && $gameParty.inBattle()) return false;
  if (skill.hideInField && !$gameParty.inBattle()) return false;
  if (!this.meetsCustomShowEval(skill)) return false;
  return true;
};

Game_BattlerBase.prototype.meetsCustomShowEval = function (skill) {
  if (skill.costShowEval === '') return true;
  var visible = true;
  var item = skill;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = skill.costShowEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL CUSTOM SHOW EVAL ERROR');
  }
  return visible;
};

Game_BattlerBase.prototype.meetsSkillConditionsEval = function (skill) {
  if (skill.requireEval === '') return true;
  var value = true;
  var item = skill;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = skill.requireEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL CUSTOM REQUIRE EVAL ERROR');
  }
  return value;
};

Game_BattlerBase.prototype.skillHpCost = function (skill) {
  var cost = skill.hpCost;
  var item = skill;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  cost += this.mhp * skill.hpCostPer;
  var code = skill.hpCostEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL CUSTOM HP COST ERROR');
  }
  return Math.max(0, Math.floor(cost));
};

Game_BattlerBase.prototype.skillMpCost = function (skill) {
  var cost = skill.mpCost;
  var item = skill;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  cost += this.mmp * skill.mpCostPer;
  var code = skill.mpCostEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL CUSTOM MP COST ERROR');
  }
  return Math.max(0, Math.floor(cost * this.mcr));
};

Game_BattlerBase.prototype.skillTpCost = function (skill) {
  var cost = skill.tpCost;
  var item = skill;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  cost += this.maxTp() * skill.tpCostPer;
  var code = skill.tpCostEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL CUSTOM TP COST ERROR');
  }
  return Math.max(0, Math.floor(cost));
};

Yanfly.Skill.Game_BattlerBase_canPaySkillCost =
  Game_BattlerBase.prototype.canPaySkillCost;
Game_BattlerBase.prototype.canPaySkillCost = function (skill) {
  if (!this.canPaySkillHpCost(skill)) return false;
  return Yanfly.Skill.Game_BattlerBase_canPaySkillCost.call(this, skill);
};

Game_BattlerBase.prototype.canPaySkillHpCost = function (skill) {
  var cost = this.skillHpCost(skill);
  if (cost <= 0) return true;
  return this._hp > cost;
};

Yanfly.Skill.Game_BattlerBase_paySkillCost =
  Game_BattlerBase.prototype.paySkillCost
Game_BattlerBase.prototype.paySkillCost = function (skill) {
  Yanfly.Skill.Game_BattlerBase_paySkillCost.call(this, skill);
  this.paySkillHpCost(skill);
  this.paySkillEvalCost(skill);
};

Game_BattlerBase.prototype.paySkillHpCost = function (skill) {
  this._hp -= this.skillHpCost(skill);
};

Game_BattlerBase.prototype.paySkillEvalCost = function (skill) {
  if (skill.executeEval === '') return;
  var item = skill;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = skill.executeEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL PAY COST EVAL ERROR');
  }
};

Game_BattlerBase.prototype.gauge1 = function () {
  return 'HP';
};

Game_BattlerBase.prototype.gauge2 = function () {
  return 'MP';
};

Game_BattlerBase.prototype.gauge3 = function () {
  return 'TP';
};

Game_BattlerBase.prototype.gaugeIcon1 = function () {
  return 0;
};

Game_BattlerBase.prototype.gaugeIcon2 = function () {
  return 0;
};

Game_BattlerBase.prototype.gaugeIcon3 = function () {
  return 0;
};

//=============================================================================
// Game_Actor
//=============================================================================

Game_Actor.prototype.gauge1 = function () {
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (equip.gauge1 === 'UNDEFINED') continue;
    return equip.gauge1;
  }
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gauge1 === 'UNDEFINED') continue;
    return state.gauge1;
  }
  return this.currentClass().gauge1;
};

Game_Actor.prototype.gauge2 = function () {
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (equip.gauge2 === 'UNDEFINED') continue;
    return equip.gauge2;
  }
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gauge2 === 'UNDEFINED') continue;
    return state.gauge2;
  }
  return this.currentClass().gauge2;
};

Game_Actor.prototype.gauge3 = function () {
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (equip.gauge3 === 'UNDEFINED') continue;
    return equip.gauge3;
  }
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gauge3 === 'UNDEFINED') continue;
    return state.gauge3;
  }
  return this.currentClass().gauge3;
};

Game_Actor.prototype.gaugeIcon1 = function () {
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (equip.gaugeIcon1 === 'UNDEFINED') continue;
    return equip.gaugeIcon1;
  }
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gaugeIcon1 === 'UNDEFINED') continue;
    return state.gaugeIcon1;
  }
  return this.currentClass().gaugeIcon1;
};

Game_Actor.prototype.gaugeIcon2 = function () {
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (equip.gaugeIcon2 === 'UNDEFINED') continue;
    return equip.gaugeIcon2;
  }
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gaugeIcon2 === 'UNDEFINED') continue;
    return state.gaugeIcon2;
  }
  return this.currentClass().gaugeIcon2;
};

Game_Actor.prototype.gaugeIcon3 = function () {
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (equip.gaugeIcon3 === 'UNDEFINED') continue;
    return equip.gaugeIcon3;
  }
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gaugeIcon3 === 'UNDEFINED') continue;
    return state.gaugeIcon3;
  }
  return this.currentClass().gaugeIcon3;
};

//=============================================================================
// Game_Enemy
//=============================================================================

Game_Enemy.prototype.gauge1 = function () {
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gauge1 === 'UNDEFINED') continue;
    return state.gauge1;
  }
  return this.enemy().gauge1;
};

Game_Enemy.prototype.gauge2 = function () {
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gauge2 === 'UNDEFINED') continue;
    return state.gauge2;
  }
  return this.enemy().gauge2;
};

Game_Enemy.prototype.gauge3 = function () {
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gauge1 === 'UNDEFINED') continue;
    return state.gauge1;
  }
  return this.enemy().gauge3;
};

Game_Enemy.prototype.gaugeIcon1 = function () {
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gaugeIcon1 === 'UNDEFINED') continue;
    return state.gaugeIcon1;
  }
  return this.enemy().gaugeIcon1;
};

Game_Enemy.prototype.gaugeIcon2 = function () {
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gaugeIcon2 === 'UNDEFINED') continue;
    return state.gaugeIcon2;
  }
  return this.enemy().gaugeIcon2;
};

Game_Enemy.prototype.gaugeIcon3 = function () {
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (state.gaugeIcon3 === 'UNDEFINED') continue;
    return state.gaugeIcon3;
  }
  return this.enemy().gaugeIcon3;
};

if (!Game_Enemy.prototype.skills) {
  Game_Enemy.prototype.skills = function () {
    var skills = []
    for (var i = 0; i < this.enemy().actions.length; ++i) {
      var skill = $dataSkills[this.enemy().actions[i].skillId];
      if (skill) skills.push(skill);
    }
    return skills;
  }
};

//=============================================================================
// Game_Action
//=============================================================================

Yanfly.Skill.Game_Action_apply = Game_Action.prototype.apply;
Game_Action.prototype.apply = function (target) {
  this.applyBeforeEffect(target);
  this.applyBeforeEval(target);
  Yanfly.Skill.Game_Action_apply.call(this, target);
  this.applyAfterEffect(target);
  this.applyAfterEval(target);
};

Game_Action.prototype.applyBeforeEffect = function (target) {
};

Game_Action.prototype.applyBeforeEval = function (target) {
  var item = this.item();
  var a = this.subject();
  var b = target;
  var user = this.subject();
  var subject = this.subject();
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = item.customBeforeEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'BEFORE EVAL ERROR');
  }
};

Game_Action.prototype.applyAfterEffect = function (target) {
};

Game_Action.prototype.applyAfterEval = function (target) {
  var item = this.item();
  var a = this.subject();
  var b = target;
  var user = this.subject();
  var subject = this.subject();
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = item.customAfterEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'AFTER EVAL ERROR');
  }
};

Yanfly.Skill.Game_Action_executeDamage = Game_Action.prototype.executeDamage;
Game_Action.prototype.executeDamage = function (target, value) {
  this.applyPreDamageEffect(target, value);
  value = this.applyPreDamageEval(target, value);
  Yanfly.Skill.Game_Action_executeDamage.call(this, target, value);
  this.applyPostDamageEffect(target, value);
  this.applyPostDamageEval(target, value);
};

Game_Action.prototype.applyPreDamageEffect = function (target, value) {
};

Game_Action.prototype.applyPreDamageEval = function (target, value) {
  var item = this.item();
  var a = this.subject();
  var b = target;
  var user = this.subject();
  var subject = this.subject();
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = item.customPreDamageEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'PRE-DAMAGE EVAL ERROR');
  }
  return value;
};

Game_Action.prototype.applyPostDamageEffect = function (target, value) {
};

Game_Action.prototype.applyPostDamageEval = function (target, value) {
  var item = this.item();
  var a = this.subject();
  var b = target;
  var user = this.subject();
  var subject = this.subject();
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = item.customPostDamageEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'POST-DAMAGE EVAL ERROR');
  }
};

//=============================================================================
// Window_Base
//=============================================================================

Yanfly.Skill.Window_Base_drawActorHp = Window_Base.prototype.drawActorHp;
Window_Base.prototype.drawActorHp = function (actor, x, y, width) {
  if (actor.gauge1() === 'HP') {
    Yanfly.Skill.Window_Base_drawActorHp.call(this, actor, x, y, width);
  } else if (actor.gauge1() === 'MP') {
    Yanfly.Skill.Window_Base_drawActorMp.call(this, actor, x, y, width);
  } else if (actor.gauge1() === 'TP') {
    Yanfly.Skill.Window_Base_drawActorTp.call(this, actor, x, y, width);
  }
};

Yanfly.Skill.Window_Base_drawActorMp = Window_Base.prototype.drawActorMp;
Window_Base.prototype.drawActorMp = function (actor, x, y, width) {
  if (actor.gauge2() === 'HP') {
    Yanfly.Skill.Window_Base_drawActorHp.call(this, actor, x, y, width);
  } else if (actor.gauge2() === 'MP') {
    Yanfly.Skill.Window_Base_drawActorMp.call(this, actor, x, y, width);
  } else if (actor.gauge2() === 'TP') {
    Yanfly.Skill.Window_Base_drawActorTp.call(this, actor, x, y, width);
  }
};

Yanfly.Skill.Window_Base_drawActorTp = Window_Base.prototype.drawActorTp;
Window_Base.prototype.drawActorTp = function (actor, x, y, width) {
  if (actor.gauge3() === 'HP') {
    Yanfly.Skill.Window_Base_drawActorHp.call(this, actor, x, y, width);
  } else if (actor.gauge3() === 'MP') {
    Yanfly.Skill.Window_Base_drawActorMp.call(this, actor, x, y, width);
  } else if (actor.gauge3() === 'TP') {
    Yanfly.Skill.Window_Base_drawActorTp.call(this, actor, x, y, width);
  }
};

//=============================================================================
// Window_SkillType
//=============================================================================

Window_SkillType.prototype.itemTextAlign = function () {
  return Yanfly.Param.SCCTextAlign;
};

//=============================================================================
// Window_SkillList
//=============================================================================

Window_SkillList.prototype.maxCols = function () {
  return Yanfly.Param.SCCWindowCol;
};

Yanfly.Skill.Window_SkillList_includes =
  Window_SkillList.prototype.includes;
Window_SkillList.prototype.includes = function (item) {
  if (this._actor) {
    if (!this._actor.noHiddenSkillConditionsMet(item)) return false;
  }
  return Yanfly.Skill.Window_SkillList_includes.call(this, item);
};

Window_SkillList.prototype.drawSkillCost = function (skill, wx, wy, width) {
  var dw = width;
  dw = this.drawTpCost(skill, wx, wy, dw);
  dw = this.drawMpCost(skill, wx, wy, dw);
  dw = this.drawHpCost(skill, wx, wy, dw);
  dw = this.drawCustomDisplayCost(skill, wx, wy, dw);
  dw = this.drawOtherCost(skill, wx, wy, dw);
  return dw;
};

Window_SkillList.prototype.drawTpCost = function (skill, wx, wy, dw) {
  if (this._actor.skillTpCost(skill) <= 0) return dw;
  if (Yanfly.Icon.Tp > 0) {
    var iw = wx + dw - Window_Base._iconWidth;
    this.drawIcon(Yanfly.Icon.Tp, iw, wy + 2);
    dw -= Window_Base._iconWidth + 2;
  }
  this.changeTextColor(this.textColor(Yanfly.Param.SCCTpTextColor));
  var fmt = Yanfly.Param.SCCTpFormat;
  var text = fmt.format(Yanfly.Util.toGroup(this._actor.skillTpCost(skill)),
    TextManager.tpA);
  this.contents.fontSize = Yanfly.Param.SCCTpFontSize;
  this.drawText(text, wx, wy, dw, 'right');
  var returnWidth = dw - this.textWidth(text) - Yanfly.Param.SCCCostPadding;
  this.resetFontSettings();
  return returnWidth;
};

Window_SkillList.prototype.drawMpCost = function (skill, wx, wy, dw) {
  if (this._actor.skillMpCost(skill) <= 0) return dw;
  if (Yanfly.Icon.Mp > 0) {
    var iw = wx + dw - Window_Base._iconWidth;
    this.drawIcon(Yanfly.Icon.Mp, iw, wy + 2);
    dw -= Window_Base._iconWidth + 2;
  }
  this.changeTextColor(this.textColor(Yanfly.Param.SCCMpTextColor));
  var fmt = Yanfly.Param.SCCMpFormat;
  var text = fmt.format(Yanfly.Util.toGroup(this._actor.skillMpCost(skill)),
    TextManager.mpA);
  this.contents.fontSize = Yanfly.Param.SCCMpFontSize;
  this.drawText(text, wx, wy, dw, 'right');
  var returnWidth = dw - this.textWidth(text) - Yanfly.Param.SCCCostPadding;
  this.resetFontSettings();
  return returnWidth;
};

Window_SkillList.prototype.drawHpCost = function (skill, wx, wy, dw) {
  if (this._actor.skillHpCost(skill) <= 0) return dw;
  if (Yanfly.Icon.Hp > 0) {
    var iw = wx + dw - Window_Base._iconWidth;
    this.drawIcon(Yanfly.Icon.Hp, iw, wy + 2);
    dw -= Window_Base._iconWidth + 2;
  }
  this.changeTextColor(this.textColor(Yanfly.Param.SCCHpTextColor));
  var fmt = Yanfly.Param.SCCHpFormat;
  var text = fmt.format(Yanfly.Util.toGroup(this._actor.skillHpCost(skill)),
    TextManager.hpA);
  this.contents.fontSize = Yanfly.Param.SCCHpFontSize;
  this.drawText(text, wx, wy, dw, 'right');
  var returnWidth = dw - this.textWidth(text) - Yanfly.Param.SCCCostPadding;
  this.resetFontSettings();
  return returnWidth;
};

Window_SkillList.prototype.textWidthEx = function (text) {
  return this.drawTextEx(text, 0, this.contents.height);
};

Window_SkillList.prototype.drawCustomDisplayCost = function (skill, wx, wy, dw) {
  this.runDisplayEvalCost(skill);
  if (skill.customCostText === '') return dw;
  var width = this.textWidthEx(skill.customCostText);
  this.resetFontSettings();
  this.drawTextEx(skill.customCostText, wx - width + dw, wy);
  var returnWidth = dw - width - Yanfly.Param.SCCCostPadding;
  this.resetFontSettings();
  return returnWidth;
};

Window_SkillList.prototype.runDisplayEvalCost = function (skill) {
  if (skill.costdisplayEval === '') return;
  var item = skill;
  var a = this._actor;
  var user = this._actor;
  var subject = this._actor;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = skill.costdisplayEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'SKILL COST DISPLAY EVAL ERROR');
  }
};

Window_SkillList.prototype.drawOtherCost = function (skill, wx, wy, dw) {
  return dw;
};

//=============================================================================
// Utilities
//=============================================================================

Yanfly.Util = Yanfly.Util || {};

if (!Yanfly.Util.toGroup) {
  Yanfly.Util.toGroup = function (inVal) {
    return inVal;
  }
};

Yanfly.Util.displayError = function (e, code, message) {
  console.log(message);
  console.log(code || 'NON-EXISTENT');
  console.error(e);
  if (Utils.isNwjs() && Utils.isOptionValid('test')) {
    if (!require('nw.gui').Window.get().isDevToolsOpen()) {
      require('nw.gui').Window.get().showDevTools();
    }
  }
};

//=============================================================================
// End of File
//=============================================================================