code:
//=============================================================================
// アクターのバトルコマンドの表示を変更するプラグイン
// FTKR_ExBattleCommand.js
// 作成者     : フトコロ
// 作成日     : 2017/11/25
// 最終更新日 : 2020/01/03
// バージョン : v2.2.2
//=============================================================================

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

var FTKR = FTKR || {};
FTKR.EBC = FTKR.EBC || {};

//=============================================================================
/*:
 * @plugindesc v2.2.2 アクターのバトルコマンドの表示を変更する
 * @author フトコロ
 *
 * @param --パーティーコマンド--
 * @default
 *
 * @param Party Command List
 * @desc パーティーコマンドの表示内容と順番を設定します。コマンドの間は、カンマ(,)で区切ってください。空欄の場合はこの機能を無効にします。
 * @default fight,escape
 *
 * @param Party Commands
 * @desc パーティーコマンドの内容を設定します。
 * @type struct<party>
 * @default {"fight":"{\"enabled\":\"\",\"ext\":\"\",\"skillId\":\"\"}","escape":"{\"enabled\":\"BattleManager.canEscape()\",\"ext\":\"\",\"skillId\":\"\"}","customs":"[]"}
 *
 * @param --コマンドアイコン--
 * @default
 *
 * @param Show Command Icon
 * @desc コマンドに設定したスキルのアイコンを表示します。
 * @type boolean
 * @on 有効
 * @off 無効
 * @default false
 *
 * @param --コマンド説明文--
 * @default
 *
 * @param Show Command Description
 * @desc コマンドに設定したスキルの説明文を表示します。
 * @type boolean
 * @on 有効
 * @off 無効
 * @default false
 *
 * @param --空欄コマンド--
 * @default
 *
 * @param Enable Select Blank
 * @desc 空欄コマンドのカーソル選択を可能にするかどうか設定する。
 * @type boolean
 * @on 選択可
 * @off 選択不可
 * @default false
 *
 * @param atcode
 * @text --- 特徴および使用効果コードID ---
 *
 * @param TRAIT_ACTOR_COMMAND
 * @desc 他のプラグインと競合を起こす場合以外は変更しないでください。
 * @default 200
 * @type number
 * @min 0
 * @parent atcode
 *
 * @help
 *-----------------------------------------------------------------------------
 * 概要
 *-----------------------------------------------------------------------------
 * アクターのバトルコマンドを変更します。
 * 変更可能な項目は以下の通りです。
 *
 * 1．パーティーコマンドやアクターコマンドにアイコンや説明文を表示できます。
 * 2．パーティーコマンドの表示内容や順番を設定できます。
 * 3．アクターコマンドの表示内容をアクター毎に設定できます。
 * 4. アクターコマンドに直接スキルを設定できます。
 *
 * プラグインの使い方は、下のオンラインマニュアルページを見てください。
 * https://github.com/futokoro/RPGMaker/blob/master/FTKR_ExBattleCommand.ja.md
 *
 *
 *-----------------------------------------------------------------------------
 * 設定方法
 *-----------------------------------------------------------------------------
 * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して
 *    ください。
 *
 * 2. 本プラグインは、FTKR_BattleCommandIcon.jsと組み合わせて使用できません。
 *
 * 3. 以下のプラグインと組み合わせる場合は、プラグイン管理の順番に注意してください。
 *
 *    FTKR_AlternatingTurnBattle.js
 *    ↑このプラグインよりも上に登録↑
 *    FTKR_ExBattleCommand.js
 *    ↓このプラグインよりも下に登録↓
 *    FTKR_BattleActionPoints.js
 *    FTKR_DisplayCommandFrame.js
 *
 *
 * -----------------------------------------------------------------------------
 * 本プラグインのライセンスについて(License)
 *-----------------------------------------------------------------------------
 * 本プラグインはMITライセンスのもとで公開しています。
 * This plugin is released under the MIT License.
 *
 * Copyright (c) 2017,2018 Futokoro
 * http://opensource.org/licenses/mit-license.php
 *
 *
 * プラグイン公開元
 * https://github.com/futokoro/RPGMaker/blob/master/README.md
 *
 *-----------------------------------------------------------------------------
 * 変更来歴
 *-----------------------------------------------------------------------------
 *
 * v2.2.2 - 2020/01/03 : 機能追加、不具合修正
 *    1. 空欄コマンドのカーソル選択をプラグインパラメータで設定する機能を追加。
 *    2. カーソル選択不可設定の場合でコマンドが２列以上の場合に、カーソル移動で
 *       空欄部を飛ばす処理が正しく動作しない不具合を修正。
 *    3. カーソル選択不可設定の場合でタッチ操作の場合に、空欄部をタッチしてカーソルを
 *       移動できてしまう不具合を修正。
 *
 * v2.2.1 - 2019/12/29 : 機能追加
 *    1. パーティーコマンドのカスタムコマンドに、指定したコモンイベントを実行する
 *       機能(実行時にターン進行しない)を追加。
 *
 * v2.2.0 - 2019/12/29 : 機能追加
 *    1. パーティーコマンドのカスタムコマンドに、指定したコモンイベントを実行する
 *       機能(実行時にターン進行)を追加。
 *
 * v2.1.0 - 2019/12/24 : 機能追加
 *    1. パーティーコマンドやアクターコマンドに空欄(カーソル選択不可)を空ける機能を追加。
 *          ⇒ v2.2.2 にて選択不可かどうかはプラグインパラメータで選択に変更。
 *
 * v2.0.1 - 2018/12/11 : 不具合修正、ヘルプ削除
 *    1. パーティーコマンドに追加コマンドを設定するとエラーになる不具合を修正。
 *
 * v2.0.0 - 2018/12/10 : 仕様見直し
 *    1. データベースのスキルを使って、コマンドのアイコンや説明文を設定するように変更。
 *    2. アクターコマンドの設定方法を変更。（タグ変更、プラグインパラメータ削除）
 *    2. カスタムコマンドの表示条件を設定する機能を削除。
 *    3. コストを表示する機能を削除。
 *
 * v1.2.2 - 2018/10/09 : 不具合修正
 *    1. 説明文を表示した状態でパーティーコマンドを表示させた場合に、説明文が
 *       そのまま残ってしまう不具合を修正。
 *
 * v1.2.1 - 2018/10/05 : 不具合修正
 *    1. カスタムコマンドのコストを非表示にしていても、コマンド名が左右につぶれて
 *       表示してしまう不具合を修正。
 *
 * v1.2.0 - 2018/10/05 : 機能追加
 *    1. カスタムコマンド選択時にスキルに設定した説明文を表示する機能を追加。
 *
 * v1.1.0 - 2018/04/09 : 機能追加
 *    1. FTKR_AlternatingTurnBattle.jsの v1.1.0 に対応。
 *    2. パーティーコマンドの表示順番を設定する機能を追加。
 *    3. カスタムコマンドのコストを表示する機能を追加。
 *
 * v1.0.1 - 2018/03/27 : 不具合修正、ヘルプ修正
 *    1.複数の特徴欄で同じスキルタイプを追加したときに、コマンドが重複して
 *      表示してしまう不具合を修正。
 *
 * v1.0.0 - 2017/11/25 : 初版作成
 *
 *-----------------------------------------------------------------------------
*/
//=============================================================================
/*~struct~party:
 * @param fight
 * @desc 「戦う」コマンドを設定します。
 * @type struct<command>
 * @default
 *
 * @param escape
 * @desc 「逃げる」コマンドを設定します。
 * @type struct<command>
 * @default
 *
 * @param customs
 * @desc 追加するパーティーコマンドを設定します。
 * @type struct<custom>[]
 * @default
*/
/*~struct~command:
 * @param enabled
 * @desc コマンドの実行条件
 * コマンドの仕様に合わせてください。
 * @default
 *
 * @param ext
 * @desc コマンドの拡張パラメータ
 * コマンドの仕様に合わせてください。
 * @default
 *
 * @param skillId
 * @desc コマンドのスキルID
 * 0 は スキル未指定
 * @type number
 * @min 0
 * @default
*/
/*~struct~custom:
 * @param name
 * @desc コマンドの表示名
 * コマンドの仕様に合わせてください。
 * @default
 *
 * @param symbol
 * @desc コマンドのシンボル
 * コマンドの仕様に合わせてください。
 * @default
 *
 * @param enabled
 * @desc コマンドの実行条件
 * コマンドの仕様に合わせてください。
 * @default
 *
 * @param ext
 * @desc コマンドの拡張パラメータ
 * コマンドの仕様に合わせてください。
 * @default
 *
 * @param skillId
 * @desc コマンドの説明用スキルID
 * 0 は スキル未指定
 * @type number
 * @min 0
 * @default
 *
 * @param show
 * @desc コマンドの表示条件
 * コマンドの仕様に合わせてください。
 * @default
 *
*/

(function() {

    var paramParse = function(obj) {
        return JSON.parse(JSON.stringify(obj, paramReplace));
    }

    var paramReplace = function(key, value) {
        try {
            return JSON.parse(value || null);
        } catch (e) {
            return value;
        }
    };

    var readMetadata = function(data, metacode, traitCode) {
        var re = /<([^<>:]+)(:?)[ ]*([^>]*)>/g;
        for (;;) {
            var match = re.exec(data.note);
            if (match) {
                if (metacode === match[1].toUpperCase()) {
                    var text = match[3];
                    var times = text.split(' ');
                    data.traits.push({
                        code     : Game_BattlerBase[traitCode],
                        dataId   : times[0],
                        ext      : times[1] || '',
                        enabled  : times[2] || 'true',       //enabled
                        skillId  : Number(times[3]) || 0,    //skillId
                        priority : Number(times[4]) || 0,
                    });
                }
            } else {
                break;
            }
        }
    };

    var readObjectMeta = function(obj, metacodes, traitCode) {
        if (!obj) return false;
        metacodes.forEach(function(metacode){
            readMetadata(obj, metacode, traitCode);
        });
    };

    var removeEndBlankCommand = function(list) {
        while(list[0].symbol == "blank"){
            list.shift();
        };
        while(list[list.length-1].symbol == "blank"){
            list.pop();
        };
    };

    //=============================================================================
    // プラグイン パラメータ
    //=============================================================================
    var parameters = PluginManager.parameters('FTKR_ExBattleCommand');

    FTKR.EBC = {
        partyCmdList    : paramParse(parameters['Party Command List']),
        partyCmds       : paramParse(parameters['Party Commands']),
        showCommandIcon : paramParse(parameters['Show Command Icon']) || false,
        showCommandDesc : paramParse(parameters['Show Command Description']) || false,
        enableSelectBlank : paramParse(parameters['Enable Select Blank']) || false,
    };

    Game_BattlerBase.TRAIT_ACTOR_COMMAND = +(paramParse(parameters['TRAIT_ACTOR_COMMAND']));

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

    var _EBC_DatabaseLoaded = false;
    var _EBC_DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
    DataManager.isDatabaseLoaded = function() {
        if (!_EBC_DataManager_isDatabaseLoaded.call(this)) return false;
        if (!_EBC_DatabaseLoaded) {
            this.ebcTraitNoteTags($dataActors);
            this.ebcTraitNoteTags($dataClasses);
            this.ebcTraitNoteTags($dataWeapons);
            this.ebcTraitNoteTags($dataArmors);
            this.ebcTraitNoteTags($dataStates);
            _EBC_DatabaseLoaded = true;
        }
        return true;
    };

    DataManager.ebcTraitNoteTags = function(group) {
        for (var n = 1; n < group.length; n++) {
            var obj = group[n];
            readObjectMeta(obj, ['FTKR_ACTOR_COMMAND'], 'TRAIT_ACTOR_COMMAND');
        }
    };

    //=============================================================================
    // BattleManager
    //=============================================================================

    BattleManager.processEbcEvent = function(eventId) {
        $gameTroop.setupEbcBattleEvent(eventId);
        $gameParty.clearActions();
        this.startTurn();
    };

    BattleManager.processEbcEventB = function(eventId) {
        $gameTroop.setupEbcBattleEvent(eventId);
        this._phase = 'start';
    };

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

    Game_Actor.prototype.battleCommands = function() {
        return this.traits(Game_BattlerBase.TRAIT_ACTOR_COMMAND);
    };

    Game_Actor.prototype.sortBattleCommands = function() {
        return this.battleCommands().sort(function(a, b) {
            var p1 = a.priority;
            var p2 = b.priority;
            if (p1 !== p2) {
                return p2 - p1;
            }
            return a - b;
        });
    };

    //=============================================================================
    // Window_Command
    //=============================================================================

    Window_Command.prototype.drawBattleCommand = function(index, rect, align) {
        var x1 = this.drawBattleCommandIcon(index, rect.x, rect.y);
        this.drawBattleCommandName(index, rect.x + x1, rect.y, rect.width - x1, align);
    };

    Window_Command.prototype.drawBattleCommandIcon = function(index, x, y) {
        if (FTKR.EBC.showCommandIcon) {
            var skill = this.commandEbcSkill(index);
            if (skill) {
                var iconIndex = skill.iconIndex;
                if (iconIndex) {
                    this.drawIcon(iconIndex, x, y + 2);
                    return Window_Base._iconWidth + 2;
                }
            }
        }
        return 0;
    };

    Window_Command.prototype.drawBattleCommandName = function(index, x, y, width, align) {
        this.drawText(this.commandName(index), x, y, width, align);
    };

    Window_Command.prototype.addEbcCommand = function(name, symbol, enabled, ext, skillId) {
        if (enabled === null) {
            enabled = true;
        }
        if (skillId === null) {
            skillId = 0;
        }
        this._list.push({ name: name, symbol: symbol, enabled: enabled, ext: ext, skillId:skillId});
    };

    Window_Command.prototype.commandEbcSkillId = function(index) {
        return this._list[index].skillId;
    };

    Window_Command.prototype.currentEbcSkillId = function() {
        return this.currentData() ? this.currentData().skillId : null;
    };

    Window_Command.prototype.findEbcSkillId = function(skillId) {
        for (var i = 0; i < this._list.length; i++) {
            if (this._list[i].skillId === skillId) {
                return i;
            }
        }
        return 0;
    };

    Window_Command.prototype.isActionSkillCommand = function(index) {
        return ['attack', 'guard', 'custom'].contains(this.commandSymbol(index));
    };

    Window_Command.prototype.commandEbcSkill = function(index) {
        return this.ebcDataSkill(this.commandEbcSkillId(index));
    };

    Window_Command.prototype.ebcDataSkill = function(skillId) {
        return skillId > 0 ? $dataSkills[skillId] : null;
    };

    Window_Command.prototype.currentEbcSkill = function() {
        return this.ebcDataSkill(this.currentEbcSkillId());
    };

    Window_Command.prototype.isEbcCommandEnabled = function(index) {
        return eval(this._list[index].enabled);
    };

    Window_Command.prototype.isEbcCurrentItemEnabled = function() {
        return this.currentData() ? eval(this.currentData().enabled) : false;
    };

    Window_Command.prototype.addEbcBlankCommand = function() {
        this.addEbcCommand('', 'blank', false, null, null);
    };

    Window_Command.prototype.isEbcBlankCommand = function(index) {
        return this.commandSymbol(index) == 'blank';
    }

    Window_Command.prototype.updateEbcSkillHelp = function() {
        var item = this.currentEbcSkill();
        this.setHelpWindowItem(item);
        if (item && item.description) {
            this.showHelpWindow();
        } else {
            this.hideHelpWindow();
        }
    };

    Window_Command.prototype.selectEbc = function(index) {
        if (!this.isEbcBlankCommand(index)) {
            this.select(index);
            return true;
        }
        return false;
    };

    Window_Command.prototype.cursorDownEbc = function(wrap) {
        var index = this.index();
        var maxItems = this.maxItems();
        var maxCols = this.maxCols();
        var maxRows = Math.ceil(maxItems / maxCols);
        for (var i = 1; i < maxRows + 1; i++){
            var newIndex = index + maxCols * i;
            if (newIndex < maxItems || (wrap && maxCols === 1)){
                if (this.selectEbc(newIndex % maxItems)) return;
            }
        }
    };

    Window_Command.prototype.cursorUpEbc = function(wrap) {
        var index = this.index();
        var maxItems = this.maxItems();
        var maxCols = this.maxCols();
        var maxRows = Math.ceil(maxItems / maxCols);
        for (var i = 1; i < maxRows + 1; i++){
            var newIndex = index - maxCols * i;
            if (newIndex >= 0 || (wrap && maxCols === 1)){
                if (this.selectEbc((newIndex + maxItems) % maxItems)) return;
            }
        }
    };

    Window_Command.prototype.cursorRightEbc = function(wrap) {
        if (this.maxCols() >= 2) {
            for (var i = this.index(); i < this.maxItems() - 1;) {
                i++
                if (this.selectEbc(i)) return;
            }
        }
    };

    Window_Command.prototype.cursorLeftEbc = function(wrap) {
        if (this.maxCols() >= 2) {
            for (var i = this.index(); i > 0;) {
                i--
                if (this.selectEbc(i)) return;
            }
        }
    };

    Window_Command.prototype.disableTouchCommand = function(triggered) {
        var x = this.canvasToLocalX(TouchInput.x);
        var y = this.canvasToLocalY(TouchInput.y);
        var hitIndex = this.hitTest(x, y);
        return hitIndex >= 0 && this.isEbcBlankCommand(hitIndex) && !FTKR.EBC.enableSelectBlank;
    };

    //=============================================================================
    // Window_PartyCommand
    //=============================================================================

    var _EBC_Window_PartyCommand_initalize = Window_PartyCommand.prototype.initialize;
    Window_PartyCommand.prototype.initialize = function() {
        _EBC_Window_PartyCommand_initalize.call(this);
        this._windowType = 'party';
    };

    Window_PartyCommand.prototype.addEbcFightCommand = function() {
        var cmd = FTKR.EBC.partyCmds.fight;
        this.addEbcCommand(TextManager.fight, 'fight', cmd.enabled, cmd.ext, cmd.skillId);
    };

    Window_PartyCommand.prototype.addEbcEscapeCommand = function() {
        var cmd = FTKR.EBC.partyCmds.escape;
        this.addEbcCommand(TextManager.escape, 'escape', cmd.enabled, cmd.ext, cmd.skillId);
    };

    Window_PartyCommand.prototype.addEbcCustomCommand = function(symbol) {
        if (!symbol) return;
        var match = /custom(\d+)/i.exec(symbol);
        if (!match) return;
        var cmd = FTKR.EBC.partyCmds.customs[Number(match[1])-1];
        if (this.includeEbc(cmd)) {
            this.addEbcCommand(cmd.name, cmd.symbol, cmd.enabled, cmd.ext, cmd.skillId);
        }
    };

    Window_PartyCommand.prototype.includeEbc = function(command) {
        return command.show && eval(command.show) || !command.show;
    };

    var _EBC_Window_PartyCommand_makeCommandList = Window_PartyCommand.prototype.makeCommandList;
    Window_PartyCommand.prototype.makeCommandList = function() {
        if (this.isEbcCommandOk()) {
            this.makeEbcCommandList();
        }else {
            _EBC_Window_PartyCommand_makeCommandList.call(this);
        }
    };

    Window_PartyCommand.prototype.isEbcCommandOk = function() {
        return FTKR.EBC.partyCmdList;
    };

    Window_PartyCommand.prototype.makeEbcCommandList = function() {
        FTKR.EBC.partyCmdList.split(',').forEach(function(symbol){
            this.makeEbcCommand(symbol);
        },this);
    //  removeEndBlankCommand(this._list);
    };

    Window_PartyCommand.prototype.makeEbcCommand = function(symbol) {
        switch(symbol.toUpperCase()) {
            case 'FIGHT':
                return this.addEbcFightCommand();
            case 'ESCAPE':
                return this.addEbcEscapeCommand();
            case 'BLANK':
                return this.addEbcBlankCommand();
            default:
                return this.addEbcCustomCommand(symbol);
        }
    };

    //書き換え
    Window_PartyCommand.prototype.isCommandEnabled = function(index) {
        return this.isEbcCommandEnabled(index);
    };

    //書き換え
    Window_PartyCommand.prototype.isCurrentItemEnabled = function() {
        return this.isEbcCurrentItemEnabled();
    };

    //書き換え
    Window_PartyCommand.prototype.updateHelp = function() {
        this.updateEbcSkillHelp();
    };

    //書き換え
    Window_PartyCommand.prototype.drawItem = function(index) {
        var rect = this.itemRectForText(index);
        var align = this.itemTextAlign();
        this.resetTextColor();
        this.changePaintOpacity(this.isCommandEnabled(index));
        this.drawBattleCommand(index, rect, align);
    };

    var _EBC_Window_PartyCommand_cursorDown = Window_PartyCommand.prototype.cursorDown;
    Window_PartyCommand.prototype.cursorDown = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorDownEbc(wrap);
        } else {
            _EBC_Window_PartyCommand_cursorDown.call(this, wrap);
        }
    };

    var _EBC_Window_PartyCommand_cursorUp = Window_PartyCommand.prototype.cursorUp;
    Window_PartyCommand.prototype.cursorUp = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorUpEbc(wrap);
        } else {
            _EBC_Window_PartyCommand_cursorUp.call(this, wrap);
        }
    };

    var _EBC_Window_PartyCommand_cursorRight = Window_PartyCommand.prototype.cursorRight;
    Window_PartyCommand.prototype.cursorRight = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorRightEbc(wrap);
        } else {
            _EBC_Window_PartyCommand_cursorRight.call(this, wrap);
        }
    };

    var _EBC_Window_PartyCommand_cursorLeft = Window_PartyCommand.prototype.cursorLeft;
    Window_PartyCommand.prototype.cursorLeft = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorLeftEbc(wrap);
        } else {
            _EBC_Window_PartyCommand_cursorLeft.call(this, wrap);
        }
    };

    var _EBC_Window_PartyCommand_onTouch = Window_PartyCommand.prototype.onTouch;
    Window_PartyCommand.prototype.onTouch = function(triggered) {
        if (this.disableTouchCommand(triggered)) return;
        _EBC_Window_PartyCommand_onTouch.call(this, triggered);
    };

    //=============================================================================
    // Window_ActorCommand
    //=============================================================================

    var _EBC_Window_ActorCommand_initalize = Window_ActorCommand.prototype.initialize;
    Window_ActorCommand.prototype.initialize = function() {
        _EBC_Window_ActorCommand_initalize.call(this);
        this._windowType = 'actor';
    };

    //書き換え
    Window_ActorCommand.prototype.addEbcAttackCommand = function(cmd) {
        this.addEbcCommand(TextManager.attack, 'attack', cmd.enabled, cmd.ext, cmd.skillId);
    };

    Window_ActorCommand.prototype.addEbcSkillCommand = function(cmd) {
        var stypeId = Number(cmd.ext);
        var name = $dataSystem.skillTypes[stypeId];
        this.addEbcCommand(name, 'skill', cmd.enabled, stypeId, cmd.skillId);
    };

    //書き換え
    Window_ActorCommand.prototype.addEbcGuardCommand = function(cmd) {
        this.addEbcCommand(TextManager.guard, 'guard', cmd.enabled, cmd.ext, cmd.skillId);
    };

    //書き換え
    Window_ActorCommand.prototype.addEbcItemCommand = function(cmd) {
        this.addEbcCommand(TextManager.item, 'item', cmd.enabled, cmd.ext, cmd.skillId);
    };

    //書き換え
    Window_ActorCommand.prototype.isCommandEnabled = function(index) {
        return this.isEbcCommandEnabled(index);
    };

    //書き換え
    Window_ActorCommand.prototype.isCurrentItemEnabled = function() {
        return this.isEbcCurrentItemEnabled();
    };

    //書き換え
    Window_ActorCommand.prototype.updateHelp = function() {
        this.updateEbcSkillHelp();
    };

    //書き換え
    Window_ActorCommand.prototype.drawItem = function(index) {
        var rect = this.itemRectForText(index);
        var align = this.itemTextAlign();
        this.resetTextColor();
        this.changePaintOpacity(this.isCommandEnabled(index));
        this.drawBattleCommand(index, rect, align);
    };

    var _EBC_Window_ActorCommand_makeCommandList = Window_ActorCommand.prototype.makeCommandList;
    Window_ActorCommand.prototype.makeCommandList = function() {
        if (this._actor) {
            if (this.isEbcCommandOk()) {
                this.makeEbcCommandList();
            } else {
                _EBC_Window_ActorCommand_makeCommandList.call(this);
            }
        }
    };

    Window_ActorCommand.prototype.isEbcCommandOk = function() {
        return this._actor && this._actor.sortBattleCommands().length;
    };

    Window_ActorCommand.prototype.makeEbcCommandList = function() {
        this._actor.sortBattleCommands().forEach(function(cmd, i){
            this.makeEbcCommand(cmd);
        },this);
//                removeEndBlankCommand(this._list);
    };

    Window_ActorCommand.prototype.makeEbcCommand = function(cmd) {
        switch(cmd.dataId.toUpperCase()) {
            case 'CUSTOM':
                return this.addCustomCommand(cmd);
            case 'ATTACK':
                return this.addEbcAttackCommand(cmd);
            case 'GUARD':
                return this.addEbcGuardCommand(cmd);
            case 'SKILL':
                return this.addEbcSkillCommand(cmd);
            case 'ITEM':
                return this.addEbcItemCommand(cmd);
            case 'BLANK':
                return this.addEbcBlankCommand();
        }
    };

    Window_ActorCommand.prototype.addCustomCommand = function(cmd) {
        var skill = this.ebcDataSkill(cmd.skillId);
        var enabled = cmd.enabled + '&&this._actor.canUse(this.ebcDataSkill(' + cmd.skillId + '))';
        this.addEbcCommand(skill.name, 'custom', enabled, cmd.skillId, cmd.skillId);
    };

    var _EBC_Window_ActorCommand_selectLast = Window_ActorCommand.prototype.selectLast;
    Window_ActorCommand.prototype.selectLast = function() {
        _EBC_Window_ActorCommand_selectLast.call(this);
        this.selectLastEbc();
    };

    Window_ActorCommand.prototype.selectLastEbc = function() {
        if (this._actor && ConfigManager.commandRemember) {
            var symbol = this._actor.lastCommandSymbol();
            if (symbol === 'custom') {
                var skill = this._actor.lastBattleSkill();
                if (skill) {
                    this.selectExt(skill.id);
                }
            }
        }
    };

    var _EBC_Window_ActorCommand_cursorDown = Window_ActorCommand.prototype.cursorDown;
    //書き換え
    Window_ActorCommand.prototype.cursorDown = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorDownEbc(wrap);
        } else {
            _EBC_Window_ActorCommand_cursorDown.call(this, wrap);
        }
    };

    var _EBC_Window_ActorCommand_cursorUp = Window_ActorCommand.prototype.cursorUp;
    //書き換え
    Window_ActorCommand.prototype.cursorUp = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorUpEbc(wrap);
        } else {
            _EBC_Window_ActorCommand_cursorUp.call(this, wrap);
        }
    };

    var _EBC_Window_ActorCommand_cursorRight = Window_ActorCommand.prototype.cursorRight;
    //書き換え
    Window_ActorCommand.prototype.cursorRight = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorRightEbc(wrap);
        } else {
            _EBC_Window_ActorCommand_cursorRight.call(this, wrap);
        }
    };

    var _EBC_Window_ActorCommand_cursorLeft = Window_ActorCommand.prototype.cursorLeft;
    //書き換え
    Window_ActorCommand.prototype.cursorLeft = function(wrap) {
        if (!FTKR.EBC.enableSelectBlank) {
            this.cursorLeftEbc(wrap);
        } else {
            _EBC_Window_ActorCommand_cursorLeft.call(this, wrap);
        }
    };

    var _EBC_Window_ActorCommand_onTouch = Window_ActorCommand.prototype.onTouch;
    Window_ActorCommand.prototype.onTouch = function(triggered) {
        if (this.disableTouchCommand(triggered)) return;
        _EBC_Window_ActorCommand_onTouch.call(this, triggered);
    };

    //=============================================================================
    // Scene_Battle
    //=============================================================================

    // パーティーコマンドの修正
    var _EBC_Scene_Battle_createPartyCommandWindow = Scene_Battle.prototype.createPartyCommandWindow;
    Scene_Battle.prototype.createPartyCommandWindow = function() {
        _EBC_Scene_Battle_createPartyCommandWindow.call(this);
        this._partyCommandWindow.setHandler('event', this.commandEvent.bind(this));
        this._partyCommandWindow.setHandler('eventB', this.commandEventB.bind(this));
    };

    Scene_Battle.prototype.commandEvent = function() {
        var commonEventId = this._partyCommandWindow.currentExt();
        BattleManager.processEbcEvent(commonEventId);
        this.changeInputWindow();
    };

    Scene_Battle.prototype.commandEventB = function() {
        var commonEventId = this._partyCommandWindow.currentExt();
        BattleManager.processEbcEventB(commonEventId);
        this.changeInputWindow();
    };

    var _Scene_Battle_endCommandSelection = Scene_Battle.prototype.endCommandSelection;
    Scene_Battle.prototype.endCommandSelection = function() {
        _Scene_Battle_endCommandSelection.call(this);
        this._actorCommandWindow.hideHelpWindow();
    };

    // アクターコマンドの修正
    var _EBC_Scene_Battle_createActorCommandWindow = Scene_Battle.prototype.createActorCommandWindow;
    Scene_Battle.prototype.createActorCommandWindow = function() {
        _EBC_Scene_Battle_createActorCommandWindow.call(this);
        this._actorCommandWindow.setHandler('custom', this.commandCustom.bind(this));
    };

    Scene_Battle.prototype.commandCustom = function() {
        var skill = this._actorCommandWindow.currentEbcSkill();
        var action = BattleManager.inputtingAction();
        action.setSkill(skill.id);
        BattleManager.actor().setLastBattleSkill(skill);
        this.onSelectAction();
    };

    // ヘルプウィンドウの修正
    var _EBC_Scene_Battle_createHelpWindow = Scene_Battle.prototype.createHelpWindow;
    Scene_Battle.prototype.createHelpWindow = function() {
        _EBC_Scene_Battle_createHelpWindow.call(this);
        if (FTKR.EBC.showCommandDesc) {
            this._partyCommandWindow.setHelpWindow(this._helpWindow);
            this._actorCommandWindow.setHelpWindow(this._helpWindow);
        }
    };

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

    // スキルタイプ重複表示の不具合修正
    Game_BattlerBase.prototype.addedSkillTypes = function() {
        return this.traitsSet(Game_BattlerBase.TRAIT_STYPE_ADD).filter(function(x, i, self) {
            return self.indexOf(x) === i;
        });
    };

    //=============================================================================
    // Game_Troop
    //=============================================================================

    // 指定したコモンイベントをセット
    Game_Troop.prototype.setupEbcBattleEvent = function(eventId) {
        if (!this._interpreter.isRunning()) {
            if (this._interpreter.setupReservedCommonEvent()) {
                return false;
            }
            var event = $dataCommonEvents[eventId];
            if (event) {
                this._interpreter.setup(event.list, this.troop().id);
                return true;
            }
        }
        return false;
    };

}());//EOF


code:
//=============================================================================
// バトルイベントを拡張するプラグイン
// FTKR_ExBattleEvent.js
// プラグインNo : 40
// 作成者     : フトコロ
// 作成日     : 2017/05/25
// 最終更新日 : 2020/03/02
// バージョン : v1.3.6
//=============================================================================

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

var FTKR = FTKR || {};
FTKR.EBE = FTKR.EBE || {};

/*:
 * @plugindesc v1.3.6 バトルイベントを拡張するプラグイン
 * @author フトコロ
 *
 * @param Battle Event
 * @desc 戦闘中に実行するコモンイベントID
 * 0 - 実行しない、カンマ(,)で区切って複数設定できます
 * @default
 *
 * @param --勝利時イベント--
 * @desc
 *
 * @param Custom Victory Event
 * @desc 戦闘勝利時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Victory Event
 * @desc 戦闘勝利時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param --敗北時イベント--
 * @desc
 *
 * @param Custom Defeat Event
 * @desc 戦闘敗北時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Defeat Event
 * @desc 戦闘敗北時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param --逃走時イベント--
 * @desc
 *
 * @param Custom Escape Event
 * @desc 戦闘逃走時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Escape Event
 * @desc 戦闘逃走時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param --中断時イベント--
 * @desc
 *
 * @param Custom Abort Event
 * @desc 戦闘中断時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Abort Event
 * @desc 戦闘中断時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param Abort BugFix
 * @desc コアスクリプトにおける戦闘中断時のバグ修正を行う。他のプラグインと競合する場合は、無効にしてください。
 * @type boolean
 * @on 有効
 * @off 無効
 * @default false
 *
 * @param --戦闘行動の強制--
 * @desc
 *
 * @param Invalid Battle Phase
 * @desc ここで規定したバトルフェーズ中に戦闘行動の強制が有効になる。複数規定する場合はカンマ(,)で区切る。
 * @default action
 *
 * @help
 *-----------------------------------------------------------------------------
 * 概要
 *-----------------------------------------------------------------------------
 * 本プラグインを実装することで、バトル終了時または中断時に
 * 指定したイベントを実行します。
 *
 * 実行可能なタイミング
 *      １．勝利時（敵が全滅した後）
 *      ２．敗北時（パーティーが全滅した後）
 *      ３．逃走時（パーティーコマンド「逃げる」やスキルの逃げる効果使用後）
 *      ４．中断時（イベントコマンド「バトルの中断」実行後）
 *
 * 戦闘終了時のイベントの処理が終了すると、バトル画面が終了します。
 *
 *
 * プラグインの使い方は、下のオンラインマニュアルページを見てください。
 * https://github.com/futokoro/RPGMaker/blob/master/FTKR_ExBattleEvent.ja.md
 *
 *
 *-----------------------------------------------------------------------------
 * 設定方法
 *-----------------------------------------------------------------------------
 * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して
 *    ください。
 *
 * 2. 以下のプラグインと組み合わせる場合は、プラグイン管理の順番に注意してください。
 *
 *    FTKR_CSS_CustomizeBattleResults.js
 *    ↑このプラグインよりも上に登録↑
 *    FTKR_ExBattleEvent.js
 *    ↓このプラグインよりも下に登録↓
 *    FTKR_ExVariablesChange.js
 *
 *
 *-----------------------------------------------------------------------------
 * 本プラグインのライセンスについて(License)
 *-----------------------------------------------------------------------------
 * 本プラグインはMITライセンスのもとで公開しています。
 * This plugin is released under the MIT License.
 *
 * Copyright (c) 2019 Futokoro
 * http://opensource.org/licenses/mit-license.php
 *
 *
 * プラグイン公開元
 * https://github.com/futokoro/RPGMaker/blob/master/README.md
 *
 *
 *-----------------------------------------------------------------------------
 * 変更来歴
 *-----------------------------------------------------------------------------
 *
 * v1.3.6 - 2020/03/02 : 機能追加
 *    1. 逃走時と中断時に指定のイベントを実行する機能を追加。
 *
 * v1.3.5 - 2020/01/15 : 不具合修正
 *    1. 戦闘終了時イベントで「戦闘行動の強制」を実行できない不具合を修正。
 *
 * v1.3.4 - 2019/12/29 : 仕様見直し
 *    1. 戦闘終了時イベントの実行処理を見直し。
 *
 * v1.3.3 - 2018/02/19 : 不具合修正
 *    1. Custom Victory Eventが0の時に、戦闘勝利イベントを実行すると
 *       戦闘勝利回数が2回増加してしまう不具合を修正。
 *
 * v1.3.2 - 2018/01/13 : 機能追加
 *    1. メッセージ表示関係のプラグインコマンドに、イベント処理を止める機能を追加。
 *
 * v1.3.1 - 2018/01/12 : 不具合修正
 *    1. 戦闘終了時イベント中にウェイトコマンドを実行すると、アクターの
 *       モーションが正常に再生されない不具合を修正。
 *
 * v1.3.0 - 2017/06/30 : 機能追加
 *    1. 戦闘終了時のイベントの後に、MVデフォルトの戦闘終了処理を実行する
 *       機能を追加。
 *
 * v1.2.0 - 2017/06/01 : 機能追加
 *    1. 敵キャラの戦闘行動を再設定するプラグインコマンドを追加。
 *
 * v1.1.0 - 2017/05/26 : 機能追加
 *    1. バトル中にコモンイベントを実行できる機能を追加。
 *    2. モーション実行コマンドにアクターを対象にできる機能を追加。
 *    3. 画面に数字をポップアップさせるプラグインコマンドを追加。
 *
 * v1.0.0 - 2017/05/25 : 初版作成
 *
 *-----------------------------------------------------------------------------
*/
//=============================================================================

var paramParse = function(obj) {
    return JSON.parse(JSON.stringify(obj, paramReplace));
}

var paramReplace = function(key, value) {
    try {
        return JSON.parse(value || null);
    } catch (e) {
        return value;
    }
};

var matchTextToRegs = function(test, regs) {
    return regs.some( function(reg){
        return test.match(reg);
    });
};

var readCommentMeta = function(comment, metacodes) {
    if (!comment) return false;
    return metacodes.some(function(metacode){
        var metaReg = new RegExp('<' + metacode + '>', 'i');
        return metaReg.test(comment);
    });
};

var splitConvertNumber = function(param) {
    var results = [];
    (param + '').split(',').forEach( function(split){
        match = /[ ]*(\d+)[ ]*-[ ]*(\d+)/.exec(split);
        if (match) {
            for (var i = Number(match[1]); i <= Number(match[2]); i++) {
                results.push(i);
            }
        } else {
            if(!isNaN(split)) results.push(Number(split));
        }
    });
    return results;
};

// textを条件式に使える状態に変換する
var convertTextToConditions = function(text) {
    var result = '';
    if (text) {
        var datas = text.split(';');
        datas.forEach(function(data, i) {
            result += data;
            if (datas[i+1]) result += ')&&(';
        });
        result = '(' + result + ')';
    }
    return result;
};

var convertEscapeCharacters = function(text) {
    if (text == null) text = '';
    var window = SceneManager._scene._windowLayer.children[0];
    return window ? window.convertEscapeCharacters(text) : text;
};

//=============================================================================
// 自作関数(グローバル)
//=============================================================================

FTKR.gameData = FTKR.gameData || {
    user   :null,
    target :null,
    item   :null,
    number :0,
};

if (!FTKR.setGameData) {
FTKR.setGameData = function(user, target, item, number) {
    FTKR.gameData = {
        user   :user || null,
        target :target || null,
        item   :item || null,
        number :number || 0
    };
};
}

if (!FTKR.evalFormula) {
FTKR.evalFormula = function(formula) {
    var datas = FTKR.gameData;
    try {
        var s = $gameSwitches._data;
        var v = $gameVariables._data;
        var a = datas.user;
        var b = datas.target;
        var item   = datas.item;
        var number = datas.number;
        if (b) var result = b.result();
        var value = eval(formula);
        if (isNaN(value)) value = 0;
        return value;
    } catch (e) {
        console.error(e);
        return 0;
    }
};
}

//=============================================================================
// プラグイン パラメータ
//=============================================================================
var parameters = PluginManager.parameters('FTKR_ExBattleEvent');

FTKR.EBE.battleEvents = splitConvertNumber(parameters['Battle Event']);
FTKR.EBE.battleEnd = {
    victory : paramParse(parameters['Victory Event'] || 0),
    customV : paramParse(parameters['Custom Victory Event'] || 0),
    defeat  : paramParse(parameters['Defeat Event'] || 0),
    customD : paramParse(parameters['Custom Defeat Event'] || 0),
    escape  : paramParse(parameters['Escape Event'] || 0),
    customE : paramParse(parameters['Custom Escape Event'] || 0),
    abort   : paramParse(parameters['Abort Event'] || 0),
    customA : paramParse(parameters['Custom Abort Event'] || 0),
    abortBF : paramParse(parameters['Abort BugFix'] || false),
    invalid : parameters['Invalid Battle Phase'] || '',
};

//=============================================================================
// プラグインコマンド
//=============================================================================

Game_Interpreter.prototype.setArgNumber = function(arg) {
    try {
        var arg = convertEscapeCharacters(arg);
        return Number(eval(arg));
    } catch (e) {
        console.error(e);
        return 0;
    }
};

var _EBE_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    _EBE_Game_Interpreter_pluginCommand.call(this, command, args);
    if (!command.match(/EBE_(.+)/i)) return;
    command = (RegExp.$1 + '').toUpperCase();
    switch (command) {
        case '戦闘終了時ステート解除':
        case 'REMOVE_BATTLE_STATES':
            $gameParty.removeBattleStates();
            break;
        case '勝利モーション実行':
        case 'PREFORM_VICTORY':
            $gameParty.performVictory();
            break;
        case 'モーション実行':
        case 'REQUEST_MOTION':
            if(!args[1] || args[1] === '全員' || args[1].toUpperCase() === 'ALL') {
                $gameParty.requestMotion(args[0]);
            } else if (Number(args[1]) >= 0) {
                var actor = $gameActors.actor(Number(args[1]));
                if (actor) actor.requestMotion(args[0]);
            }
            break;
        case '勝利ME演奏':
        case 'PLAY_VICTORY_ME':
            BattleManager.playVictoryMe();
            break;
        case '敗北ME演奏':
        case 'PLAY_DEFEAT_ME':
            BattleManager.playDefeatMe();
            break;
        case 'BGMBGS再開':
        case 'REPLAY_BGM_AND_BGS':
            BattleManager.replayBgmAndBgs();
            break;
        case 'BGM停止':
        case 'STOP_BGM':
            AudioManager.stopBgm();
            break;
        case '戦闘報酬計算':
        case 'MAKE_REWARDS':
            BattleManager.makeRewards();
            break;
        case '勝利メッセージ表示':
        case 'DISPLAY_VICTORY_MESSAGE':
            BattleManager.displayVictoryMessage();
            if (args[0] === '-s')this.setWaitMode('message');
            break;
        case '敗北メッセージ表示':
        case 'DISPLAY_DEFEAT_MESSAGE':
            BattleManager.displayDefeatMessage();
            if (args[0] === '-s')this.setWaitMode('message');
            break;
        case '戦闘報酬表示':
        case 'DISPLAY_REWARDS':
            BattleManager.displayRewards();
            if (args[0] === '-s')this.setWaitMode('message');
            break;
        case '戦闘報酬入手':
        case 'GAIN_REWARDS':
            BattleManager.gainRewards();
            break;
        case '戦闘再開':
        case 'RESTART_BATTLE':
            BattleManager._checkEbeBattleEvent = false;
            break;
        case '数字ポップアップ':
        case 'POPUP_NUMBER':
            this.setupNumberPopup(args);
            break;
        case '敵キャラの戦闘行動の設定':
        case 'SET_BATTLE_ENEMY_ACTION':
            var memberId = this.setArgNumber(args[0]);
            $gameTroop.members()[memberId].makeActions();
            break;
    }
};

Game_Interpreter.prototype.setupNumberPopup = function(args) {
    var index = this.setArgNumber(args[0]);
    for (var i = 1; i < args.length; i++) {
        var arg = (args[i] + '').toUpperCase();
        switch (arg) {
            case '画像番号':
            case 'IMAGENUM':
                i++;
                var baseRow = this.setArgNumber(args[i]);
                break;
            case '表示内容':
            case 'VALUE':
                i++;
                var value = this.setArgNumber(args[i]);
                break;
            case 'ポップアップ高さ':
            case 'POPUP_HEIGHT':
                i++;
                var height = this.setArgNumber(args[i]);
                if (!isNaN(args[i+1])) {
                    i++;
                    var offsetY = this.setArgNumber(args[i]);
                }
                break;
            case '表示時間':
            case 'DURATION':
                i++;
                var duration = this.setArgNumber(args[i]);
                break;
            case '表示差':
            case 'DIFF_COUNT':
                i++;
                var maxcount = this.setArgNumber(args[i]);
                break;
            case '表示座標':
            case 'POSITION':
                i++;
                var x = this.setArgNumber(args[i]);
                i++;
                var y = this.setArgNumber(args[i]);
                break;
            case '消去しない':
            case 'REMAIN':
                var remain = true;
                break;
            case '消去':
            case 'ERASE':
                BattleManager.eraseNumberPopup(index);
                return ;
        }
    }
    var sprite = BattleManager.setupNumberPopup(index);
    if (!isNaN(baseRow)) sprite.setBaseRow(baseRow);
    if (!isNaN(height)) sprite.setPopupHeight(height, offsetY);
    if (!isNaN(duration)) sprite.setDuration(duration);
    if (!isNaN(maxcount)) sprite.setMaxcount(maxcount);
    if (!isNaN(x) && !isNaN(y))sprite.setPosition(x, y);
    if (remain) sprite.setRemain();
    if (!isNaN(value)) sprite.setValue(value);
};

//=============================================================================
// BattleManager
//=============================================================================

var _EBE_BattleManager_initMembers = BattleManager.initMembers;
BattleManager.initMembers = function() {
    _EBE_BattleManager_initMembers.call(this);
    this._checkEbeBattleEvent = false;
    this._battleEndPattern = 0;
    this._numberSprite = [];
    this._invalidPhase = FTKR.EBE.battleEnd.invalid.split(',');
};

var _EBE_Game_Party_requestMotionRefresh = Game_Party.prototype.requestMotionRefresh;
Game_Party.prototype.requestMotionRefresh = function() {
    if (!BattleManager.isBattleEndEvent()) {
        _EBE_Game_Party_requestMotionRefresh.call(this);
    }
};

BattleManager.isBattleEndEvent = function() {
    return $gameParty.inBattle() && this._checkEbeBattleEvent;
};

BattleManager.isInvalidPhase = function() {
    return this._invalidPhase.contains(this._phase);
};

var _EBE_BattleManager_updateEvent = BattleManager.updateEvent;
BattleManager.updateEvent = function() {
    if (this.isBattleEndEvent() && !this.isInvalidPhase()) {
        if (this.isActionForced()) {
            this.processForcedAction();
            return true;
        } else {
            return this.updateEventMain();
        }
    } else {
        return _EBE_BattleManager_updateEvent.call(this);
    }
};

var _EBE_BattleManager_checkBattleEnd = BattleManager.checkBattleEnd;
BattleManager.checkBattleEnd = function() {
    if (this.isBattleEndEvent()) {
        this._checkEbeBattleEvent = false;
        switch (this._battleEndPattern) {
            case 0: //勝利
                if (FTKR.EBE.battleEnd.customV) break;
                _EBE_BattleManager_processVictory.call(this);
                return true;
            case 1: //逃走
                if (FTKR.EBE.battleEnd.customE) break;
                _EBE_BattleManager_processAbort.call(this);
                return true;
            case 2: //敗北
                if (FTKR.EBE.battleEnd.customD) break;
                _EBE_BattleManager_processDefeat.call(this);
                return true;
            case 3: //中断
                this._battleEndPattern = 1;
                if (FTKR.EBE.battleEnd.customA) break;
                _EBE_BattleManager_processAbort.call(this);
                return true;
        }
        this.endBattle(this._battleEndPattern);
        return true;
    }
    return _EBE_BattleManager_checkBattleEnd.call(this);
};

var _EBE_BattleManager_processVictory = BattleManager.processVictory;
BattleManager.processVictory = function() {
    if (FTKR.EBE.battleEnd.victory && !this.isBattleEndEvent()) {
        if ($gameTroop.setupEbeBattleEvent('victory', ['EBE_戦闘勝利時'])) {
            this._checkEbeBattleEvent = true;
            this._battleEndPattern = 0;
        }
        return true;
    }
    _EBE_BattleManager_processVictory.call(this);
};

var _EBE_BattleManager_processDefeat = BattleManager.processDefeat;
BattleManager.processDefeat = function() {
    if (FTKR.EBE.battleEnd.defeat && !this.isBattleEndEvent()) {
        if ($gameTroop.setupEbeBattleEvent('defeat', ['EBE_戦闘敗北時'])) {
            this._checkEbeBattleEvent = true;
            this._battleEndPattern = 2;
        }
        return true;
    }
    _EBE_BattleManager_processDefeat.call(this);
};

var _EBE_BattleManager_checkAbort = BattleManager.checkAbort;
BattleManager.checkAbort = function() {
    if (FTKR.EBE.battleEnd.abortBF) {
        if ($gameParty.isEmpty()) {
            SoundManager.playEscape();
            this._escaped = true;
            this.processAbort();
        } else if (this.isAborting()) {
            this._escaped = true;
            this.processAbort();
        }
        return false;
    } else {
        _EBE_BattleManager_checkAbort.call(this);
    }
};

var _EBE_BattleManager_processAbort = BattleManager.processAbort;
BattleManager.processAbort = function() {
    if (FTKR.EBE.battleEnd.abort && !this.isBattleEndEvent() && this.isAborting()) {
        if ($gameTroop.setupEbeBattleEvent('abort', ['EBE_戦闘中断時'])) {
            this._checkEbeBattleEvent = true;
            this._battleEndPattern = 3;
            this._phase = 'battleEnd';
        }
        return true;
    } else if (FTKR.EBE.battleEnd.escape && !this.isBattleEndEvent()) {
        if ($gameTroop.setupEbeBattleEvent('escape', ['EBE_戦闘逃走時'])) {
            this._checkEbeBattleEvent = true;
            this._battleEndPattern = 1;
            this._phase = 'battleEnd';
        }
        return true;
    }
    _EBE_BattleManager_processAbort.call(this);
};

BattleManager.setupNumberPopup = function(index) {
    if (!this._numberSprite[index]) {
        var sprite = new Sprite_Number();
        this._numberSprite[index] = sprite;
        this._spriteset._battleField.addChild(this._numberSprite[index]);
    }
    return this._numberSprite[index];
};

BattleManager.eraseNumberPopup = function(index) {
    this._spriteset._battleField.removeChild(this._numberSprite[index]);
    this._numberSprite[index] = {};
};

BattleManager.isActed = function(battler) {
    return !this._actionBattlers.contains(battler);
};

BattleManager.isActedEnemy = function(battlerId) {
    return !this.isActed($gameTroop.members()[battlerId]);
};

BattleManager.isActedActor = function(battlerId) {
    return !this.isActed($gameParty.members()[battlerId]);
};

//=============================================================================
// Game_Party
//=============================================================================

Game_Party.prototype.requestMotion = function(motionName) {
    this.members().forEach(function(actor) {
        if (actor.canMove()) actor.requestMotion(motionName);
    });
};

//=============================================================================
// Game_Troop
//=============================================================================

FTKR.EBE.Game_Troop_clear = Game_Troop.prototype.clear;
Game_Troop.prototype.clear = function() {
    FTKR.EBE.Game_Troop_clear.call(this);
    this._commonEventFlags = [];
};

FTKR.EBE.Game_Troop_setupBattleEvent = Game_Troop.prototype.setupBattleEvent;
Game_Troop.prototype.setupBattleEvent = function() {
    FTKR.EBE.Game_Troop_setupBattleEvent.call(this);
    if (!this._interpreter.isRunning()) {
        if (this._interpreter.setupReservedCommonEvent()) {
            return;
        }
        var eventIds = FTKR.EBE.battleEvents;
        for (var i = 0; i < eventIds.length; i++) {
            if (eventIds[i]) {
                var event = $dataCommonEvents[eventIds[i]];
                if (this.meetsCommonEventCommentConditions(event) && !this._commonEventFlags[i]) {
                    this._interpreter.setup(event.list, this.troop().id);
                    if (this.commonEventSpan(event) <= 1) {
                        this._commonEventFlags[i] = true;
                    }
                    break;
                }
            }
        }
    }
};

FTKR.EBE.Game_Troop_increaseTurn = Game_Troop.prototype.increaseTurn;
Game_Troop.prototype.increaseTurn = function() {
    var eventIds = FTKR.EBE.battleEvents;
    for (var i = 0; i < eventIds.length; i++) {
        if (eventIds[i]) {
            var event = $dataCommonEvents[eventIds[i]];
            if (this.commonEventSpan(event) === 1) {
                this._commonEventFlags[i] = false;
            }
        }
    }
    FTKR.EBE.Game_Troop_increaseTurn.call(this);
};

Game_Troop.prototype.setupEbeBattleEvent = function(condition, metacodes) {
    if (!this._interpreter.isRunning()) {
        if (this._interpreter.setupReservedCommonEvent()) {
            return false;
        }
        var pages = this.troop().pages;
        for (var i = 0; i < pages.length; i++) {
            var page = pages[i];
            if (this.meetsPagesCommentConditions(page, metacodes) && !this._eventFlags[i]) {
                this._interpreter.setup(page.list, this.troop().id);
                this._eventFlags[i] = true;
                return true;
            }
        }
        var event = $dataCommonEvents[FTKR.EBE.battleEnd[condition]];
        this._interpreter.setup(event.list, this.troop().id);
        return true;
    }
    return false;
};

Game_Troop.prototype.meetsPagesCommentConditions = function(page, metacodes) {
    for (var v = 0; v < page.list.length; v++) {
        var list = page.list[v];
        if (list && ([108, 408].contains(list.code))) {
            return readCommentMeta(list.parameters[0], metacodes);
        }
    }
};

Game_Troop.prototype.commonEventSpan = function(event) {
    for (var v = 0; v < event.list.length; v++) {
        var list = event.list[v];
        if (list && ([108, 408].contains(list.code))) {
            var match = /<([^<>:]+)(:?)([^>]*)>/g.exec(list.parameters[0]);
            switch((match[1] + '').toUpperCase()) {
                case 'スパン':
                case 'SPAN':
                    switch((match[3] + '').toUpperCase()) {
                        case 'バトル':
                        case 'BATTLE':
                            return 0;
                        case 'ターン':
                        case 'TURN':
                            return 1;
                        case 'モーメント':
                        case 'MOMENT':
                            return 2;
                    }
            }
        }
    }
    return 0;
};

Game_Troop.prototype.meetsCommonEventCommentConditions = function(event) {
    return this.meetsConditions(this.convertCommonEventConditions(event));
};

Game_Troop.prototype.convertCommonEventConditions = function(event) {
    var conditions = {};
    var code = false;
    for (var i = 0; i < event.list.length; i++) {
        var list = event.list[i];
        if (list && ([108, 408].contains(list.code))) {
            var match = /<([^<>:]+)(:?)([^>]*)>/g.exec(list.parameters[0]);
            if (match) {
                switch((match[1] + '').toUpperCase()){
                    case 'ターン終了':
                    case 'TURNEND':
                        conditions.turnEnding = true;
                        break;
                    case 'ターン':
                    case 'TURN':
                        if (match[2] === ':') {
                            var turn = /(\d+)[ ]*\+[ ]*(\d+)[ ]*\*X/i.exec(match[3]);
                            if (turn) {
                                conditions.turnValid = true;
                                conditions.turnA = Number(turn[1]);
                                conditions.turnB = Number(turn[2]);
                            }
                        }
                        break;
                    case '敵キャラHP':
                    case 'ENEMY_HP':
                        if (match[2] === ':') {
                            var value = /#(\d+)[ ]*(\d+)[ ]*\%以下/i.exec(match[3]);
                            if (!value) value = /#(\d+)[ ]*less[ ]than[ ]*(\d+)[ ]*\%/i.exec(match[3]);
                            if (value) {
                                conditions.enemyValid = true;
                                conditions.enemyIndex = Number(value[1]);
                                conditions.enemyHp = Number(value[2]);
                            }
                        }
                        break;
                    case 'アクターHP':
                    case 'ACTOR_HP':
                        if (match[2] === ':') {
                            var value = /#(\d+)[ ]*(\d+)[ ]*\%以下/i.exec(match[3]);
                            if (!value) value = /#(\d+)[ ]*less[ ]than[ ]*(\d+)[ ]*\%/i.exec(match[3]);
                            if (value) {
                                conditions.actorValid = true;
                                conditions.actorId = Number(value[1]);
                                conditions.actorHp = Number(value[2]);
                            }
                        }
                        break;
                    case 'スイッチ':
                    case 'SWITCH':
                        if (match[2] === ':') {
                            conditions.switchValid = true;
                            conditions.switchId = Number(match[3]);
                        }
                        break;
                    case '/実行条件':
                    case '/CONDITIONS':
                        code = false;
                        break;
                    case '実行条件':
                    case 'CONDITIONS':
                        conditions.customValid = true;
                        conditions.custom = '';
                        code = true;
                        break;
                }
            } else {
                 if (code) conditions.custom += list.parameters[0] + ';';
            }
        }
    }
    var page = {conditions:conditions};
    return page;
};

Game_Troop.prototype.evalConditionsFormula = function(text) {
    var formula = convertTextToConditions(text);
    if (!formula) return true;
    return FTKR.evalFormula(formula);
};

FTKR.EBE.Game_Troop_meetsConditions = Game_Troop.prototype.meetsConditions;
Game_Troop.prototype.meetsConditions = function(page) {
    var c = page.conditions;
    var result = FTKR.EBE.Game_Troop_meetsConditions.call(this, page);
    if (!c.turnEnding && !result) {
        return false;
    }
    if ((c.turnEnding || c.turnValid || c.enemyValid ||
            c.actorValid || c.switchValid) && !result) {
        return false;
    }
    if (c.customValid && !this.evalConditionsFormula(c.custom)) {
        return false;
    }
    return true;
};

//=============================================================================
// Sprite_Number
// 数字をスプライトで表示する
//=============================================================================

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

Sprite_Number.prototype = Object.create(Sprite.prototype);
Sprite_Number.prototype.constructor = Sprite_Number;

Sprite_Number.prototype.initialize = function() {
    Sprite.prototype.initialize.call(this);
    this._flashColor = [0, 0, 0, 0];
    this._flashDuration = 0;
    this._damageBitmap = ImageManager.loadSystem('Damage');
    this._remain = false;
    this._duration = 30;
    this._maxcount = 0;
    this._count = 0;
    this._baseRow = 0;
    this._value = 0;
    this._index = 0;
    this._popupHeight = 40;
    this._popupOffsetY = 0.5;
    this._fullDuration = this._duration;
};

Sprite_Number.prototype.setupCriticalEffect = function() {
    this._flashColor = [255, 0, 0, 160];
    this._flashDuration = 60;
};

Sprite_Number.prototype.digitWidth = function() {
    return this._damageBitmap ? this._damageBitmap.width / 10 : 0;
};

Sprite_Number.prototype.digitHeight = function() {
    return this._damageBitmap ? this._damageBitmap.height / 5 : 0;
};

Sprite_Number.prototype.setBaseRow = function(baseRow) {
    this._baseRow = baseRow;
};

Sprite_Number.prototype.setDuration = function(duration) {
    this._duration = duration;
};

Sprite_Number.prototype.setValue = function(value) {
    this._value = value;
    this.resetFullDuration();
};

Sprite_Number.prototype.setMaxcount = function(maxcount) {
    this._maxcount = maxcount;
    this._count = this._maxcount;
};

Sprite_Number.prototype.setPosition = function(x, y) {
    this.x = x;
    this.y = y;
};

Sprite_Number.prototype.setRemain = function() {
    this._remain = true;
};

Sprite_Number.prototype.setPopupHeight = function(popupHeight, popupOffsetY) {
    this._popupHeight = popupHeight;
    if(!isNaN(popupOffsetY)) this._popupOffsetY = popupOffsetY;
};

Sprite_Number.prototype.resetFullDuration = function() {
    var string = Math.abs(this._value).toString();
    this._fullDuration = this._duration * string.length;
};

Sprite_Number.prototype.updateOpacity = function() {
    if (this._remain) return;
    if (this._fullDuration < 10) {
        this.opacity = 255 * this._fullDuration / 10;
    }
};

Sprite_Number.prototype.update = function() {
    Sprite.prototype.update.call(this);
    if (this._count >= this._maxcount) {
        this.createDigit(this._index);
        this._index++;
        this._count = 0;
    } else {
        this._count++;
    }
    if (this._fullDuration > 0) {
        this._fullDuration--;
        for (var i = 0; i < this.children.length; i++) {
            this.updateChild(this.children[i]);
        }
    }
    this.updateFlash();
    this.updateOpacity();
};

Sprite_Number.prototype.createChildSprite = function() {
    var sprite = new Sprite();
    sprite.bitmap = this._damageBitmap;
    sprite.anchor.x = 0.5;
    sprite.anchor.y = 1;
    sprite.y = -this._popupHeight;
    sprite.ry = sprite.y;
    this.addChild(sprite);
    return sprite;
};

Sprite_Number.prototype.createDigit = function(index) {
    var value = this._value;
    var baseRow = this._baseRow;
    var string = Math.abs(value).toString();
    if (index >= string.length) return;
    var row = baseRow + (value < 0 ? 1 : 0);
    var w = this.digitWidth();
    var h = this.digitHeight();
    var sprite = this.createChildSprite();
    var n = Number(string[index]);
    sprite.setFrame(n * w, row * h, w, h);
    sprite.x = (index - (string.length - 1) / 2) * w;
    sprite.dy = -this._popupOffsetY * 2 * index;
};

Sprite_Number.prototype.updateChild = function(sprite) {
    sprite.dy += this._popupOffsetY;
    sprite.ry += sprite.dy;
    if (sprite.ry >= 0) {
        sprite.ry = 0;
        sprite.dy *= -0.6;
    }
    sprite.y = Math.round(sprite.ry);
    sprite.setBlendColor(this._flashColor);
};

Sprite_Number.prototype.updateFlash = function() {
    if (this._flashDuration > 0) {
        var d = this._flashDuration--;
        this._flashColor[3] *= (d - 1) / d;
    }
};

Sprite_Number.prototype.isPlaying = function() {
    return this._duration > 0;
};

/*--------------------------------------

--------------------------------------*/

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// 変数の操作を拡張するプラグイン
// FTKR_ExVariablesChange.js
// プラグインNo : 23
// 作成者     : フトコロ
// 作成日     : 2017/04/18
// 最終更新日 : 2018/07/01
// バージョン : v1.2.4
//=============================================================================

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

var FTKR = FTKR || {};
FTKR.EVC = FTKR.EVC || {};

//=============================================================================
/*:
 * @plugindesc v1.2.4 変数の操作を拡張するプラグイン
 * @author フトコロ
 *
 * @param --アイテム増減時--
 * @desc
 *
 * @param Buy
 * @desc アイテム購入時の汎用処理
 * @default
 *
 * @param Gain
 * @desc アイテム増加時の汎用処理
 * @default
 *
 * @param Sell
 * @desc アイテム売却時の汎用処理
 * @default
 *
 * @param Lose
 * @desc アイテム減少時の汎用処理
 * @default
 *
 * @param --アイテム・スキル使用時--
 * @desc
 *
 * @param Use
 * @desc アイテム・スキル使用時の汎用処理
 * @default
 *
 * @param Success
 * @desc アイテム・スキル使用成功時の汎用処理
 * @default
 *
 * @param Failure
 * @desc アイテム・スキル使用失敗時の汎用処理
 * @default
 *
 * @param Damage
 * @desc アイテム・スキルを使用してダメージを与えた時の汎用処理
 * @default
 *
 * @param Receive Damage
 * @desc アイテム・スキルを使用されてダメージを受けた時の汎用処理
 * @default
 *
 * @param Evade
 * @desc アイテム・スキルを使用されて回避した時の汎用処理
 * @default
 *
 * @param Kill
 * @desc アイテム・スキルを使用してエネミーを討伐した時の汎用処理
 * @default
 *
 * @param --戦闘終了時--
 * @desc
 *
 * @param Battle End
 * @desc 戦闘終了時の汎用処理
 * @default
 *
 * @param Battle Victory
 * @desc 戦闘勝利時の汎用処理
 * @default
 *
 * @param Battle Escape
 * @desc 戦闘逃走時の汎用処理
 * @default
 *
 * @param Battle Defeat
 * @desc 戦闘敗北時の汎用処理
 * @default
 *
 * @help
 *-----------------------------------------------------------------------------
 * 概要
 *-----------------------------------------------------------------------------
 * 本プラグインを実装することで、以下の状況において変数やスイッチを
 * 操作することができます。
 *
 * 1. アイテム、武器、防具の増減時
 * 2. アイテム、スキルの使用時
 * 3. 戦闘終了時
 *
 *
 *-----------------------------------------------------------------------------
 * 設定方法
 *-----------------------------------------------------------------------------
 * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して
 *    ください。
 *
 *
 *-----------------------------------------------------------------------------
 * アイテム、武器、防具の増減時
 *-----------------------------------------------------------------------------
 * ノートタグをメモ欄に追記すると以下の状況において、変数・スイッチの
 * 変更ができます。
 *
 * 対象：アイテム、武器、防具
 *
 * 1. ショップで購入した時に実行
 *    :ショップで複数回購入した場合、その都度実行します。
 * <EVC 購入時>
 * 計算式
 * </EVC 購入時>
 *
 *
 * 2. ショップで売却した時に実行
 *    :ショップで複数回売却した場合、その都度実行します。
 * <EVC 売却時>
 * 計算式
 * </EVC 売却時>
 *
 *
 * 3. アイテム数が増加すると実行
 * <EVC 増加時>
 * 計算式
 * </EVC 増加時>
 *
 *
 * 4. アイテム数が減少すると実行
 * <EVC 減少時>
 * 計算式
 * </EVC 減少時>
 *
 *
 *-----------------------------------------------------------------------------
 * アイテム、スキルの使用時
 *-----------------------------------------------------------------------------
 * ノートタグをメモ欄に追記すると以下の状況において、変数・スイッチの
 * 変更ができます。
 *
 * 対象：アイテム、スキル、アクター、エネミー、クラス、装備、ステート
 *
 * なお、タグで設定した変数の計算が行われる順番は以下の通りです。
 * アイテム/スキル ⇒ アクター/エネミー ⇒ クラス ⇒ 装備 ⇒ ステート
 *
 * ＜アイテム・スキルを使用した場合＞
 *
 * 1. 成功失敗問わずに使用すると実行
 *
 * <EVC 使用時>
 * 計算式
 * </EVC 使用時>
 *
 *
 * 2. 使用して成功すると実行
 *
 * <EVC 使用成功時>
 * 計算式
 * </EVC 使用成功時>
 *
 *
 * 3. 使用して失敗(命中しない、回避される)すると実行
 *
 * <EVC 使用失敗時>
 * 計算式
 * </EVC 使用失敗時>
 *
 *
 * 4. ダメージを与えると実行
 *
 * <EVC 与ダメージ時>
 * 計算式
 * </EVC 与ダメージ時>
 *
 *
 * 6. ダメージを与えて敵を倒すと実行
 * (アクターなら倒したとき、エネミーなら倒されたとき実行)
 *
 * <EVC 討伐時>
 * 計算式
 * </EVC 討伐時>
 *
 *
 * ＜アイテム・スキルを使用された場合＞
 *
 * 1. ダメージを受けると実行
 *
 * <EVC 被ダメージ時>
 * 計算式
 * </EVC 被ダメージ時>
 *
 *
 * 2. 回避すると実行
 *
 * <EVC 回避時>
 * 計算式
 * </EVC 回避時>
 *
 *
 *-----------------------------------------------------------------------------
 * 戦闘終了時
 *-----------------------------------------------------------------------------
 * ノートタグをメモ欄に追記すると以下の状況において、変数・スイッチの
 * 変更ができます。
 *
 * 対象：アクター、エネミー、クラス、装備、ステート
 *
 * なお、タグで設定した変数の計算が行われる順番は以下の通りです。
 * アクター ⇒ クラス ⇒ 装備 ⇒ ステート
 * アクター ⇒ エネミー
 *
 * この処理は、戦闘に参加したアクターおよびエネミーに対して実行します。
 * 戦闘不能状態でも実行します。
 *
 * 1. 戦闘が終了すると実行  :この処理は最後に実行します。
 *
 * <EVC 戦闘終了時>
 * 計算式
 * </EVC 戦闘終了時>
 *
 *
 * 2. プレイヤーが戦闘に勝利すると実行
 *
 * <EVC 勝利時>
 * 計算式
 * </EVC 勝利時>
 *
 *
 * 3. プレイヤーが戦闘に敗北すると実行
 *
 * <EVC 敗北時>
 * 計算式
 * </EVC 敗北時>
 *
 *
 * 4. 逃走で戦闘終了すると実行
 *
 * <EVC 逃走時>
 * 計算式
 * </EVC 逃走時>
 *
 *
 * 戦闘終了時の汎用処理には、使用者、対象者はありません。
 * また、セルフ変数は使用できません。
 *
 *
 *-----------------------------------------------------------------------------
 * プラグインパラメータの汎用処理について
 *-----------------------------------------------------------------------------
 * 各状況において、アイテムやアクター等のタグで設定しなくても
 * 毎回実行する処理を規定できます。
 *
 * この汎用処理は、アイテムやアクター等のタグによる処理の後に実行します。
 *
 * 複数の計算を実行する場合は、以下のようにセミコロン(;)で計算式を
 * 区切ってください。
 *
 * 例)
 * v[1] += 1; v[2] += 1
 *
 *
 *-----------------------------------------------------------------------------
 * 計算式について
 *-----------------------------------------------------------------------------
 * 計算式(eval)は、ダメージ計算式のように、計算式を入力することで、
 * 固定値以外の値を使用することができます。以下のコードを使用できます。
 *  s[x]    - スイッチID x の値を意味します。
 *  v[x]    - 変数ID x の値を意味します。
 *  a       - 使用者のゲームデータを参照します。(使用者がいる場合のみ)
 *  b       - 対象者のゲームデータを参照します。(対象者がいる場合のみ)
 *  item    - 使用したアイテムのデータを参照します。(*1)
 *  av[x]   - 使用者のセルフ変数ID x の値を意味します。(*2)
 *  bv[x]   - 対象者のセルフ変数ID x の値を意味します。(*2)
 *  iv[x]   - アイテムのセルフ変数ID x の値を意味します。(*1)(*2)
 *  number  - 購入・売却・増減時のアイテム数を意味します。
 *  result  - スキル・アイテムを使用した結果を参照します。
 *            result.hpDamage でHPダメージ量を取得します。
 *
 * (*1) アイテムとは、使用したスキルまたはアイテム、購入・売却したアイテムの
 *      ことです。
 * (*2) セルフ変数を使用する場合は、FTKR_ItemSelfVariables.jsが必要です。
 *
 *
 * [設定例]
 * 購入時に変数を操作するためアイテムに以下のノートタグを設定する。
 *
 * <EVC 購入時>
 * s[1] = true
 * v[10] = 10
 * iv[1] += v[5]
 * iv[2] += number
 * </EVC 購入時>
 *
 * スイッチID1 を ON にします。
 * 変数ID10 に 10 を代入します。
 * 購入したアイテムのセルフ変数ID1 に 変数ID5 の値を加算します。
 * 購入したアイテムのセルフ変数ID2 に 購入数を加算します。
 *
 *
 * ＜変数計算における注意点＞
 * ゲーム内変数は、初期状態では 0 以外の不明な状態になっています。
 * そのため、一度もゲーム内変数になんらかの値を代入していない場合、
 * そのまま v[x] += 1 などと計算式を実行すると、正しく計算できません。
 *
 * ゲーム内変数IDは、使用前に必ず初期化(0 を代入する)するか、
 * 以下のように計算式に記入するようにしてください。
 *
 * 例）変数ID10 に 1 を加算する場合
 * if(!v[10]) v[10] = 0
 * v[10] += 1
 *
 * なお、FTKR_ItemSelfVariables.jsのセルフ変数は、ゲーム開始時に
 * 必ず0を代入するようになっているため、上記の処置は不要です。
 *
 *
 *-----------------------------------------------------------------------------
 * 本プラグインのライセンスについて(License)
 *-----------------------------------------------------------------------------
 * 本プラグインはMITライセンスのもとで公開しています。
 * This plugin is released under the MIT License.
 *
 * Copyright (c) 2017 Futokoro
 * http://opensource.org/licenses/mit-license.php
 *
 *
 *-----------------------------------------------------------------------------
 * 変更来歴
 *-----------------------------------------------------------------------------
 *
 * v1.2.4 - 2018/07/01 : 仕様変更
 *    1. 他プラグインとの競合回避のためダメージ時のデータ取得タイミングを変更。
 *
 * v1.2.3 - 2017/08/24 : 不具合修正
 *    1. アクターの職業IDを正しく取得できていない不具合を修正。
 *
 * v1.2.2 - 2017/06/07 : 不具合修正
 *    1. 被ダメージ時の処理タイミングを修正。(v1.2.1の修正による不具合)
 *
 * v1.2.1 - 2017/06/07 : 不具合修正、機能追加
 *    1. 被ダメージ時に使用者・対象者・使用スキル(アイテム)のゲームデータを
 *       参照できない不具合を修正。
 *    2. 戦闘終了時のタグをエネミーに適用。
 *    3. 与ダメージ時の処理タイミングを変更。
 *
 * v1.2.0 - 2017/06/05 : 機能追加
 *    1. アイテム・スキルの回避時を追加。
 *    2. 処理の見直し。
 *
 * v1.1.1 - 2017/05/19 : ヘルプ修正
 *
 * v1.1.0 - 2017/05/11 : 機能追加
 *    1. エネミー討伐時や戦闘終了時を追加。
 *    2. プラグインパラメータで設定できる汎用計算処理を追加。
 *
 * v1.0.6 - 2017/05/03 : 不具合修正
 *    1. 非ダメージ時を正しく処理できていない不具合を修正。
 *    2. 計算式を正しく処理できていない不具合を修正。
 *
 * v1.0.5 - 2017/05/02 : 不具合修正
 *    1. アイテム増減時の処理の順番を変更。
 *
 * v1.0.4 - 2017/04/28 : 不具合修正
 *    1. アイテム増減時に例外処理を追加。
 *
 * v1.0.3 - 2017/04/26 : 機能追加
 *    1. ダメージ時の変数操作機能を追加
 *    2. アイテム・スキル使用時のタグ適用先を拡張。
 *
 * v1.0.2 - 2017/04/25 : 不具合修正
 *    1. 対象者のセルフ変数が正しく反映されない不具合を修正。
 *
 * v1.0.1 - 2017/04/19 : 不具合修正
 *
 * v1.0.0 - 2017/04/18 : 初版作成
 *
 *-----------------------------------------------------------------------------
*/
//=============================================================================

(function() {

    //=============================================================================
    // プラグイン パラメータ
    //=============================================================================
    var parameters = PluginManager.parameters('FTKR_ExVariablesChange');

    FTKR.EVC.default = {
        buy     :String(parameters['Buy'] || ''),
        gain    :String(parameters['Gain'] || ''),
        sell    :String(parameters['Sell'] || ''),
        lose    :String(parameters['Lose'] || ''),
        use     :String(parameters['Use'] || ''),
        success :String(parameters['Success'] || ''),
        failure :String(parameters['Failure'] || ''),
        damage  :String(parameters['Damage'] || ''),
        receive :String(parameters['Receive Damage'] || ''),
        evade   :String(parameters['Evade'] || ''),
        kill    :String(parameters['Kill'] || ''),
        end     :String(parameters['Battle End'] || ''),
        victory :String(parameters['Battle Victory'] || ''),
        escape  :String(parameters['Battle Escape'] || ''),
        defeat  :String(parameters['Battle Defeat'] || ''),
    };

    //=============================================================================
    // 自作関数(グローバル)
    //=============================================================================

    FTKR.gameData = FTKR.gameData || {
        user   :null,
        target :null,
        item   :null,
        number :0,
    };

    if (!FTKR.setGameData) {
    FTKR.setGameData = function(user, target, item, number) {
        FTKR.gameData = {
            user   :user || null,
            target :target || null,
            item   :item || null,
            number :number || 0
        };
    };
    }

    if (!FTKR.evalCalcFormula) {
    FTKR.evalCalcFormula = function(formula) {
        var datas = FTKR.gameData;
        try {
            var s = $gameSwitches._data;
            var v = $gameVariables._data;
            var a = datas.user;
            var b = datas.target;
            var item   = datas.item;
            var number = datas.number;
            if (b) var result = b.result();
            eval(formula);
        } catch (e) {
            console.error(e);
        }
    };
    }

    //=============================================================================
    // 自作関数
    //=============================================================================

    //挟み込み形式のメタデータを読み取ってtextを返す
    var readEntrapmentCodeToText = function(obj, codeTitles) {
        regs = convertEntrapmentRegArray('EVC', codeTitles);
        var notedata = obj.note.split(/[\r\n]+/);
        var setMode = 'none';
        var text = '';
        notedata.forEach( function(line) {
            if (testRegs(line, regs, 'a')) {
                setMode = 'read';
            } else if (testRegs(line, regs, 'b')) {
                setMode = 'none';
            } else if (setMode === 'read') {
                text += line + ';';
            }
        });
        return text;
    };

    //文字列の配列を挟み込み形式用の正規表現オブジェクトの配列に変換する
    var convertEntrapmentRegArray = function(header, codeTitles) {
        return codeTitles.map(function(str) {
            return {
                a:new RegExp('<' + header + ' ' + str + '>', 'i'),
                b:new RegExp('<\/' + header + ' ' + str + '>', 'i')
            };
        });
    };

    //正規表現オブジェクトの配列regsとdataをテストする
    var testRegs = function(data, regs, prop) {
        return regs.some(function(reg) {
            return prop ? reg[prop].test(data) : reg.test(data);
        });
    };

    //objのメモ欄から <codeTitle[0]: x> から <codeTitle[n]: x>のいずれかの値を読み取って配列で返す
    var readSplitAnyEntrapmentCode = function(obj, codeTitles) {
        var evalsText = readEntrapmentCodeToText(obj, codeTitles);
        return evalsText ? evalsText.split(';') : [];
    };

    //配列内のobjのメモ欄から <codeTitle: x> の値を読み取って配列で返す
    var readItemsEntrapmentCodeSplitTotal = function(items, codeTitles) {
        var result = [];
        items.forEach( function(item) {
            if(item) Array.prototype.push.apply(result, readSplitAnyEntrapmentCode(item, codeTitles));
        });
        return result;
    };

    //target(アクターまたはエネミー)が持つ、codeTitle[0] ~ codeTitle[n]のいずれかで指定したタグの値を配列にして返す
    // クラス、装備、ステートも含む
    var readItemsEntrapmentCodeArray = function(target, codeTitles) {
        var result = [];
        if(target.isActor()) {
            return result.concat(
                readSplitAnyEntrapmentCode(target.actor(), codeTitles),
                readSplitAnyEntrapmentCode($dataClasses[target._classId], codeTitles),
                readItemsEntrapmentCodeSplitTotal(target.equips(), codeTitles),
                readItemsEntrapmentCodeSplitTotal(target.states(), codeTitles)
            );
        } else if(target.isEnemy()) {
            return result.concat(
                readSplitAnyEntrapmentCode(target.enemy(), codeTitles),
                readItemsEntrapmentCodeSplitTotal(target.states(), codeTitles)
            );
        }
        return result;
    };

    var variablesChangeNoteTags = function(codeTitles, item, target) {
        if(item) variablesChangeItemNoteTags(codeTitles, item);
        if(target) variablesChangeUnitNoteTags(codeTitles, target);
    };

    var variablesChangeItemNoteTags = function(codeTitles, obj) {
        var evalsText = readEntrapmentCodeToText(obj, codeTitles);
        if (!evalsText) return;
        evcEvalsFormula(evalsText.split(';'));
    };

    var variablesChangeUnitNoteTags = function(codeTitles, obj) {
        evcEvalsFormula(readItemsEntrapmentCodeArray(obj, codeTitles));
    };

    var evcEvalsFormula = function(evals) {
        for (var i = 0; i < evals.length; i++) {
            FTKR.evalCalcFormula(evals[i]);
        }
        if($gameMap) $gameMap.requestRefresh();
    };

    var defaultVariablesChange = function(condition) {
        var eval = FTKR.EVC.default[condition];
        if(eval) {
            evcEvalsFormula(eval.split(';'));
        }
    };

    //=============================================================================
    // 使用時
    //=============================================================================

    var _EVC_Game_Action_apply = Game_Action.prototype.apply;
    Game_Action.prototype.apply = function(target) {
        _EVC_Game_Action_apply.call(this, target);
        this.evcVariablesChange(target);
    };

    Game_Action.prototype.evcVariablesChange = function(target) {
        var result = target.result();
        if (!result.used) return false;
        FTKR.setGameData(this.subject(), target, this.item());
        this.variablesChangeItemNoteTags(['使用時', 'USE'], this.subject());
        defaultVariablesChange('use');
        if (result.isHit()) {
            this.variablesChangeItemNoteTags(['使用成功時', 'SUCCESS'], this.subject());
            defaultVariablesChange('success');
            if (this.killedTargetEnemy(target)) {
                this.variablesChangeItemNoteTags(['討伐時', 'KILL'], this.subject());
                variablesChangeUnitNoteTags(['討伐時', 'KILL'], target)
                defaultVariablesChange('kill');
            }
        } else {
            if (result.evaded) {
                variablesChangeUnitNoteTags(['回避時', 'EVADE'], target);
                defaultVariablesChange('evade');
            }
            this.variablesChangeItemNoteTags(['使用失敗時', 'FAILURE'], this.subject());
            defaultVariablesChange('failure');
        }
        return true;
    };

    Game_Action.prototype.variablesChangeItemNoteTags = function(codeTitles, target) {
        variablesChangeNoteTags(codeTitles, this.item(), target);
    };

    Game_Action.prototype.killedTargetEnemy = function(target) {
        var result = target.result();
        return (result.hpDamage || result.mpDamage) && target.isEnemy() && target.hp <= 0;
    };

    //=============================================================================
    // ダメージ時
    //=============================================================================

    var _EVC_Game_Action_executeDamage = Game_Action.prototype.executeDamage;
    Game_Action.prototype.executeDamage = function(target, value) {
        _EVC_Game_Action_executeDamage.call(this, target, value);
        if (this.isHpEffect() || this.isMpEffect()) {
            FTKR.setGameData(this.subject(), target, this.item());
            this.variablesChangeItemNoteTags(['与ダメージ時', 'DAMAGE'], this.subject());
            defaultVariablesChange('damage');
            variablesChangeUnitNoteTags(['被ダメージ時', 'RECEIVE_DAM'], target);
            defaultVariablesChange('receive');
        }
    };

    //=============================================================================
    // 購入時
    //=============================================================================

    var _EVC_Scene_Shop_doBuy = Scene_Shop.prototype.doBuy;
    Scene_Shop.prototype.doBuy = function(number) {
        FTKR.setGameData(null, null, this._item, number);
        variablesChangeNoteTags(['購入時', 'BUY'], this._item);
        defaultVariablesChange('buy');
        _EVC_Scene_Shop_doBuy.call(this, number);
    };

    //=============================================================================
    // 増加・減少時
    //=============================================================================

    var _EVC_Game_Party_gainItem = Game_Party.prototype.gainItem;
    Game_Party.prototype.gainItem = function(item, amount, includeEquip) {
        if (this.itemContainer(item) && amount) {
            FTKR.setGameData(null, null, item, amount);
            if (amount > 0) {
                variablesChangeNoteTags(['増加時', 'GAIN'], item);
                defaultVariablesChange('gain');
            } else if (amount < 0) {
                variablesChangeNoteTags(['減少時', 'LOSE'], item);
                defaultVariablesChange('lose');
            }
        }
        _EVC_Game_Party_gainItem.call(this, item, amount, includeEquip);
    };

    //=============================================================================
    // 売却時
    //=============================================================================

    var _EVC_Scene_Shop_doSell = Scene_Shop.prototype.doSell;
    Scene_Shop.prototype.doSell = function(number) {
        FTKR.setGameData(null, null, this._item, number);
        variablesChangeNoteTags(['売却時', 'SELL'], this._item);
        defaultVariablesChange('sell');
        _EVC_Scene_Shop_doSell.call(this, number);
    };

    //=============================================================================
    // 戦闘終了時
    //=============================================================================

    var _EVC_BattleManager_processVictory = BattleManager.processVictory;
    BattleManager.processVictory = function() {
        this.allBattleMembers().forEach(function(member){
            FTKR.setGameData(member);
            variablesChangeUnitNoteTags(['勝利時', 'VICTORY'], member);
        });
        FTKR.setGameData();
        defaultVariablesChange('victory');
        _EVC_BattleManager_processVictory.call(this);
    };

    var _EVC_BattleManager_processEscape = BattleManager.processEscape;
    BattleManager.processEscape = function() {
        var success = _EVC_BattleManager_processEscape.call(this);
        if (success) {
            this.allBattleMembers().forEach(function(member){
                FTKR.setGameData(member);
                variablesChangeUnitNoteTags(['逃走時', 'ESCAPE'], member);
            });
            FTKR.setGameData();
            defaultVariablesChange('escape');
        }
        return success;
    };

    var _EVC_BattleManager_processDefeat = BattleManager.processDefeat;
    BattleManager.processDefeat = function() {
        this.allBattleMembers().forEach(function(member){
            FTKR.setGameData(member);
            variablesChangeUnitNoteTags(['敗北時', 'DEFEAT'], member);
            defaultVariablesChange('defeat');
        });
        FTKR.setGameData();
        _EVC_BattleManager_processDefeat.call(this);
    };

    var _EVC_BattleManager_endBattle = BattleManager.endBattle;
    BattleManager.endBattle = function(result) {
        _EVC_BattleManager_endBattle.call(this, result);
        this.allBattleMembers().forEach(function(member){
            FTKR.setGameData(member);
            variablesChangeUnitNoteTags(['戦闘終了時', 'BATTLEEND'], member);
        });
        FTKR.setGameData();
        defaultVariablesChange('end');
    };

}());//EOF


code:
//=============================================================================
// FixImageLoading.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015-2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.0.1 2019/04/06 MoviePicture.jsとの競合を修正
// 2.0.0 2017/06/09 本体ver1.5.0に合わせて再作成
// 1.1.1 2016/11/20 ロード完了時にframeが更新されない不具合を修正
//                  ロード中にframeが変更された場合に、ロード完了まで反映を遅らせる仕様を追加
// 1.1.0 2016/11/16 liply_GC.jsとの競合を解消 by 奏 ねこま様
// 1.0.0 2016/05/02 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:ja
 * @plugindesc 画像ロード時のチラつき防止プラグイン
 * @author トリアコンタン
 *
 * @help キャッシュしていない画像を表示したときに
 * 一瞬発生するチラつきを防止します。
 * 画像のロードが完了するまで以前に表示していた画像を残します。
 *
 * 逆に画像を消したいときは明示的にピクチャの消去等を行ってから
 * 表示してください。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';

    var _Sprite__renderCanvas = Sprite.prototype._renderCanvas;
    Sprite.prototype._renderCanvas = function(renderer) {
        _Sprite__renderCanvas.apply(this, arguments);
        if (this.isExistLoadingBitmap()) {
            this._renderCanvas_PIXI(renderer);
        }
    };

    var _Sprite__renderWebGL      = Sprite.prototype._renderWebGL;
    Sprite.prototype._renderWebGL = function(renderer) {
        _Sprite__renderWebGL.apply(this, arguments);
        if (this.isExistLoadingBitmap()) {
            if (this._isPicture) {
                this._speedUpCustomBlendModes(renderer);
                renderer.setObjectRenderer(renderer.plugins.picture);
                if (!this.isVideoPicture || !this.isVideoPicture()) {
                    renderer.plugins.picture.render(this);
                }
            } else {
                renderer.setObjectRenderer(renderer.plugins.sprite);
                renderer.plugins.sprite.render(this);
            }
        }
    };

    Sprite.prototype.isExistLoadingBitmap = function() {
        return this.bitmap && !this.bitmap.isReady();
    };
})();


code:
//=============================================================================
// FloatVariables.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015-2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.0 2017/09/15 型指定機能に対応
// 1.0.0 2016/07/30 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc FloatVariablesPlugin
 * @author triacontane
 *
 * @param FloatVariableStart
 * @desc 小数演算を行う変数の開始位置です。
 * @default 0
 * @type variable
 *
 * @param FloatVariableEnd
 * @desc 小数演算を行う変数の終了位置です。
 * @default 0
 * @type variable
 *
 * @help FloatVariables.js
 *
 * 指定した範囲内の変数を小数演算可能にします。
 *
 * ・通常(整数演算)の場合
 * 3 / 2 = 1
 *
 * ・小数演算の場合
 * 3 / 2 = 1.5
 *
 * 小数が代入されている変数をイベントコマンドのオペランドとして
 * 使用すると予期しない問題が発生する可能性があります。
 * (HPに0.5を加算するなど)
 *
 * 注意して利用してください。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
/*:
 * @plugindesc 変数の小数演算プラグイン
 * @author トリアコンタン
 *
 * @param 小数変数開始位置
 * @desc 小数演算を行う変数の開始位置です。
 * @default 0
 * @type variable
 *
 * @param 小数変数終了位置
 * @desc 小数演算を行う変数の終了位置です。
 * @default 0
 * @type variable
 *
 * @help FloatVariables.js
 *
 * 指定した範囲内の変数を小数演算可能にします。
 *
 * ・通常(整数演算)の場合
 * 3 / 2 = 1
 *
 * ・小数演算の場合
 * 3 / 2 = 1.5
 *
 * 小数が代入されている変数をイベントコマンドのオペランドとして
 * 使用すると予期しない問題が発生する可能性があります。
 * (HPに0.5を加算するなど)
 *
 * 注意して利用してください。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';
    var pluginName = 'FloatVariables';

    var getParamNumber = function(paramNames, min, max) {
        var value = getParamOther(paramNames);
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(value, 10) || 0).clamp(min, max);
    };

    var getParamOther = function(paramNames) {
        if (!Array.isArray(paramNames)) paramNames = [paramNames];
        for (var i = 0; i < paramNames.length; i++) {
            var name = PluginManager.parameters(pluginName)[paramNames[i]];
            if (name) return name;
        }
        return null;
    };

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var paramFloatVariableStart = getParamNumber(['FloatVariableStart', '小数変数開始位置']);
    var paramFloatVariableEnd   = getParamNumber(['FloatVariableEnd', '小数変数終了位置']);

    var _Game_Variables_setValue = Game_Variables.prototype.setValue;
    Game_Variables.prototype.setValue = function(variableId, value) {
        if (variableId >= paramFloatVariableStart && variableId <= paramFloatVariableEnd) {
            if (variableId > 0 && variableId < $dataSystem.variables.length) {
                this._data[variableId] = value;
                this.onChange();
            }
        } else {
            _Game_Variables_setValue.apply(this, arguments);
        }
    };
})();


code:
//=============================================================================
// Foreground.js (Ver1.0.1)
//=============================================================================
// [History]
// 2015.Nov. 7  1.0.0 First Release
// 2018.Sep.19  1.0.1 Fix bug when 'event command -> test' becomes error

/*:
 * @plugindesc display foreground tiling sprite(Ver1.0.1)
 * @author Sasuke KANNAZUKI (thanks to Yoji Ojima)
 *
 * @noteParam fgName
 * @noteRequire 1
 * @noteDir img/parallaxes/
 * @noteType file
 * @noteData maps
 *
 * @help  This plugin does not provide plugin commands.
 *
 * 'foreground' is like a parallax that displays over the map.
 * put bitmap file at img/parallaxes.
 *
 * Map Note:
 *  write down following 5 settings at map's note.
 *  <fgName:name>     name is the string, file name of tiling sprite.
 *    if the name starts '!', it is regarded as "foreground zero".
 *    the filename is searched from img/parallaxes.
 *  <fgLoopX:number>  number is the flag of loop x. 0:no 1:yes
 *    if this is not written on the note, it'll be 0(=no).
 *  <fgLoopY:number>  number is the flag of loop y. 0:no 1:yes
 *    if this is not written on the note, it'll be 0(=no).
 *  <fgSx:number>     number is x scroll speed.
 *    when it doesn't loop x, this is ignored.
 *    if this is not written on the note, it'll be 0.
 *  <fgSy:number>     number is y scroll speed.
 *    when it doesn't loop y, this is ignored.
 *    if this is not written on the note, it'll be 0.
 *
 * Ex.
 * <fgName:sample1><fgLoopX:1><fgLoopY:1>
 *
 * <fgName:!sample1>
 *
 * [License]
 * this plugin is released under MIT license.
 * http://opensource.org/licenses/mit-license.php
 */

/*:ja
 * @plugindesc マップに合わせてスクロールする近景の設定(Ver1.0.1)
 * @author 神無月サスケ (thanks to Yoji Ojima)
 *
 * @noteParam fgName
 * @noteRequire 1
 * @noteDir img/parallaxes/
 * @noteType file
 * @noteData maps
 *
 * @help このプラグインにプラグインコマンドはありません。
 * 近景(foreground)は、マップの上に表示される遠景のようなものです。
 * 使用する画像ファイルは、img/parallaxes に置いてください。
 *
 * マップのメモ:
 *  以下の5項目を書いてください(設定項目は、遠景と似ています)。
 *  <fgName:ファイル名> 前景として使うファイル名です（拡張子なし）
 *    名前が '!'で始まる場合、遠景同様視差ゼロとなります。
 *    ファイルは img/parallaxes に置いてください
 *  <fgLoopX:数字> X座標にループするかどうか  (0:no 1:yes)。
 *    省略時は0(=no)になります。
 *  <fgLoopY:number> Y座標にループするかどうか  (0:no 1:yes)。
 *    省略時は0(=no)になります。
 *  <fgSx:数字>    X座標のスクロール速度です
 *    X座標にループしない場合は無視されます。
 *    省略時は0になります。
 *  <fgSy:数字>    Y座標のスクロール速度です
 *    Y座標にループしない場合は無視されます。
 *    省略時は0になります。
 *
 * 例：
 * <fgName:sample1><fgLoopX:1><fgLoopY:1>
 * sample1.png が前景になり、斜め上にループします。
 *
 * <fgName:!sample1>
 * 視差ゼロで!sample1.png が表示されます。
 *
 * ■ライセンス表記
 * このプラグインは MIT ライセンスで配布されます。
 * ご自由にお使いください。
 * http://opensource.org/licenses/mit-license.php
 */

(function() {
  //
  // check zero foreground or not.
  //
  ImageManager.isZeroForeground = function(filename) {
    return filename.charAt(0) === '!';
  };

  //
  // map initialization
  //
  var _Game_Map_initialize = Game_Map.prototype.initialize;
  Game_Map.prototype.initialize = function() {
    _Game_Map_initialize.call(this);
    this.initForeground();
  };

  Game_Map.prototype.initForeground = function(){
    this._foregroundDefined = true;
    this._foregroundName = '';
    this._foregroundZero = false;
    this._foregroundLoopX = false;
    this._foregroundLoopY = false;
    this._foregroundSx = 0;
    this._foregroundSy = 0;
    this._foregroundX = 0;
    this._foregroundY = 0;
  };

  //
  // if foreground is undefined, initialize it.
  //
  Game_Map.prototype.guardForeground = function(){
    if(!this._foregroundDefined){
      this.initForeground();
    }
  };

  //
  // an accessor
  //
  Game_Map.prototype.foregroundName = function() {
    this.guardForeground();
    return this._foregroundName;
};

  //
  // set foreground by reading map's note.
  //
  var _Game_Map_setup = Game_Map.prototype.setup;
  Game_Map.prototype.setup = function(mapId) {
    _Game_Map_setup.call(this, mapId);
    this.setupForeground();
  };

  Game_Map.prototype.setupForeground = function() {
    if ($dataMap.meta) {
      this._foregroundName = $dataMap.meta.fgName || '';
      this._foregroundZero = ImageManager.isZeroForeground(
        this._foregroundName);
      this._foregroundLoopX = !!$dataMap.meta.fgLoopX;
      this._foregroundLoopY = !!$dataMap.meta.fgLoopY;
      this._foregroundSx = Number($dataMap.meta.fgSx) || 0;
      this._foregroundSy = Number($dataMap.meta.fgSy) || 0;
    }
    this._foregroundX = 0;
    this._foregroundY = 0;
  };

  //
  // to display foreground
  //
  var _Game_Map_setDisplayPos = Game_Map.prototype.setDisplayPos;
  Game_Map.prototype.setDisplayPos = function(x, y) {
    _Game_Map_setDisplayPos.call(this, x, y);
    this.guardForeground();
    if (this.isLoopHorizontal()) {
      this._foregroundX = x;
    } else {
       this._foregroundX = this._displayX;
    }
    if (this.isLoopVertical()) {
      this._foregroundY = y;
    } else {
      this._foregroundY = this._displayY;
    }
  };

  Game_Map.prototype.foregroundOx = function() {
    this.guardForeground();
    if (this._foregroundZero) {
      return this._foregroundX * this.tileWidth();
    } else if (this._foregroundLoopX) {
      return this._foregroundX * this.tileWidth() / 2;
    } else {
      return 0;
    }
  };

  Game_Map.prototype.foregroundOy = function() {
    this.guardForeground();
    if (this._foregroundZero) {
      return this._foregroundY * this.tileHeight();
    } else if (this._foregroundLoopY) {
      return this._foregroundY * this.tileHeight() / 2;
    } else {
      return 0;
    }
  };

  //
  // to scroll foreground
  //
  var _Game_Map_scrollDown = Game_Map.prototype.scrollDown;
  Game_Map.prototype.scrollDown = function(distance) {
    var lastY = this._displayY;
    _Game_Map_scrollDown.call(this, distance);
    this.guardForeground();
    if (this.isLoopVertical()) {
      if (this._foregroundLoopY) {
        this._foregroundY += distance;
      }
    } else if (this.height() >= this.screenTileY()) {
      var displayY = Math.min(lastY + distance,
        this.height() - this.screenTileY());
      this._foregroundY += displayY - lastY;
    }
  };

  var _Game_Map_scrollLeft = Game_Map.prototype.scrollLeft;
  Game_Map.prototype.scrollLeft = function(distance) {
    var lastX = this._displayX;
    _Game_Map_scrollLeft.call(this, distance);
    this.guardForeground();
    if (this.isLoopHorizontal()) {
      if (this._foregroundLoopX) {
        this._foregroundX -= distance;
      }
    } else if (this.width() >= this.screenTileX()) {
      var displayX = Math.max(lastX - distance, 0);
      this._foregroundX += displayX - lastX;
    }
  };

  var _Game_Map_scrollRight = Game_Map.prototype.scrollRight;
  Game_Map.prototype.scrollRight = function(distance) {
    var lastX = this._displayX;
    _Game_Map_scrollRight.call(this, distance);
    this.guardForeground();
    if (this.isLoopHorizontal()) {
      if (this._foregroundLoopX) {
        this._foregroundX += distance;
      }
    } else if (this.width() >= this.screenTileX()) {
      var displayX = Math.min(lastX + distance,
       this.width() - this.screenTileX());
      this._foregroundX += displayX - lastX;
    }
  };

  var _Game_Map_scrollUp = Game_Map.prototype.scrollUp;
  Game_Map.prototype.scrollUp = function(distance) {
    var lastY = this._displayY;
    _Game_Map_scrollUp.call(this, distance);
    this.guardForeground();
    if (this.isLoopVertical()) {
      if (this._foregroundLoopY) {
        this._foregroundY -= distance;
      }
    } else if (this.height() >= this.screenTileY()) {
      var displayY = Math.max(lastY - distance, 0);
      this._foregroundY += displayY - lastY;
    }
  };

  //
  // update foreground
  //
  var _Game_Map_update = Game_Map.prototype.update;
  Game_Map.prototype.update = function(sceneActive) {
    _Game_Map_update.call(this, sceneActive);
    this.updateForeground();
  };

  Game_Map.prototype.updateForeground = function() {
    this.guardForeground();
    if (this._foregroundLoopX) {
      this._foregroundX += this._foregroundSx / this.tileWidth() / 2;
    }
    if (this._foregroundLoopY) {
      this._foregroundY += this._foregroundSy / this.tileHeight() / 2;
    }
  };

  //
  // sprites
  //
  var _Spriteset_Map_createLowerLayer =
   Spriteset_Map.prototype.createLowerLayer;
  Spriteset_Map.prototype.createLowerLayer = function() {
    _Spriteset_Map_createLowerLayer.call(this);
   this.createForeground();
  };

  var _Spriteset_Map_update = Spriteset_Map.prototype.update;
  Spriteset_Map.prototype.update = function() {
    _Spriteset_Map_update.call(this);
    this.updateForeground();
  };

  Spriteset_Map.prototype.createForeground = function() {
    this._foreground = new TilingSprite();
    this._foreground.move(0, 0, Graphics.width, Graphics.height);
    // in order to display under the weather sprites:
    this._baseSprite.removeChild(this._weather);
    this._baseSprite.addChild(this._foreground);
    this._baseSprite.addChild(this._weather);
  };

  Spriteset_Map.prototype.updateForeground = function() {
    if (this._foregroundName !== $gameMap.foregroundName()) {
      this._foregroundName = $gameMap.foregroundName();
      this._foreground.bitmap = ImageManager.loadParallax(this._foregroundName);
    }
    if (this._foreground.bitmap) {
      this._foreground.origin.x = $gameMap.foregroundOx();
      this._foreground.origin.y = $gameMap.foregroundOy();
    }
  };

})();