code:
/*---------------------------------------------------------------------------*
 * Torigoya_QuickSkill.js
 *---------------------------------------------------------------------------*
 * 2019/08/24 ru_shalm
 * http://torigoya.hatenadiary.jp/
 *---------------------------------------------------------------------------*/

/*:
 * @plugindesc usable Quick skill (select and action!)
 * @author ru_shalm
 *
 * @param ■ Advanced Settings
 *
 * @param Recalc Action Time Mode
 * @type select
 * @option None
 * @option Only Actor
 * @option Party
 * @default None
 *
 * @help
 *
 * Skill Note:
 *   <QuickSkill>           # set quick skill
 */

/*:ja
 * @plugindesc 選択するとターンを消費せずに即発動するスキルを追加します。
 * @author ru_shalm
 *
 * @param ■ 上級者向け設定
 *
 * @param Recalc Action Time Mode
 * @type select
 * @option なし
 * @option 使用者のみ
 * @option 味方全員
 * @desc ターン消費なしスキル後に行動回数の再計算を行う対象。確率で行動回数が変わるキャラがいる場合おかしな挙動になります。
 * @default None
 *
 * @help
 * ターン消費なしスキルを作れるようになります。
 *
 * ------------------------------------------------------------
 * ■ 設定方法
 * ------------------------------------------------------------
 * スキルのメモ欄に以下のように記述してください。
 *
 * <QuickSkill>
 */

(function (global) {
    'use strict';

    var QuickSkill = {
        name: 'Torigoya_QuickSkill',
        currentActionActor: null,
        originalSubject: null,
        actorIndexForForcedAction: null,
        backupActions: null,

        // 競合回避用フラグ
        conflictData: {
            // 連携発動スキル / yanaさま
            // https://www6.atwiki.jp/pokotan/pages/3.html
            currentChainAction: null
        }
    };
    QuickSkill.settings = (function () {
        var parameters = PluginManager.parameters(QuickSkill.name);
        return {
            recalcActionTimeMode: String(parameters['Recalc Action Time Mode'])
        };
    })();

    // -------------------------------------------------------------------------
    // Utils

    QuickSkill.reset = function () {
        this.currentActionActor = null;
        this.originalSubject = null;
        this.actorIndexForForcedAction = null;
        this.backupActions = null;

        this.conflictData.currentChainAction = null;
    };

    QuickSkill.isBattleEnd = function () {
        return $gameParty.isEmpty() || $gameParty.isAllDead() || $gameTroop.isAllDead();
    };

    QuickSkill.recalcMode = function () {
        switch (QuickSkill.settings.recalcActionTimeMode) {
            case 'Party':
            case '味方全員':
                return 'party';
            case 'Only Actor':
            case '使用者のみ':
                return 'actor';
            case 'None':
            case 'なし':
            default:
                return 'none';
        }
    };

    // -------------------------------------------------------------------------
    // Game_Battler

    // ターン消費なしスキル中はActionを減らさないようにしないと死ぬ
    Game_Battler.prototype.removeCurrentAction = function () {
        if (QuickSkill.conflictData.currentChainAction) {
            this._actions.shift();
        } else if (QuickSkill.currentActionActor) {
            this._actions[0] = new Game_Action(this);
            this._actions.sort(function (a, _) {
                return a._item.isNull() ? 1 : 0;
            });
        } else if (QuickSkill.actorIndexForForcedAction !== null) {
            this._actions = QuickSkill.backupActions;
        } else {
            this._actions.shift();
        }
    };

    // ターン消費なし戦闘行動の強制の場合は行動を保存してあげる
    var upstream_Game_Battler_forceAction = Game_Battler.prototype.forceAction;
    Game_Battler.prototype.forceAction = function (skillId, targetIndex) {
        if (BattleManager._phase === 'torigoya_quickSkill') {
            QuickSkill.backupActions = this._actions;
        }
        upstream_Game_Battler_forceAction.apply(this, arguments);
    };

    // 行動回数が増えていたらActionを増やす
    // ※RPGツクールの仕様上、確率で増える行動回数が設定できるが、
    //   このメソッドを呼び出すと行動計算が再計算されてしまうため、
    //   「さっき1回だったのに急に2回になった！」のようなことが起きることがあります。
    //   ただし、減ることはないようにしています。
    Game_Battler.prototype.torigoya_quickSkill_recalcActionTime = function () {
        var actionTimes = this.makeActionTimes();
        for (var i = this._actions.length; i < actionTimes; i++) {
            this._actions.push(new Game_Action(this));
        }
    };

    // 行動選択後のバックを防止する
    var upstream_Game_Battler_performActionEnd = Game_Battler.prototype.performActionEnd;
    Game_Battler.prototype.performActionEnd = function() {
        var isInputting = this._actionState === 'inputting';
        upstream_Game_Battler_performActionEnd.apply(this);
        if (isInputting) this.setActionState('inputting');
    };

    // -------------------------------------------------------------------------
    // Scene_Battle

    // Actionが決定されたら、Actionの中にターン消費なしスキルがないか調べる
    var upstream_Scene_Battle_selectNextCommand = Scene_Battle.prototype.selectNextCommand;
    Scene_Battle.prototype.selectNextCommand = function () {
        QuickSkill.currentActionActor = BattleManager.actor();
        if (QuickSkill.currentActionActor) {
            var actions = QuickSkill.currentActionActor._actions;
            for (var i = 0; i < actions.length; ++i) {
                if (actions[i]._item.isNull()) continue;
                if (actions[i]._item.object().meta['QuickSkill']) {
                    actions.unshift(actions.splice(i, 1)[0]);
                    QuickSkill.originalSubject = BattleManager._subject;
                    BattleManager._subject = BattleManager.actor();
                    BattleManager.processTurn();
                    $gameTroop._interpreter.setupReservedCommonEvent();
                    return;
                }
            }
            QuickSkill.currentActionActor = null;
        }
        upstream_Scene_Battle_selectNextCommand.apply(this);
    };

    // -------------------------------------------------------------------------
    // BattleManager

    // 戦闘開始前に初期化処理を行う
    var upstream_BattleManager_setup = BattleManager.setup;
    BattleManager.setup = function (troopId, canEscape, canLose) {
        QuickSkill.reset();
        upstream_BattleManager_setup.apply(this, arguments);
    };

    // ターン消費なしスキル中なら後片付け
    var upstream_BattleManager_endAction = BattleManager.endAction;
    BattleManager.endAction = function () {
        QuickSkill.conflictData.currentChainAction = this._subject.currentChainAction && this._subject.currentChainAction();

        upstream_BattleManager_endAction.apply(this);

        // 後始末
        if (QuickSkill.currentActionActor) {
            if (QuickSkill.conflictData.currentChainAction) {
                QuickSkill.conflictData.currentChainAction = null;
            } else {
                this._phase = 'torigoya_quickSkill';
                this._subject = QuickSkill.originalSubject;
                if (this.actor() && this.actor().canInput()) {
                    this.changeActor(this._actorIndex, 'inputting');
                } else {
                    this.selectNextCommand();
                }
                QuickSkill.currentActionActor = null;
            }
        }
    };

    // ターン消費なしスキル中にイベントが積まれたら実行する
    var upstream_BattleManager_updateEvent = BattleManager.updateEvent;
    BattleManager.updateEvent = function () {
        switch (this._phase) {
            case 'turn':
                if (QuickSkill.actorIndexForForcedAction !== null) {
                    this._phase = 'torigoya_quickSkill';
                    this._actorIndex = QuickSkill.actorIndexForForcedAction;
                    QuickSkill.actorIndexForForcedAction = null;
                    QuickSkill.backupActions = null;
                }
                break;
            case 'torigoya_quickSkill':
                if (this.isActionForced()) {
                    QuickSkill.actorIndexForForcedAction = this._actorIndex;
                    this.processForcedAction();
                    return true;
                } else if (this.updateEventMain()) {
                    return true;
                }
                if (this._phase === 'torigoya_quickSkill') {
                    this._phase = QuickSkill.isBattleEnd() ? 'turn' : 'input';

                    // 行動回数の再計算
                    switch (QuickSkill.recalcMode()) {
                        case 'party':
                            $gameParty.members().forEach(function (member) {
                                member.torigoya_quickSkill_recalcActionTime();
                            });
                            break;
                        case 'actor':
                            $gameParty.members()[this._actorIndex].torigoya_quickSkill_recalcActionTime();
                            break;
                    }
                }
                this.refreshStatus();
                break;
        }
        return upstream_BattleManager_updateEvent.apply(this);
    };

    // -------------------------------------------------------------------------
    // 競合対策

    // NumbState.js
    // ターン消費なしスキルによる行動時には行動不能判定をしないようにする
    if (Game_BattlerBase.prototype.numb_occur) {
        var upstream_Game_BattlerBase_numb_occur = Game_BattlerBase.prototype.numb_occur;
        Game_BattlerBase.prototype.numb_occur = function() {
            if (QuickSkill.currentActionActor) return false;
            return upstream_Game_BattlerBase_numb_occur.apply(this);
        };
    }

    // -------------------------------------------------------------------------
    global.Torigoya = (global.Torigoya || {});
    global.Torigoya.QuickSkill = QuickSkill;
})(this);


code:
//=============================================================================
// TouchBindToKey.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.0 2016/02/27 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc マウス入力のキーバインドプラグイン
 * @author トリアコンタン
 *
 * @param 左クリックボタン
 * @desc 左クリックに対応するボタンです。
 * @default
 *
 * @param 中央クリックボタン
 * @desc 中央（ホイール）クリックに対応するボタンです。
 * @default
 *
 * @param 右クリックボタン
 * @desc 右クリックに対応するボタンです。
 * @default
 *
 * @param 元の動作を抑制
 * @desc もともとマウスに割り当てられていた機能を抑制します。
 * @default OFF
 *
 * @help マウスクリックを特定のボタンに紐付けます。
 * 紐付けた場合、クリックのもともとの動作は無効になります。
 *
 * ・パラメータに指定可能な文字列一覧
 * tab
 * ok
 * shift
 * control
 * escape
 * pageup
 * pagedown
 * left
 * up
 * right
 * down
 * debug
 * menu
 *
 * 注意！
 * 現状、マウス(PC)専用プラグインです。タッチ操作には対応していません。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

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

    var getParamString = function(paramNames, lowerFlg) {
        var value = getParamOther(paramNames);
        return value == null ? '' : lowerFlg ? value.toLowerCase() : value;
    };

    var getParamBoolean = function(paramNames) {
        var value = getParamOther(paramNames);
        return (value || '').toUpperCase() == 'ON';
    };

    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 paramBindLeft   = getParamString(['BindLeft', '左クリックボタン']);
    var paramBindMiddle = getParamString(['BindMiddle', '中央クリックボタン']);
    var paramBindRight  = getParamString(['BindRight', '右クリックボタン']);
    var paramSuppress   = getParamBoolean(['Suppress', '元の動作を抑制']);

    //=============================================================================
    // TouchInput
    //  動作をキー入力情報に送信します。
    //=============================================================================
    var _TouchInput_update = TouchInput.update;
    TouchInput.update = function() {
        _TouchInput_update.apply(this, arguments);
        if (paramSuppress) {
            if (paramBindLeft) {
                this._mousePressed = false;
                this._released = false;
                this._triggered = false;
                this._pressedTime = 0;
            }
            if (paramBindRight) {
                this._cancelled = false;
            }
        }
    };

    var _TouchInput__onLeftButtonDown = TouchInput._onLeftButtonDown;
    TouchInput._onLeftButtonDown = function(event) {
        _TouchInput__onLeftButtonDown.apply(this, arguments);
        if (paramBindLeft) Input.setCurrentStateForMouseBind(paramBindLeft, true);
    };

    var _TouchInput__onMiddleButtonDown = TouchInput._onMiddleButtonDown;
    TouchInput._onMiddleButtonDown = function(event) {
        _TouchInput__onMiddleButtonDown.apply(this, arguments);
        if (paramBindMiddle) Input.setCurrentStateForMouseBind(paramBindMiddle, true);
    };

    var _TouchInput__onRightButtonDown = TouchInput._onRightButtonDown;
    TouchInput._onRightButtonDown = function(event) {
        _TouchInput__onRightButtonDown.apply(this, arguments);
        if (paramBindRight) Input.setCurrentStateForMouseBind(paramBindRight, true);
    };

    var _TouchInput__onMouseUp = TouchInput._onMouseUp;
    TouchInput._onMouseUp = function(event) {
        _TouchInput__onMouseUp.apply(this, arguments);
        if (event.button === 0) {
            if (paramBindLeft)   Input.setCurrentStateForMouseBind(paramBindLeft, false);
        } else if (event.button === 1) {
            if (paramBindMiddle) Input.setCurrentStateForMouseBind(paramBindMiddle, false);
        } else if (event.button === 2) {
            if (paramBindRight)  Input.setCurrentStateForMouseBind(paramBindRight, false);
        }
    };

    //=============================================================================
    // Input
    //  TouchInputから送信された情報を受け取ります。
    //=============================================================================
    Input.setCurrentStateForMouseBind = function(button, value) {
        this._currentState[button] = !!value;
    };
})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// TriggerOnEquipAndState.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015-2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.5.1 2019/12/29 1.5.0の修正以後、パーティメンバーを外したときにエラーになっていた問題を修正
// 1.5.0 2019/11/25 装備スロットごとに変数を増減できる機能を追加
// 1.4.5 2018/05/05 1.4.4で動的データベース構築プラグインとの競合が発生していたので解消
// 1.4.4 2018/05/04 装備封印で外れた場合に変数の増減が行われない問題を修正
// 1.4.3 2018/01/27 DynamicVariables.jsとの連携機能を追加
// 1.4.2 2017/08/29 HIME_EquipSlotsCore.jsとの競合を解消
// 1.4.1 2017/01/12 メモ欄の値が空で設定された場合にエラーが発生するかもしれない問題を修正
// 1.4.0 2016/07/27 スイッチにも設定値タグを付けられるよう修正
// 1.3.2 2016/07/14 「武器(防具)の増減」によって装備が外れた場合に対応
// 1.3.1 2016/07/14 1.3.0で敵を倒した際にエラーになる現象の修正
// 1.3.0 2016/07/14 対象アクターがパーティから外れた場合にスイッチをOFFにする仕様を追加
// 1.2.1 2016/07/07 1.2.0が初期装備に対応していなかった問題を修正
// 1.2.0 2016/07/06 戦闘メンバーのみ有効になる設定を追加
// 1.1.0 2016/06/08 一つの装備で複数のスイッチ、変数を操作できるよう修正
// 1.0.1 2016/06/03 スクリプトに「>」「<」を使えるように修正
// 1.0.0 2016/04/03 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc TriggerOnEquipAndStatePlugin
 * @author Triacontane
 *
 * @param BattleMemberOnly
 * @desc 変数やスイッチが変動する対象となるアクターが戦闘メンバーに限定されます。
 * @default false
 * @type boolean
 *
 * @param SlotVariables
 * @desc 装備品を装備したスロット番号に対応する変数をメモ欄で指定した値だけ増減させます。
 * @default ["0","0","0","0","0"]
 * @type variable[]
 *
 * @help 装備またはステートの着脱時に、変数およびスイッチを操作できるようになります。
 * 着脱時に、スイッチの場合はON/OFFが切り替わり、変数の場合は値が増減します。
 * 操作対象および設定値には制御文字およびJavaScript計算式を利用できます。
 *
 * 対象となっているアクターがパーティから外れた場合、スイッチはOFFになります。
 * (ver1.3.0以降の仕様)
 *
 * [アイテム]および[ステート]のメモ欄に以下の通り記述してください。
 *
 * ・操作されるスイッチ番号や変数番号です。
 *  <TOESスイッチ対象:3>        // 3番のスイッチが操作対象
 *  <TOES変数対象:20 + actorId> // 20番 + アクターIDの変数が操作対象
 *
 * 通常の制御文字やJavaScript計算式に加えて「actorId」と記述すると、
 * 装備やステートが変更された対象のアクターIDに変換されます。
 *
 * ・スイッチに設定される値です。（省略時はONになります）
 *  <TOESスイッチ設定値:ON>  // 装備時にスイッチがONになり、解除するとOFFになります。
 *  <TOESスイッチ設定値:OFF> // 装備時にスイッチがOFFになり、解除するとONになります。
 *
 * ・変数に設定される値です。
 *  <TOES変数設定値:3> // 装備時に3加算され、解除すると3減算されます。
 *
 * 一度に二つ以上のスイッチや変数を操作したい場合は項目名の後ろに
 * 　数字を追加してください。(3以降も同様)
 *  <TOESスイッチ対象:3>   // 3番のスイッチが操作対象
 *  <TOESスイッチ対象2:5>  // 5番のスイッチも操作対象
 *
 *  注意！
 *  指定する際は、番号に歯抜けがないようにしてください。
 *  以下はダメです。
 *  <TOESスイッチ対象:3>   // 3番のスイッチが操作対象
 *  <TOESスイッチ対象3:5>  // 動作しない
 *
 * ・追加機能
 * 装備品ごとではなく装備スロットごとに変数値を増減できます。
 * パラメータ「スロット変数リスト」からスロット番号に対応する変数番号を指定して
 * さらにメモ欄に以下の通り設定します。
 *  <TOESスロット変数設定値:3> // 装備時に3加算され、解除すると3減算されます。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
/*:ja
 * @plugindesc 装備変更時の変数操作プラグイン
 * @author トリアコンタン
 *
 * @param BattleMemberOnly
 * @text 戦闘メンバーのみ
 * @desc 変数やスイッチが変動する対象となるアクターが戦闘メンバーに限定されます。
 * @default false
 * @type boolean
 *
 * @param SlotVariables
 * @text スロット変数リスト
 * @desc 装備品を装備したスロット番号に対応する変数をメモ欄で指定した値だけ増減させます。
 * @default ["0","0","0","0","0"]
 * @type variable[]
 *
 * @help 装備またはステートの着脱時に、変数およびスイッチを操作できるようになります。
 * 着脱時に、スイッチの場合はON/OFFが切り替わり、変数の場合は値が増減します。
 * 操作対象および設定値には制御文字およびJavaScript計算式を利用できます。
 *
 * 対象となっているアクターがパーティから外れた場合、スイッチはOFFになります。
 * (ver1.3.0以降の仕様)
 *
 * [アイテム]および[ステート]のメモ欄に以下の通り記述してください。
 *
 * ・操作されるスイッチ番号や変数番号です。
 *  <TOESスイッチ対象:3>        // 3番のスイッチが操作対象
 *  <TOES変数対象:20 + actorId> // 20番 + アクターIDの変数が操作対象
 *
 * 通常の制御文字やJavaScript計算式に加えて「actorId」と記述すると、
 * 装備やステートが変更された対象のアクターIDに変換されます。
 *
 * ・スイッチに設定される値です。（省略時はONになります）
 *  <TOESスイッチ設定値:ON>  // 装備時にスイッチがONになり、解除するとOFFになります。
 *  <TOESスイッチ設定値:OFF> // 装備時にスイッチがOFFになり、解除するとONになります。
 *
 * ・変数に設定される値です。
 *  <TOES変数設定値:3> // 装備時に3加算され、解除すると3減算されます。
 *
 * 一度に二つ以上のスイッチや変数を操作したい場合は項目名の後ろに
 * 　数字を追加してください。(3以降も同様)
 *  <TOESスイッチ対象:3>   // 3番のスイッチが操作対象
 *  <TOESスイッチ対象2:5>  // 5番のスイッチも操作対象
 *
 *  注意！
 *  指定する際は、番号に歯抜けがないようにしてください。
 *  以下はダメです。
 *  <TOESスイッチ対象:3>   // 3番のスイッチが操作対象
 *  <TOESスイッチ対象3:5>  // 動作しない
 *
 * ・追加機能
 * 装備品ごとではなく装備スロットごとに変数値を増減できます。
 * パラメータ「スロット変数リスト」からスロット番号に対応する変数番号を指定して
 * さらにメモ欄に以下の通り設定します。
 *  <TOESスロット変数設定値:3> // 装備時に3加算され、解除すると3減算されます。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';
    var metaTagPrefix = 'TOES';

    /**
     * Create plugin parameter. param[paramName] ex. param.commandPrefix
     * @param pluginName plugin name(EncounterSwitchConditions)
     * @returns {Object} Created parameter
     */
    var createPluginParameter = function(pluginName) {
        var paramReplacer = function(key, value) {
            if (value === 'null') {
                return value;
            }
            if (value[0] === '"' && value[value.length - 1] === '"') {
                return value;
            }
            try {
                return JSON.parse(value);
            } catch (e) {
                return value;
            }
        };
        var parameter     = JSON.parse(JSON.stringify(PluginManager.parameters(pluginName), paramReplacer));
        PluginManager.setParameters(pluginName, parameter);
        return parameter;
    };

    var param = createPluginParameter('TriggerOnEquipAndState');
    param.SlotVariables = param.SlotVariables || [];

    var getMetaValue = function(object, name) {
        var metaTagName = metaTagPrefix + (name ? name : '');
        return object.meta.hasOwnProperty(metaTagName) ? object.meta[metaTagName] : undefined;
    };

    var getMetaValues = function(object, names) {
        if (!Array.isArray(names)) return getMetaValue(object, names);
        for (var i = 0, n = names.length; i < n; i++) {
            var value = getMetaValue(object, names[i]);
            if (value !== undefined) return value;
        }
        return undefined;
    };

    var getArgString = function(arg, upperFlg) {
        arg = convertEscapeCharactersAndEval(arg, false);
        return upperFlg ? arg.toUpperCase() : arg;
    };

    var getArgNumber = function(arg, min, max) {
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(convertEscapeCharactersAndEval(arg, true), 10) || 0).clamp(min, max);
    };

    var getArgBoolean = function(arg) {
        return (arg || '').toUpperCase() === 'ON';
    };

    var convertEscapeCharactersAndEval = function(text, evalFlg) {
        if (text == null || text === true) text = '';
        text = text.replace(/>?/gi, '>');
        text = text.replace(/<?/gi, '<');
        text = text.replace(/\\/g, '\x1b');
        text = text.replace(/\x1b\x1b/g, '\\');
        text = text.replace(/\x1bV\[(\d+)\]/gi, function() {
            return $gameVariables.value(parseInt(arguments[1], 10));
        }.bind(this));
        text = text.replace(/\x1bV\[(\d+)\]/gi, function() {
            return $gameVariables.value(parseInt(arguments[1], 10));
        }.bind(this));
        text = text.replace(/\x1bN\[(\d+)\]/gi, function() {
            var actor = parseInt(arguments[1], 10) >= 1 ? $gameActors.actor(parseInt(arguments[1], 10)) : null;
            return actor ? actor.name() : '';
        }.bind(this));
        text = text.replace(/\x1bP\[(\d+)\]/gi, function() {
            var actor = parseInt(arguments[1], 10) >= 1 ? $gameParty.members()[parseInt(arguments[1], 10) - 1] : null;
            return actor ? actor.name() : '';
        }.bind(this));
        text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
        return evalFlg ? eval(text) : text;
    };

    //=============================================================================
    // Game_Party
    //  変数設定が必要かどうかを返します。
    //=============================================================================
    Game_Party.prototype.isNeedControlVariable = function(actor) {
        return !param.BattleMemberOnly || (this.battleMembers().contains(actor) || this.size() < this.maxBattleMembers());
    };

    Game_Party.prototype.getMembersNeedControl = function() {
        return param.BattleMemberOnly ? this.battleMembers() : this.members();
    };

    Game_Party.prototype.getReserveMembers = function() {
        var battleMembers = this.battleMembers();
        return this.members().filter(function(actor) {
            return !battleMembers.contains(actor);
        });
    };

    var _Game_Party_setupStartingMembers      = Game_Party.prototype.setupStartingMembers;
    Game_Party.prototype.setupStartingMembers = function() {
        _Game_Party_setupStartingMembers.apply(this, arguments);
        this.getMembersNeedControl().forEach(function(actor) {
            actor.onChangeMember(true);
        });
    };

    var _Game_Party_addActor      = Game_Party.prototype.addActor;
    Game_Party.prototype.addActor = function(actorId) {
        _Game_Party_addActor.apply(this, arguments);
        var actor = $gameActors.actor(actorId);
        if (this.getMembersNeedControl().contains(actor)) {
            actor.onChangeMember(true);
        }
    };

    var _Game_Party_removeActor      = Game_Party.prototype.removeActor;
    Game_Party.prototype.removeActor = function(actorId) {
        var actor = $gameActors.actor(actorId);
        if (this.getMembersNeedControl().contains(actor)) {
            actor.onChangeMember(false);
        }
        var reserveMembers = this.getReserveMembers();
        _Game_Party_removeActor.apply(this, arguments);
        if (param.BattleMemberOnly) {
            var members = this.battleMembers();
            reserveMembers.forEach(function(actor) {
                if (members.contains(actor)) {
                    actor.onChangeMember(true);
                }
            });
        }
    };

    var _Game_Party_swapOrder      = Game_Party.prototype.swapOrder;
    Game_Party.prototype.swapOrder = function(index1, index2) {
        var prevMembers = this.getMembersNeedControl();
        var actors      = [$gameActors.actor(this._actors[index1]), $gameActors.actor(this._actors[index2])];
        _Game_Party_swapOrder.apply(this, arguments);
        var members = this.getMembersNeedControl();
        actors.forEach(function(actor) {
            if (prevMembers.contains(actor) && !members.contains(actor)) {
                actor.onChangeMember(false);
            }
            if (members.contains(actor) && !prevMembers.contains(actor)) {
                actor.onChangeMember(true);
            }
        });
    };

    //=============================================================================
    // Game_Actor
    //  ステートが変更された際のスイッチ、変数制御を追加定義します。
    //=============================================================================
    var _Game_BattlerBase_addNewState      = Game_BattlerBase.prototype.addNewState;
    Game_BattlerBase.prototype.addNewState = function(stateId) {
        if (this instanceof Game_Actor && !this._states.contains(stateId)) {
            this.onChangeEquipAndState($dataStates[stateId], true);
        }
        _Game_BattlerBase_addNewState.apply(this, arguments);
    };

    var _Game_BattlerBase_eraseState      = Game_BattlerBase.prototype.eraseState;
    Game_BattlerBase.prototype.eraseState = function(stateId) {
        if (this instanceof Game_Actor && this._states.contains(stateId)) {
            this.onChangeEquipAndState($dataStates[stateId], false);
        }
        _Game_BattlerBase_eraseState.apply(this, arguments);
    };

    var _Game_BattlerBase_clearStates      = Game_BattlerBase.prototype.clearStates;
    Game_BattlerBase.prototype.clearStates = function() {
        if (this instanceof Game_Actor && this._states) {
            this._states.forEach(function(stateId) {
                this.onChangeEquipAndState($dataStates[stateId], false);
            }.bind(this));
        }
        _Game_BattlerBase_clearStates.apply(this, arguments);
    };

    //=============================================================================
    // Game_Actor
    //  装備が変更された際のスイッチ、変数制御を追加定義します。
    //=============================================================================
    var _Game_Actor_changeEquip      = Game_Actor.prototype.changeEquip;
    Game_Actor.prototype.changeEquip = function(slotId, item) {
        var prevItem = new Game_Item(this._equips[slotId].object());
        _Game_Actor_changeEquip.apply(this, arguments);
        var newItem = this._equips[slotId];
        if (prevItem.itemId() !== 0 && prevItem.itemId() !== newItem.itemId()) {
            this.onChangeEquipAndState(prevItem.object(), false, false, slotId);
        }
        if (newItem.itemId() !== 0 && newItem.itemId() !== prevItem.itemId()) {
            this.onChangeEquipAndState(newItem.object(), true, false, slotId);
        }
    };

    var _Game_Actor_discardEquip = Game_Actor.prototype.discardEquip;
    Game_Actor.prototype.discardEquip = function(item) {
        var slotId = this.equips().indexOf(item);
        if (slotId >= 0) {
            this.onChangeEquipAndState(item, false, false, slotId);
        }
        _Game_Actor_discardEquip.apply(this, arguments);
    };

    Game_Actor.prototype.onChangeMember = function(addedSign) {
        this.equips().forEach(function(equip, index) {
            if (equip && equip.id !== 0) {
                this.onChangeEquipAndState(equip, addedSign, true, index);
            }
        }.bind(this));
        this._states.forEach(function(stateId) {
            this.onChangeEquipAndState($dataStates[stateId], addedSign, true);
        }.bind(this));
    };

    var _Game_Actor_releaseUnequippableItems = Game_Actor.prototype.releaseUnequippableItems;
    Game_Actor.prototype.releaseUnequippableItems = function(forcing) {
        if (forcing) {
            _Game_Actor_releaseUnequippableItems.apply(this, arguments);
            return;
        }
        var prevEquips = this.equips();
        _Game_Actor_releaseUnequippableItems.apply(this, arguments);
        prevEquips.forEach(function(prevEquip, index) {
            var equip = this._equips[index].object();
            if (prevEquip && !equip) {
                this.onChangeEquipAndState(prevEquip, false, false, index);
            }
        }, this);
    };

    Game_Actor.prototype.onChangeEquipAndState = function(item, addedSign, force, slotId) {
        if (!$gameParty.isNeedControlVariable(this) && !force) return;
        var index = 1;
        while (index) {
            if (this.controlVariable(item, addedSign, index === 1 ? '' : String(index))) {
                index++;
            } else {
                index = 0;
            }
        }
        if (slotId !== undefined) {
            this.controlVariableForSlot(item, addedSign, slotId);
        }
    };

    Game_Actor.prototype.controlVariable = function(item, addedSign, indexString) {
        var switchTarget = getMetaValues(item, ['スイッチ対象' + indexString, 'SwitchTarget' + indexString]);
        var result       = false;
        if (switchTarget) {
            var switchId = this.getVariableIdForToes(switchTarget, $dataSystem.switches.length - 1);
            var switchValue = getMetaValues(item, ['スイッチ設定値' + indexString, 'SwitchValue' + indexString]);
            $gameSwitches.setValue(switchId, switchValue ? !(getArgBoolean(switchValue) ^ addedSign) : addedSign);
            result = true;
        }
        var variableTarget = getMetaValues(item, ['変数対象' + indexString, 'VariableTarget' + indexString]);
        if (variableTarget) {
            var variableId    = this.getVariableIdForToes(variableTarget, $dataSystem.variables.length - 1);
            var variableValue = getMetaValues(item, ['変数設定値' + indexString, 'VariableValue' + indexString]);
            this.changeVariable(variableId, variableValue, addedSign);
            result = true;
        }
        return result;
    };

    Game_Actor.prototype.controlVariableForSlot = function(item, addedSign, slotId) {
        var variableId = param.SlotVariables[slotId];
        var variableValue = getMetaValues(item, ['スロット変数設定値', 'SlotVariableValue']);
        if (variableId && variableValue) {
            this.changeVariable(variableId, variableValue, addedSign);
        }
    };

    Game_Actor.prototype.changeVariable = function(variableId, variableValue, addedSign) {
        // for DynamicVariables.js
        var originalValue = $gameVariables.getOriginalValue ? $gameVariables.getOriginalValue(variableId) : $gameVariables.value(variableId);
        var resultValue   = (variableValue ? getArgNumber(variableValue) : 1) * (addedSign ? 1 : -1);
        $gameVariables.setValue(variableId, originalValue + resultValue);
    };

    Game_Actor.prototype.getVariableIdForToes = function(target, max) {
        var actorId = this._actorId; // used in eval
        var result  = 0;
        try {
            result = eval(getArgString(target)).clamp(1, max);
        } catch (e) {
            console.error(e.toString());
            console.log(e.stack);
        }
        return result;
    };

    //=============================================================================
    // Game_EquipSlot
    //  for HIME_EquipSlotsCore.js
    //=============================================================================
    if (typeof Game_EquipSlot !== 'undefined') {
        Game_EquipSlot.prototype.itemId = function() {
            return this._item.itemId();
        };
    }
})();


code:
/*
 * ===========================================================================
 * ** Victor Engine MV - Basic Module
 * ---------------------------------------------------------------------------
 *  VE_BasicModule.js
 * ===========================================================================
 */

var Imported = Imported || {};
Imported['VE - Basic Module'] = '1.23';

var VictorEngine = VictorEngine || {};
VictorEngine.BasicModule = VictorEngine.BasicModule || {};

(function() {

    VictorEngine.BasicModule.loadDatabase = DataManager.loadDatabase;
    DataManager.loadDatabase = function() {
        VictorEngine.BasicModule.loadDatabase.call(this);
        PluginManager.requiredPlugin.call(PluginManager, 'VE - Basic Module');
    };

    PluginManager.requiredPlugin = function(name, required, version) {
        VictorEngine.BasicModule.checkPlugins(name, required, version);
    };

})();

/*:
 * ===========================================================================
 * @plugindesc v1.23 - Plugin with base code required for all Victor Engine plugins.
 * @author Victor Sant
 *
 * @param == Trait Names ==
 *
 * @param Hit Rate Name
 * @desc 'Hit Rate' Ex-Parameter name shown on windows.
 * @default Hit
 *
 * @param Evasion Rate Name
 * @desc 'Evasion Rate' Ex-Parameter name shown on windows.
 * @default Evasion
 *
 * @param Critical Rate Name
 * @desc 'Critical Rate' Ex-Parameter name shown on windows.
 * @default Critical
 *
 * @param Critical Evasion Name
 * @desc 'Critical Evasion' Ex-Parameter name shown on windows.
 * @default C. Evasion
 *
 * @param Magic Evasion Name
 * @desc 'Magic Evasion' Ex-Parameter name shown on windows.
 * @default M. Evasion
 *
 * @param Magic Reflection Name
 * @desc 'Magic Reflection' Ex-Parameter name shown on windows.
 * @default M. Reflection
 *
 * @param Counter Attack Name
 * @desc 'Counter Attack' Ex-Parameter name shown on windows.
 * @default Counter
 *
 * @param HP Regeneration Name
 * @desc 'HP Regeneration' Ex-Parameter name shown on windows.
 * @default HP Regen
 *
 * @param MP Regeneration Name
 * @desc 'MP Regeneration' Ex-Parameter name shown on windows.
 * @default MP Regen
 *
 * @param TP Regeneration Name
 * @desc 'TP Regeneration' Ex-Parameter name shown on windows.
 * @default TP Regen
 *
 * @param Target Rate Name
 * @desc 'Target Rate' Sp-Parameter name shown on windows.
 * @default Target Rate
 *
 * @param Guard Rate Name
 * @desc 'Guard Rate' Sp-Parameter name shown on windows.
 * @default Guard Rate
 *
 * @param Recovery Effect Name
 * @desc 'Recovery Effect' Sp-Parameter name shown on windows.
 * @default Recovery
 *
 * @param Pharmacology Name
 * @desc 'Pharmacology' Sp-Parameter name shown on windows.
 * @default Pharmacology
 *
 * @param MP Cost Rate Name
 * @desc 'MP Cost Rate' Sp-Parameter name shown on windows.
 * @default MP Cost
 *
 * @param TP Charge Rate Name
 * @desc 'TP Charge Rate' Sp-Parameter name shown on windows.
 * @default TP Charge
 *
 * @param Physical Damage Name
 * @desc 'Physical Damage' Sp-Parameter name shown on windows.
 * @default Physical Damage
 *
 * @param Magical Damage Name
 * @desc 'Magical Damage' Sp-Parameter name shown on windows.
 * @default Magical Damage
 *
 * @param Floor Damage Name
 * @desc 'Floor Damage' Sp-Parameter name shown on windows.
 * @default Floor Damage
 *
 * @param Experience Rate Name
 * @desc 'Experience Rate' Sp-Parameter name shown on windows.
 * @default Exp. Rate
 *
 * ===========================================================================
 * @help
 * ===========================================================================
 * Install this plugin above any other Victor Engine plugin.
 * ===========================================================================
 *
 * ===========================================================================
 *  Version History:
 * ---------------------------------------------------------------------------
 *  v 1.00 - 2015.11.26 > First release.
 *  v 1.01 - 2015.11.29 > Added function to get database objects.
 *  v 1.02 - 2015.12.07 > Added function to get multiples elements.
 *                      > Added check for plugin correct order.
 *  v 1.03 - 2015.12.13 > Added function to get page comments.
 *  v 1.04 - 2015.12.21 > Added function to check only relevant objects.
 *  v 1.05 - 2015.12.25 > Added check to wait bitmap loading.
 *  v 1.06 - 2015.12.31 > Added rgb to hex and hex to rgb functions.
 *                      > Added function to get plugins parameters.
 *  v 1.07 - 2016.01.07 > Fixed issue with plugin order checks.
 *  v 1.08 - 2016.01.17 > Added function to get BattleLog method index.
 *                      > Added function to insert methods on BattleLog.
 *  v 1.09 - 2016.01.24 > Added function to set wait for animations.
 *  v 1.10 - 2016.02.05 > Added function to get values from regex.
 *  v 1.11 - 2016.02.10 > Added function to capitalize texts.
 *                      > Added Plugin Parameter to set trait display names.
 *  v 1.12 - 2016.02.18 > Added function to get parameter names.
 *  v 1.13 - 2016.02.26 > Added functions to setup battler direction.
 *  v 1.14 - 2016.03.15 > Added functions to check opponents.
 *  v 1.15 - 2016.03.18 > Added function for compatibility with YEP.
 *  v 1.16 - 2016.03.23 > Added function to replace mathods.
 *                        Added functions for dynamic motions.
 *  v 1.17 - 2016.04.01 > Fixed issue with battler sprite check.
 *  v 1.18 - 2016.04.21 > Fixed issue with damage popup on action user.
 *  v 1.19 - 2016.04.30 > Added function to get evaluated font color.
 *  v 1.20 - 2016.05.12 > Added function to get width of text with escape codes.
 *  v 1.21 - 2016.05.31 > Improved method stack for dynamic motions.
 *                      > Added functions for compatibility with Battle Motions.
 *  v 1.22 - 2016.06.26 > Added functions for escape command.
 *  v 1.23 - 2017.05.25 > Added functions for damage formula.
 * ===========================================================================
 */

/*:ja
 * ===========================================================================
 * @plugindesc v1.23 - 全てのVictor Engineプラグインに必要なベースコード付きプラグイン
 * @author Victor Sant
 *
 * @param == Trait Names ==
 * @text == 特性名 ==
 *
 * @param Hit Rate Name
 * @text 命中率の名前
 * @desc '命中率'ウィンドウに表示される元パラメータ名
 * @default 命中
 *
 * @param Evasion Rate Name
 * @text 回避率の名前
 * @desc '回避率'ウィンドウに表示される元パラメータ名
 * @default 回避
 *
 * @param Critical Rate Name
 * @text 会心率の名前
 * @desc '会心率'ウィンドウに表示される元パラメータ名
 * @default 会心
 *
 * @param Critical Evasion Name
 * @text 会心回避率の名前
 * @desc '会心回避率'ウィンドウに表示される元のパラメータ名
 * @default 会心回避
 *
 * @param Magic Evasion Name
 * @text 魔法回避率の名前
 * @desc '魔法回避率'ウィンドウに表示される元のパラメータ名
 * @default 魔法回避
 *
 * @param Magic Reflection Name
 * @text 魔法反射率の名前
 * @desc '魔法反射率'ウィンドウに表示される元のパラメータ名
 * @default 魔法反射
 *
 * @param Counter Attack Name
 * @text 反撃率の名前
 * @desc '反撃率'ウィンドウに表示される元のパラメータ名
 * @default 反撃
 *
 * @param HP Regeneration Name
 * @text HP再生率の名前
 * @desc 'HP再生率'ウィンドウに表示される元のパラメータ名
 * @default HP再生
 *
 * @param MP Regeneration Name
 * @text MP再生率の名前
 * @desc 'MP再生率'ウィンドウに表示される元のパラメータ名
 * @default MP再生
 *
 * @param TP Regeneration Name
 * @text TP再生率の名前
 * @desc 'TP再生率'ウィンドウに表示される元のパラメータ名
 * @default TP再生
 *
 * @param Target Rate Name
 * @text 狙われ率の名前
 * @desc '狙われ率'ウィンドウに表示される元のパラメータ名
 * @default 狙われ率
 *
 * @param Guard Rate Name
 * @text 防御効果率の名前
 * @desc '防御効果率'ウィンドウに表示される元のパラメータ名
 * @default 防御効果率
 *
 * @param Recovery Effect Name
 * @text 回復効果率の名前
 * @desc '回復効果率'ウィンドウに表示される元のパラメータ名
 * @default 回復
 *
 * @param Pharmacology Name
 * @text 薬の知識の名前
 * @desc '薬の知識'ウィンドウに表示される元のパラメータ名
 * @default 薬の知識
 *
 * @param MP Cost Rate Name
 * @text MP消費率の名前
 * @desc 'MP消費率'ウィンドウに表示される元のパラメータ名
 * @default MP消費
 *
 * @param TP Charge Rate Name
 * @text TPチャージ率の名前
 * @desc 'TPチャージ率'ウィンドウに表示される元のパラメータ名
 * @default TPチャージ
 *
 * @param Physical Damage Name
 * @text 物理ダメージ率の名前
 * @desc '物理ダメージ率'ウィンドウに表示される元のパラメータ名
 * @default 物理ダメージ
 *
 * @param Magical Damage Name
 * @text 魔法ダメージ率の名前
 * @desc '魔法ダメージ率'ウィンドウに表示される元のパラメータ名
 * @default 魔法ダメージ
 *
 * @param Floor Damage Name
 * @text 床ダメージ率の名前
 * @desc '床ダメージ率'ウィンドウに表示される元のパラメータ名
 * @default 床ダメージ
 *
 * @param Experience Rate Name
 * @text 経験値獲得率の名前
 * @desc '経験値獲得率'ウィンドウに表示される元のパラメータ名
 * @default 経験値獲得率
 *
 * ===========================================================================
 * @help
 * 翻訳:ムノクラ
 * https://fungamemake.com/
 * https://twitter.com/munokura/
 *
 * 元プラグイン:
 * https://victorenginescripts.wordpress.com/rpg-maker-mv/basic-module/
 * ===========================================================================
 * このプラグインを他のVictor Engineプラグインの上にインストールします。
 * ===========================================================================
 *
 * ===========================================================================
 *  Version History:
 * ---------------------------------------------------------------------------
 *  v1.00 - 2015.11.26 First release.
 *  v1.01 - 2015.11.29 Added function to get database objects.
 *  v1.02 - 2015.12.07 Added function to get multiples elements.
 *                     Added check for plugin correct order.
 *  v1.03 - 2015.12.13 Added function to get page comments.
 *  v1.04 - 2015.12.21 Added function to check only relevant objects.
 *  v1.05 - 2015.12.25 Added check to wait bitmap loading.
 *  v1.06 - 2015.12.31 Added rgb to hex and hex to rgb functions.
 *                     Added function to get plugins parameters.
 *  v1.07 - 2016.01.07 Fixed issue with plugin order checks.
 *  v1.08 - 2016.01.17 Added function to get BattleLog method index.
 *                     Added function to insert methods on BattleLog.
 *  v1.09 - 2016.01.24 Added function to set wait for animations.
 *  v1.10 - 2016.02.05 Added function to get values from regex.
 *  v1.11 - 2016.02.10 Added function to capitalize texts.
 *                     Added Plugin Parameter to set trait display names.
 *  v1.12 - 2016.02.18 Added function to get parameter names.
 *  v1.13 - 2016.02.26 Added functions to setup battler direction.
 *  v1.14 - 2016.03.15 Added functions to check opponents.
 *  v1.15 - 2016.03.18 Added function for compatibility with YEP.
 *  v1.16 - 2016.03.23 Added function to replace mathods.
 *                     Added functions for dynamic motions.
 *  v1.17 - 2016.04.01 Fixed issue with battler sprite check.
 *  v1.18 - 2016.04.21 Fixed issue with damage popup on action user.
 *  v1.19 - 2016.04.30 Added function to get evaluated font color.
 *  v1.20 - 2016.05.12 Added function to get width of text with escape codes.
 *  v1.21 - 2016.05.31 Improved method stack for dynamic motions.
 *                     Added functions for compatibility with Battle Motions.
 *  v1.22 - 2016.06.26 Added functions for escape command.
 *  v1.23 - 2017.05.25 Added functions for damage formula.
 * ===========================================================================
 */

(function() {

    //===========================================================================
    // Parameters
    //===========================================================================

    VictorEngine.getPluginParameters = function() {
        var script = document.currentScript || (function() {
            var scripts = document.getElementsByTagName('script');
            return scripts[scripts.length - 1];
        })();
        var start = script.src.lastIndexOf('/') + 1;
        var end = script.src.indexOf('.js');
        return PluginManager.parameters(script.src.substring(start, end));
    }

    var parameters = VictorEngine.getPluginParameters();
    VictorEngine.Parameters = VictorEngine.Parameters || {};
    VictorEngine.Parameters.BasicModule = {};
    VictorEngine.Parameters.BasicModule.hit = String(parameters["Hit Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.eva = String(parameters["Evasion Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.cri = String(parameters["Critical Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.cev = String(parameters["Critical Evasion Name"]).trim();
    VictorEngine.Parameters.BasicModule.hev = String(parameters["Magic Evasion Name"]).trim();
    VictorEngine.Parameters.BasicModule.mrf = String(parameters["Magic Reflection Name"]).trim();
    VictorEngine.Parameters.BasicModule.cnt = String(parameters["Counter Attack Name"]).trim();
    VictorEngine.Parameters.BasicModule.hrg = String(parameters["HP Regeneration Name"]).trim();
    VictorEngine.Parameters.BasicModule.mrg = String(parameters["MP Regeneration Name"]).trim();
    VictorEngine.Parameters.BasicModule.trg = String(parameters["TP Regeneration Name"]).trim();
    VictorEngine.Parameters.BasicModule.tgr = String(parameters["Target Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.grd = String(parameters["Guard Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.rec = String(parameters["Recovery Effect Name"]).trim();
    VictorEngine.Parameters.BasicModule.pha = String(parameters["Pharmacology Name"]).trim();
    VictorEngine.Parameters.BasicModule.mcr = String(parameters["MP Cost Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.tcr = String(parameters["TP Charge Rate Name"]).trim();
    VictorEngine.Parameters.BasicModule.pdr = String(parameters["Physical Damage Name"]).trim();
    VictorEngine.Parameters.BasicModule.mdr = String(parameters["Magical Damage Name"]).trim();
    VictorEngine.Parameters.BasicModule.fdr = String(parameters["Floor Damage"]).trim();
    VictorEngine.Parameters.BasicModule.ext = String(parameters["Experience"]).trim();

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

    VictorEngine.BasicModule.isDatabaseLoaded = DataManager.isDatabaseLoaded;
    DataManager.isDatabaseLoaded = function() {
        if (!VictorEngine.BasicModule.isDatabaseLoaded.call(this)) return false;
        VictorEngine.loadParameters();
        VictorEngine.loadNotetags();
        return ImageManager.isReady();
    };

    //===========================================================================
    // VictorEngine
    //===========================================================================

    VictorEngine.BasicModule.checkPlugins = function(name, req, ver) {
        var msg = '';
        this.loadedPlugins = this.loadedPlugins || {};
        if (ver && req && (!Imported[req] || Number(Imported[req]) < Number(ver))) {
            msg += 'The plugin ' + name + ' requires the plugin ' + req;
            msg += ' v' + ver + ' or higher installed to work properly'
            if (Number(Imported[req]) < Number(ver)) {
                msg += '. Your current version is v' + Imported[req];
            }
            msg += '. Go to http://victorenginescripts.wordpress.com/'
            msg += ' to download the updated plugin.';
            throw msg;
        } else if (!ver && req && this.loadedPlugins[req] === true) {
            msg += 'The plugin ' + name + ' requires the plugin ' + req;
            msg += ' to be placed bellow it. Open the Plugin Manager and place';
            msg += ' the plugins in the correct order.';
            throw msg;
        } else if (req && Imported['VE - Basic Module'] && !this.loadedPlugins['VE - Basic Module']) {
            msg += 'The plugin ' + name + ' must be placed bellow the plugin ' + req;
            msg += '. Open the Plugin Manager and place';
            msg += ' the plugins in the correct order.';
            throw msg;
        } else {
            this.loadedPlugins[name] = true
        }
    };

    VictorEngine.loadNotetags = function() {
        if (VictorEngine.BasicModule.loaded) return;
        VictorEngine.BasicModule.loaded = true;
        var list = [$dataActors, $dataClasses, $dataSkills, $dataItems, $dataWeapons,
            $dataArmors, $dataEnemies, $dataStates
        ];
        list.forEach(function(objects, index) {
            this.processNotetags(objects, index)
        }, this);
    };

    VictorEngine.processNotetags = function(objects, index) {
        objects.forEach(function(data) {
            if (data) {
                this.loadNotetagsValues(data, index);
            }
        }, this);
    };

    VictorEngine.objectSelection = function(index, list) {
        var objects = ['actor', 'class', 'skill', 'item', 'weapon', 'armor', 'enemy', 'state'];
        return list.contains(objects[index]);
    };

    VictorEngine.loadNotetagsValues = function(data, index) {};

    VictorEngine.loadParameters = function() {};

    VictorEngine.getNotesValues = function(value1, value2) {
        value2 = value2 || value1;
        return new RegExp('<' + value1 + '>([\\s\\S]*?)<\\/' + value2 + '>', 'gi');
    };

    VictorEngine.getPageNotes = function(event) {
        var result = (event instanceof Game_CommonEvent) || event.page();
        if (!result || !event.list()) {
            return "";
        }
        return event.list().reduce(function(r, cmd) {
            var valid = (cmd.code === 108 || cmd.code === 408);
            var comment = valid ? cmd.parameters[0] + "\r\n" : "";
            return r + comment;
        }, "");
    };

    VictorEngine.getAllElements = function(subject, action) {
        if (action.item().damage.elementId < 0) {
            return subject.attackElements();
        } else {
            return [action.item().damage.elementId];
        }
    };

    VictorEngine.getAllStates = function(subject, item) {
        var result;
        return item.effects.reduce(function(r, effect) {
            if (effect.code === 21) {
                if (effect.dataId === 0) {
                    result = subject.attackStates();
                } else {
                    result = [effect.dataId];
                };
            } else {
                result = [];
            };
            return r.concat(result);
        }, []);
    };

    VictorEngine.getDamageFormula = function(action) {
		return action.item().damage.formula;
    };

    VictorEngine.getNumberValue = function(match, type, base) {
        var regex = new RegExp(type + '[ ]*:[ ]*([+-.\\d]+)', 'gi');
        var value = regex.exec(match);
        return value ? Number(value[1]) : base;
    };

    VictorEngine.getStringValue = function(match, type, base) {
        var regex = new RegExp(type + "[ ]*:[ ]*([\\w ]+)", 'gi');
        var value = regex.exec(match);
        return value ? value[1].trim() : base;
    };

    VictorEngine.getAnyValue = function(match, type, base) {
        var regex = new RegExp(type + "[ ]*:[ ]*('[^\']+'|\"[^\"]+\")", 'gi');
        var value = regex.exec(match);
        return value ? value[1].slice(1, -1) : base;
    };

    VictorEngine.getNumberValues = function(match, type) {
        var regex = new RegExp(type + '[ ]*:[ ]*((?:[+-.\\d]+[ ]*,?[ ]*)+)', 'gi');
        var value = regex.exec(match);
        var result = value ? value[1].match(/\d+/gi) : [];
        return result.map(function(id) {
            return Number(id)
        });
    };

    VictorEngine.getStringValues = function(match, type) {
        var regex = new RegExp(type + '[ ]*:[ ]*((?:[\\w ]+[ ]*,?[ ]*)+)', 'gi');
        var value = regex.exec(match);
        var result = value ? value[1].match(/\d+/gi) : [];
        return result.map(function(id) {
            return value[1].trim()
        });
    };

    VictorEngine.captalizeText = function(text) {
        return text.replace(/(?:^|\s)\S/g, function(a) {
            return a.toUpperCase();
        });
    };

    VictorEngine.replaceZeros = function(text, value) {
        value = value || '';
        return text.replace(/\b(0(?!\b))+/g, function(a) {
            return a.replace(/0/g, value);
        });
    };

    VictorEngine.rgbToHex = function(r, g, b) {
        r = Math.floor(r).toString(16).padZero(2);
        g = Math.floor(g).toString(16).padZero(2);
        b = Math.floor(b).toString(16).padZero(2);
        return '#' + r + g + b;
    }

    VictorEngine.hexToRgb = function(hex) {
        var r = parseInt(hex[1] + hex[2], 16);
        var g = parseInt(hex[3] + hex[4], 16);
        var b = parseInt(hex[5] + hex[6], 16);
        return [r, g, b];
    }

    VictorEngine.methodIndex = function(methods, name) {
        for (var i = 0; i < methods.length; i++) {
            if (methods[i] && methods[i].name === name) {
                return i;
            }
        }
        return null;
    }

    VictorEngine.removeMethod = function(methods, name) {
        var index = this.methodIndex(methods, name);
        if (index || index === 0) {
            methods.splice(index, 1);
        }
    }

    VictorEngine.insertMethod = function(methods, index, name, params) {
        if (index || index === 0) {
            methods.splice(index, 0, {
                name: name,
                params: params
            });
        }
    }

    VictorEngine.replaceMethod = function(methods, index, name, params) {
        if (index || index === 0) {
            methods.splice(index, 1, {
                name: name,
                params: params
            });
        }
    }

    VictorEngine.waitAnimation = function(animationId) {
        var animation = $dataAnimations[animationId];
        return animation ? animation.frames.length * 4 + 1 : 0;
    };

    VictorEngine.params = function() {
        return ['hp', 'mp', 'atk', 'def', 'mat', 'mdf', 'agi', 'luk'];
    };

    VictorEngine.xparams = function() {
        return ['hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt', 'hrg', 'mrg', 'trg'];
    };

    VictorEngine.sparams = function() {
        return ['tgr', 'grd', 'rec', 'pha', 'mcr', 'tcr', 'prd', 'mrd', 'frd', 'exr'];
    };

    VictorEngine.allParams = function() {
        return this.params().concat(this.xparams(), this.sparams())
    };

    VictorEngine.paramName = function(paramId) {
        return this.params()[paramId];
    };

    VictorEngine.xparamName = function(xparamId) {
        return this.xparams()[xparamId];
    };

    VictorEngine.sparamName = function(sparamId) {
        return this.sparams()[sparamId];
    };

    VictorEngine.paramId = function(paramName) {
        return this.params().indexOf(paramName.toLowerCase());
    };

    VictorEngine.paramText = function(name) {
        switch (name.toLowerCase()) {
            case 'hit':
            case 'eva':
            case 'cri':
            case 'cev':
            case 'mev':
            case 'mrf':
            case 'cnt':
            case 'hrg':
            case 'mrg':
            case 'trg':
            case 'tgr':
            case 'grd':
            case 'rec':
            case 'pha':
            case 'mcr':
            case 'tcr':
            case 'pdr':
            case 'mdr':
            case 'fdr':
            case 'ext':
                return this.Parameters.BasicModule[name.toLowerCase()];
            case 'hp':
            case 'atk':
            case 'def':
            case 'agi':
            case 'mp':
            case 'mat':
            case 'mdf':
            case 'luk':
                var paramId = this.params().indexOf(name.toLowerCase());
                return TextManager.param(paramId)
            default:
                return this.captalizeText(name.toLowerCase());
        }
    };

    VictorEngine.battlerIndex = function(battler) {
        if (battler && battler.isActor() && $gameParty.members().contains(battler)) {
            return 1 + $gameParty.members().indexOf(battler);
        } else if (battler && battler.isEnemy() && $gameTroop.members().contains(battler)) {
            return 1 + $gameParty.maxBattleMembers() + $gameTroop.members().indexOf(battler);
        } else {
            return 0;
        }
    };

    VictorEngine.battleSprites = function(spriteId) {
        return this._battleSprites[spriteId];
    };

    VictorEngine.addBattleSprite = function(spriteId, sprite) {
        this._battleSprites = this._battleSprites || {};
        this._battleSprites[spriteId] = sprite;
    };

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

    BattleManager.updateStackAction = function(index, subject, target) {
        this._logWindow.saveMethodsStack(index);
        this.clearTargets(target);
        this.invokeAction(subject, target);
        this._logWindow.restoreMethodsStack(index);
    };

    BattleManager.clearTargets = function(target) {
        for (var i = 0; i < this._targets.length; i++) {
            if (this._targets[i] === target) {
                this._targets.splice(i, 1);
                i--;
            }
        }
    };

    BattleManager.clearActionTargets = function() {
        this._targets = [];
    };

    BattleManager.prepareAction = function(subject, action, targets, skip) {
        this._phase = 'action';
        this._subject = subject;
        this._action = action;
        this._targets = targets;
        if (skip) {
            subject.useItem(action.item());
        }
        this._action.applyGlobal();
        this.refreshStatus();
    };

    BattleManager.startCounterAction = function(subject, target, targets, action) {
        if (targets.length > 0) {
            this._isCounterAttack = true;
            this._counterSubject = subject;
            this._counterTarget = target;
            this.prepareAction(subject, action, targets);
            this._logWindow.startCounterAction(subject, action, targets);
        }
    };

    BattleManager.averageTargetsPositions = function(targets) {
        var x = targets.reduce(function(r, member) {
            return r + member.screenX();
        }, 0) / targets.length;
        var y = targets.reduce(function(r, member) {
            return r + member.screenX();
        }, 0) / targets.length;
        return {
            x: x,
            y: y
        };
    };

    BattleManager.isSurprise = function() {
        return this._surprise;
    };

    BattleManager.isPreemptive = function() {
        return this._preemptive;
    };

    //===========================================================================
    // SceneManager
    //===========================================================================

    SceneManager.sceneSpriteset = function() {
        return this._scene ? this._scene._spriteset : null;
    };

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

    Window_Base.prototype.getFontColor = function(color) {
        if (color.match(/^\#[abcdef\d]{6}/i)) {
            return '"' + color + '"';
        } else {
            return color;
        }
    };

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

    Game_Action.prototype.setEscape = function() {
        var action = {
            name: TextManager.escape,
            speed: 9999,
            escape: true
        };
        this._escapeAction = action;
    };

    Game_Action.prototype.isEscape = function() {
        return !!this._escapeAction;
    };

    //===========================================================================
    // Game_Unit
    //===========================================================================

    Game_Unit.prototype.averageX = function() {
        return this.aliveMembers().reduce(function(r, member) {
            return r + member.screenX();
        }, 0) / this.aliveMembers().length;
    };

    Game_Unit.prototype.averageY = function() {
        return this.aliveMembers().reduce(function(r, member) {
            return r + member.screenY();
        }, 0) / this.aliveMembers().length;
    };

    //===========================================================================
    // Game_Player
    //===========================================================================

    Game_Player.prototype.follower = function(index) {
        return index === 0 ? this : this.followers().follower(index - 1);
    };

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

    Game_BattlerBase.prototype.screenX = function() {
        return this.spriteScreenX() || this._screenX || 0;
    };

    Game_BattlerBase.prototype.screenY = function() {
        return this.spriteScreenY() || this._screenY || 0;
    };

    Game_BattlerBase.prototype.homeX = function() {
        return this.battleSprite() ? this.battleSprite().homeX() : 0;
    };

    Game_BattlerBase.prototype.homeY = function() {
        return this.battleSprite() ? this.battleSprite().homeY() : 0;
    };

    Game_BattlerBase.prototype.spriteScreenX = function() {
        return this.battleSprite() ? this.battleSprite().screenX() : 0;
    };

    Game_BattlerBase.prototype.spriteScreenY = function() {
        return this.battleSprite() ? this.battleSprite().screenY() : 0;
    };

    Game_BattlerBase.prototype.mainSprite = function() {
        return this.battleSprite() ? this.battleSprite().mainSprite() : null;
    };

    Game_BattlerBase.prototype.friends = function() {
        return this.isActor() ? $gameParty : $gameTroop;
    };

    Game_BattlerBase.prototype.opponents = function() {
        return this.isEnemy() ? $gameParty : $gameTroop;
    };

    Game_BattlerBase.prototype.isOpponent = function(battler) {
        return this.isEnemy() === !battler.isEnemy();
    };

    Game_BattlerBase.prototype.idleMotions = function() {
        return ['wait', 'idle', 'dying', 'abnormal', 'guard', 'chant', 'sleep', 'victory', 'dead'];
    };

    Game_BattlerBase.prototype.isIdleMotion = function(motionType) {
        return this.idleMotions().contains(motionType);
    };

    Game_BattlerBase.prototype.isFacingDown = function() {
        return this.battlerDirection() === 'down';
    };

    Game_BattlerBase.prototype.isFacingLeft = function() {
        return this.battlerDirection() === 'left';
    };

    Game_BattlerBase.prototype.isFacingRight = function() {
        return this.battlerDirection() === 'right';
    };

    Game_BattlerBase.prototype.isFacingUp = function() {
        return this.battlerDirection() === 'up';
    };

    Game_BattlerBase.prototype.isFacingHorizontal = function() {
        return this.isFacingLeft() || this.isFacingRight();
    };

    Game_BattlerBase.prototype.isFacingVertical = function() {
        return this.isFacingDown() || this.isFacingUp();
    };

    Game_BattlerBase.prototype.turnDown = function() {
        this._battlerDirection = 'down';
    };

    Game_BattlerBase.prototype.turnLeft = function() {
        this._battlerDirection = 'left';
    };

    Game_BattlerBase.prototype.turnRight = function() {
        this._battlerDirection = 'right';
    };

    Game_BattlerBase.prototype.turnUp = function() {
        this._battlerDirection = 'up';
    };

    Game_BattlerBase.prototype.turnBack = function() {
        if (this.isFacingLeft()) {
            this.turnRight();
        } else if (this.isFacingRight()) {
            this.turnLeft();
        }
    };

    Game_BattlerBase.prototype.turnTowardCenter = function() {
        this.turnTowardPosition(Graphics.boxWidth / 2, Graphics.boxHeight / 2);
    };

    Game_BattlerBase.prototype.turnAwayFromCenter = function() {
        this.turnAwayFromPosition(Graphics.boxWidth / 2, Graphics.boxHeight / 2);
    };

    Game_BattlerBase.prototype.turnTowardOpponents = function() {
        this.turnTowardPosition(this.opponents().averageX(), this.opponents().averageY());
    };

    Game_BattlerBase.prototype.turnAwayFromOpponents = function() {
        this.turnAwayFromPosition(this.opponents().averageX(), this.opponents().averageY);
    };

    Game_BattlerBase.prototype.turnTowardTargets = function(targets) {
        var position = BattleManager.averageTargetsPositions(targets);
        this.turnTowardPosition(position.x, position.y);
    };

    Game_BattlerBase.prototype.turnAwayFromTargets = function(targets) {
        var position = BattleManager.averageTargetsPositions(targets);
        this.turnAwayFromPosition(position.x, position);
    };

    Game_BattlerBase.prototype.turnTowardPosition = function(positionX, positionY) {
        if (this.screenX() < positionX) {
            this.turnRight();
        } else if (this.screenX() > positionX) {
            this.turnLeft();
        }
    };

    Game_BattlerBase.prototype.turnAwayFromPosition = function(positionX, positionY) {
        if (this.screenX() < positionX) {
            this.turnLeft();
        } else if (this.screenX() > positionX) {
            this.turnRight();
        }
    };

    Game_BattlerBase.prototype.isBehind = function(target) {
        return (target.isFacingRight() && this.screenX() < target.screenX()) ||
            (target.isFacingLeft() && this.screenX() > target.screenX());
    };

    Game_BattlerBase.prototype.isSpriteEffecting = function() {
        return this.battleSprite() && this.battleSprite().isEffecting();
    };

    Game_BattlerBase.prototype.isSpriteMoving = function() {
        return this.battleSprite() && this.battleSprite().isMoving();
    };

    Game_BattlerBase.prototype.isSpriteAnimation = function() {
        return this.battleSprite() && this.battleSprite().isAnimationPlaying();
    };

    Game_BattlerBase.prototype.isAnimatedBattler = function() {
        return this.battleSprite() && this.battleSprite().isAnimatedBattler();
    };

    Game_BattlerBase.prototype.isStaticBattler = function() {
        return this.battleSprite() && this.battleSprite().isStaticBattler();
    };

    Game_BattlerBase.prototype.inHomePosition = function() {
        return this.battleSprite() && this.battleSprite().inHomePosition();
    };

    Game_BattlerBase.prototype.notIinHomePosition = function() {
        return !this.inHomePosition();
    };

    Game_BattlerBase.prototype.isCounterAttack = function() {
        return this._counterAttack;
    };

    Game_BattlerBase.prototype.startCounterAttack = function() {
        this._counterAttack = true;
    };

    Game_BattlerBase.prototype.endCounterAttack = function() {
        this._counterAttack = false;
    };

    Game_BattlerBase.prototype.battleSprite = function() {
        return VictorEngine.battleSprites(this.spriteId());
    };

    Game_BattlerBase.prototype.setBattleSprite = function(sprite) {
        VictorEngine.addBattleSprite(this.spriteId(), sprite);
    };

    Game_BattlerBase.prototype.clearBattleSprite = function() {
        VictorEngine.addBattleSprite(this.spriteId(), null);
    };

    Game_BattlerBase.prototype.addNewAction = function(action) {
        this._actions.unshift(action);
    };

    Game_BattlerBase.prototype.startEscapeCommand = function() {
        this._isEscapeCommand = true;
    };
    Game_BattlerBase.prototype.endEscapeCommand = function() {
        this._isEscapeCommand = false;
    };
    Game_BattlerBase.prototype.isEscapeCommand = function() {
        return this._isEscapeCommand;
    };

    //===========================================================================
    // Game_Battler
    //===========================================================================

    VictorEngine.BasicModule.onBattleEnd = Game_Battler.prototype.onBattleEnd;
    Game_Battler.prototype.onBattleEnd = function() {
        VictorEngine.BasicModule.onBattleEnd.call(this);
        this.clearBattleSprite();
    };

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

    Game_Actor.prototype.battlerDirection = function() {
        return this._battlerDirection || 'left';
    };

    Game_Actor.prototype.spriteId = function() {
        return 'actor ' + String(this.actorId());
    };

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

    Game_Enemy.prototype.battlerDirection = function() {
        return this._battlerDirection || ($gameSystem.isSideView() ? 'right' : 'left');
    };

    Game_Enemy.prototype.attackAnimationId1 = function() {
        return 0;
    };

    Game_Enemy.prototype.attackAnimationId2 = function() {
        return 0;
    };

    Game_Enemy.prototype.spriteId = function() {
        return 'enemy ' + String(this.index());
    };

    //===========================================================================
    // Sprite_Battler
    //===========================================================================

    Object.defineProperties(Sprite_Battler.prototype, {
        z: {
            get: function() {
                return 3;
            },
            configurable: true
        },
        h: {
            get: function() {
                return this.spriteZ();
            },
            configurable: true
        }
    });

    Sprite_Battler.prototype.isEnemy = function() {
        return this._battler && this._battler.isEnemy();
    };

    Sprite_Battler.prototype.isVisible = function() {
        return this.visible && this.opacity > 0;
    };

    Sprite_Battler.prototype.isDamagePopup = function() {
        return this._damages.length > 0;
    };

    Sprite_Battler.prototype.isDisabledMotion = function() {
        var motion = Sprite_Actor.MOTIONS;
        return this._motion === motion['dead'] || this._motion === motion['sleep'];
    };

    Sprite_Battler.prototype.isAnimatedBattler = function() {
        return false;
    };

    Sprite_Battler.prototype.isStaticBattler = function() {
        return false;
    };

    Sprite_Battler.prototype.spriteZ = function() {
        return this.screenY();
    };

    Sprite_Battler.prototype.screenX = function() {
        return this._homeX + this._offsetX;
    };

    Sprite_Battler.prototype.screenY = function() {
        return this._homeY + this._offsetY;
    };

    Sprite_Battler.prototype.homeX = function() {
        return this._homeX;
    };

    Sprite_Battler.prototype.homeY = function() {
        return this._homeY;
    };

    Sprite_Battler.prototype.mainSprite = function() {
        return this._mainSprite;
    };

    Sprite_Battler.prototype.noEntryMove = function() {
        return this._battler && !this._battler.canMove();
    };

    Sprite_Battler.prototype.center = function() {
        var sprite = this._mainSprite ? this._mainSprite : this;
        var x = sprite._frame.width / 2 || 0;
        var y = sprite._frame.height / 2 || 0;
        return {
            x: x,
            y: y
        };
    };

    //===========================================================================
    // Sprite_Actor
    //===========================================================================

    Sprite_Actor.prototype.updateBattlerDirection = function() {
        if (this._battler && !this.isDisabledMotion()) {
            if ((this._battler.isFacingLeft() && this.scale.x < 0) ||
                (this._battler.isFacingRight() && this.scale.x > 0)) {
                this.scale.x *= -1;
            }
        }
    };

    //===========================================================================
    // Sprite_Enemy
    //===========================================================================

    Sprite_Enemy.prototype.updateBattlerDirection = function() {
        if (this._battler && !this.isDisabledMotion()) {
            if ((this._battler.isFacingLeft() && this.scale.x > 0) ||
                (this._battler.isFacingRight() && this.scale.x < 0)) {
                this.scale.x *= -1;
            }
        }
    };

    Sprite_Enemy.prototype.isStaticBattler = function() {
        return true;
    };

    //===========================================================================
    // Sprite_Damage
    //===========================================================================

    Object.defineProperties(Sprite_Damage.prototype, {
        z: {
            get: function() {
                return 10;
            },
            configurable: true
        }
    });

    //===========================================================================
    // Spriteset_Battle
    //===========================================================================

    VictorEngine.BasicModule.setBattler = Sprite_Battler.prototype.setBattler;
    Sprite_Battler.prototype.setBattler = function(battler) {
        VictorEngine.BasicModule.setBattler.call(this, battler);
        if (battler) {
            battler.setBattleSprite(this);
        }
    };

    Spriteset_Battle.prototype.sortBattleSprites = function() {
        if (this._sortChildrenFrame !== Graphics.frameCount) {
            this._battleField.children.sort(this.compareBattleSprites.bind(this));
            this._sortChildrenFrame = Graphics.frameCount;
        }
    };

    Spriteset_Battle.prototype.compareBattleSprites = function(a, b) {
        if ((a.z || 0) !== (b.z || 0)) {
            return (a.z || 0) - (b.z || 0);
        } else if ((a.h || 0) !== (b.h || 0)) {
            return (a.h || 0) - (b.h || 0);
        } else if ((a.y || 0) !== (b.y || 0)) {
            return (a.y || 0) - (b.y || 0);
        } else {
            return a.spriteId - b.spriteId;
        }
    };

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

    Window_Base.prototype.textWidthEx = function(text) {
        if (text) {
            var state = {
                index: 0,
                x: 0
            };
            state.text = this.convertEscapeCharacters(text);
            while (state.index < state.text.length) {
                this.processCharacter(state)
            };
            return state.x;
        } else {
            return 0;
        }
    };

    //===========================================================================
    // Window_BattleLog
    //===========================================================================

    Window_BattleLog.prototype.waitForBattleAnimation = function(animationId, speed) {
        var speed = Math.max(speed, 1) || 1;
        this.waitForTime(VictorEngine.waitAnimation(animationId) / speed);
    };

    Window_BattleLog.prototype.startCounterAction = function(subject, action, targets) {
        this.push('addText', TextManager.counterAttack.format(subject.name()));
        this.startAction(subject, action, targets);
    };

    Window_BattleLog.prototype.waitForTime = function(time) {
        this._waitCount = time;
    };

    Window_BattleLog.prototype.setupStartAction = function(subject, action, targets) {
        if (this._setupStartActionFrame !== Graphics.frameCount) {
            VictorEngine.removeMethod(this._methods, 'showAnimation');
            VictorEngine.removeMethod(this._methods, 'waitForBattleAnimation');
            this.push('prepareAction', subject, action, targets);
            this._setupStartActionFrame = Graphics.frameCount;
        }
    };

    Window_BattleLog.prototype.initializeMethodsStack = function() {
        this._stackWaitCount = [];
        this._stackWaitMode = [];
        this._methodsStack = [];
        this._stackIndex = 0;
    };

    Window_BattleLog.prototype.prepareAction = function(subject, action, targets) {
        this.uniqueTargets(targets).forEach(function(unique) {
            this._stackIndex = VictorEngine.battlerIndex(unique.target);
            this.prepareUniqueAction(subject, action, unique.target, unique.repeat)
        }, this)
        this._stackIndex = 0;
    };

    Window_BattleLog.prototype.prepareUniqueAction = function(subject, action, target, repeat) {
        this.prepareUniqueActionStep1(subject, action, target, repeat);
        this.prepareUniqueActionStep2(subject, action, target, repeat);
        this.prepareUniqueActionStep3(subject, action, target, repeat);
    };

    Window_BattleLog.prototype.prepareUniqueActionStep1 = function(subject, action, target, repeat) {
        var item = action.item();
        this.push('showAnimation', subject, [target], item.animationId);
    };

    Window_BattleLog.prototype.prepareUniqueActionStep2 = function(subject, action, target, repeat) {
        var item = action.item();
        var animId = this.uniqueActionAnimationId(subject, item)
        this.push('waitForBattleAnimation', animId);
    };

    Window_BattleLog.prototype.prepareUniqueActionStep3 = function(subject, action, target, repeat) {
        for (var i = 0; i < repeat; i++) {
            if (i > 0) {
                this.push('waitForTime', 1);
            }
            this.push('updateStackAction', this._stackIndex, subject, target);
        }
    };

    Window_BattleLog.prototype.uniqueActionAnimationId = function(subject, item) {
        if (item.animationId < 0) {
            return subject.attackAnimationId1();
        } else {
            return item.animationId;
        }
    }

    Window_BattleLog.prototype.uniqueTargets = function(targets) {
        var repeats = [];
        targets.forEach(function(target, i) {
            var index = targets.indexOf(target);
            if (index === i) {
                repeats[index] = {
                    target: target,
                    repeat: 1
                };
            } else {
                repeats[index].repeat++;
            }
        })
        return repeats.filter(function(repeat) {
            return !!repeat
        });
    }

    Window_BattleLog.prototype.updateMethodsStack = function() {
        var methods = this._methodsStack;
        for (var i = 0; i < methods.length; i++) {
            if (methods[i] && methods[i].length > 0) {
                while (methods[i].length > 0 && !this.updateStackWait(i)) {
                    this.callNextStackMethod(i);
                }
            }
        }
        if (this.isStackEmpty()) {
            this._methodsStack = [];
        }
    };

    Window_BattleLog.prototype.isStackEmpty = function() {
        return this._methodsStack.every(function(methods) {
            return !methods || methods.length === 0;
        })
    };

    Window_BattleLog.prototype.stackBattler = function(index) {
        if (index > 0) {
            var max = $gameParty.maxBattleMembers();
            if (index > max) {
                return $gameTroop.members()[index - max - 1];
            } else {
                return $gameParty.members()[index - 1];
            }
        } else {
            return null;
        }
    };

    Window_BattleLog.prototype.callNextStackMethod = function(index) {
        var method = this._methodsStack[index].shift();
        if (method.name && this[method.name]) {
            this[method.name].apply(this, method.params);
        } else {
            throw new Error('Method not found: ' + method.name);
        }
    };

    Window_BattleLog.prototype.saveMethodsStack = function(index) {
        this._saveStackIndex = this._stackIndex;
        this._saveMethodsStack = this._methodsStack[index].clone();
        this._stackIndex = index;
        this._methodsStack[index] = [];
    };

    Window_BattleLog.prototype.restoreMethodsStack = function(index) {
        this._methodsStack[index] = this._methodsStack[index].concat(this._saveMethodsStack);
        this._stackIndex = this._saveStackIndex;
    };

    Window_BattleLog.prototype.methodStackActive = function() {
        return this._methodsStack.length > 0;
    };

    Window_BattleLog.prototype.updateStackAction = function(index, subject, target) {
        BattleManager.updateStackAction(index, subject, target);
    };

    Window_BattleLog.prototype.pushMethodsStack = function(methodName) {
        var index = this._stackIndex || 0;
        var methodArgs = Array.prototype.slice.call(arguments, 1);
        if (methodName === 'wait') {
            methodName = 'stackWait';
            methodArgs.unshift(index);
        } else if (methodName === 'waitForTime') {
            methodName = 'stackWaitForTime';
            methodArgs.unshift(index);
        } else if (methodName === 'waitForBattleAnimation') {
            methodName = 'stackWaitFoAnimation';
            methodArgs.unshift(index);
        } else if (methodName === 'updateWaitMode') {
            methodName = 'updateStackWaitMode';
            methodArgs.unshift(index);
        } else if (methodName === 'setWaitMode') {
            methodName = 'setStackWaitMode';
            methodArgs.unshift(index);
        }
        this._methodsStack[index] = this._methodsStack[index] || [];
        this._methodsStack[index].push({
            name: methodName,
            params: methodArgs
        });
    };

    Window_BattleLog.prototype.updateStackWait = function(index) {
        return this.updateStackWaitCount(index) || this.updateStackWaitMode(index);
    };

    Window_BattleLog.prototype.updateStackWaitCount = function(index) {
        if (this._stackWaitCount[index] && this._stackWaitCount[index] > 0) {
            this._stackWaitCount[index]--;
            return true;
        }
        return false;
    };

    Window_BattleLog.prototype.stackWait = function(index) {
        this.stackWaitForTime(index, this.messageSpeed());
    };

    Window_BattleLog.prototype.stackWaitFoAnimation = function(index, animationId, speed) {
        var speed = Math.max(speed, 1) || 1;
        this.stackWaitForTime(index, VictorEngine.waitAnimation(animationId) / speed);
    };

    Window_BattleLog.prototype.stackWaitForTime = function(index, time) {
        this._stackWaitCount[index] = time;
    };

    Window_BattleLog.prototype.updateStackWaitMode = function(index) {
        var battler = this.stackBattler(index);
        var waitMode = this._stackWaitMode[index] || [];
        if (waitMode.contains('effect')) {
            var waiting = battler ? battler.isSpriteEffecting() : this._spriteset.isEffecting();
            if (waiting) {
                return true;
            } else {
                this.removeWaitMode(index, 'effect');
            }
        }
        if (waitMode.contains('movement')) {
            var waiting = battler ? battler.isSpriteMoving() : this._spriteset.isAnyoneMoving();
            if (waiting) {
                return true;
            } else {
                this.removeWaitMode(index, 'movement');
            }
        }
        this._stackWaitMode[index] = [];
        return false;
    };

    Window_BattleLog.prototype.setStackWaitMode = function(index, waitMode) {
        this._stackWaitMode[index] = this._stackWaitMode[index] || [];
        if (!this._stackWaitMode[index].contains(waitMode)) {
            this._stackWaitMode[index].push(waitMode);
        }
    };

    Window_BattleLog.prototype.removeWaitMode = function(index, waitMode) {
        this._stackWaitMode[index] = this._stackWaitMode[index] || [];
        var waitIndex = this._stackWaitMode[index].indexOf(waitMode);
        this._stackWaitMode[index].splice(waitIndex, 1);
    };

    Window_BattleLog.prototype.startEscape = function(subject, action) {
        subject._isEscapeCommand = true;
    };

    Window_BattleLog.prototype.performEscape = function(subject) {
        $gameParty._skipClear = true;
        BattleManager.processEscape();
        $gameParty._skipClear = false;
    };

    Window_BattleLog.prototype.setupCurrentAction = function(subject, action, targets) {};

})();