code:
/*=============================================================================
 MessageAutoReplace.js
----------------------------------------------------------------------------
 (C)2022 Triacontane
 This software is released under the MIT License.
 http://opensource.org/licenses/mit-license.php
----------------------------------------------------------------------------
 Version
 1.0.0 2022/04/05 初版
 1.1.0 2025/01/26 アイテムの説明文にも置換を適用
----------------------------------------------------------------------------*/

(() => {
    'use strict';

    // プラグインパラメータの設定
    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('MessageAutoReplace');
    if (!param.replaceList) {
        param.replaceList = [];
    }

    // メッセージウィンドウでの置換処理
    var _Game_Message_allText = Game_Message.prototype.allText;
    Game_Message.prototype.allText = function() {
        return this.applyTextReplace(_Game_Message_allText.apply(this, arguments));
    };

    Game_Message.prototype.applyTextReplace = function(text) {
        param.replaceList.forEach(function(item) {
            if (item.switchId && !$gameSwitches.value(item.switchId)) {
                return;
            }
            const regExp = new RegExp(item.targetText, 'g');
            text = text.replace(regExp, function() {
                const params = Array.from(arguments).slice(1);
                return item.text.format.apply(item.text, params);
            });
        });
        return text;
    };

    // アイテム説明文にも置換を適用
    var _Game_Item_description = Game_Item.prototype.description;
    Game_Item.prototype.description = function() {
        var description = _Game_Item_description.call(this);
        return this.applyTextReplace(description);
    };

    // アイテム説明文の置換処理を追加
    Game_Item.prototype.applyTextReplace = function(text) {
        param.replaceList.forEach(function(item) {
            if (item.switchId && !$gameSwitches.value(item.switchId)) {
                return;
            }
            const regExp = new RegExp(item.targetText, 'g');
            text = text.replace(regExp, function() {
                const params = Array.from(arguments).slice(1);
                return item.text.format.apply(item.text, params);
            });
        });
        return text;
    };

})();


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

/*:
 * @plugindesc MessageCommonPlugin
 * @author triacontane
 *
 * @help メッセージの表示中にコモンイベントを呼び出します。
 * コモンイベントは並列扱いで実行されます。
 *
 * 以下の制御文字を含めて「文章の表示」を実行してください。
 * \CE[1] # コモンイベント[1]を実行します。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc メッセージコモンプラグイン
 * @author トリアコンタン
 *
 * @help メッセージの表示中にコモンイベントを呼び出します。
 * コモンイベントは並列扱いで実行されます。
 *
 * 以下の制御文字を含めて「文章の表示」を実行してください。
 * \CE[1] # コモンイベント[1]を実行します。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';

    //=============================================================================
    // Game_System
    //  メッセージコモンイベントを更新します。
    //=============================================================================
    Game_System.prototype.addMessageCommonEvents = function(id) {
        if (!this._messageCommonEvents) {
            this._messageCommonEvents = [];
        }
        var interpreter = new Game_Interpreter();
        interpreter.setup($dataCommonEvents[id].list);
        this._messageCommonEvents.push(interpreter);
    };

    Game_System.prototype.updateMessageCommonEvents = function() {
        if (!this._messageCommonEvents || this._messageCommonEvents.length === 0) return;
        this._messageCommonEvents.forEach(function(interpreter) {
            interpreter.update();
        });
        this._messageCommonEvents = this._messageCommonEvents.filter(function(interpreter) {
            return interpreter.isRunning();
        });
    };

    //=============================================================================
    // Window_Message
    //  メッセージコモンイベントを呼び出します。
    //=============================================================================
    var _Window_Message_processEscapeCharacter = Window_Message.prototype.processEscapeCharacter;
    Window_Message.prototype.processEscapeCharacter = function(code, textState) {
        if (code === 'CE') {
            this.callMessageCommon(this.obtainEscapeParam(textState));
            return;
        }
        _Window_Message_processEscapeCharacter.apply(this, arguments);
    };

    Window_Message.prototype.callMessageCommon = function(commonEventId) {
        $gameSystem.addMessageCommonEvents(commonEventId);
    };

    var _Window_Message_update = Window_Message.prototype.update;
    Window_Message.prototype.update = function() {
        $gameSystem.updateMessageCommonEvents();
        _Window_Message_update.apply(this, arguments);
    };
})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// MessageSelectPicture.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.2.4 2020/07/12 1.2.3の対応で選択肢をイベントコマンドの上限を超えて指定すると正常に機能しない問題を修正
// 1.2.3 2020/07/12 MPP_ChoiceEX.jsと併用したとき、非表示の選択肢があると選択肢と表示ピクチャとがズレる競合を修正
// 1.2.2 2019/09/29 ピクチャ選択と無関係な選択肢を選択後に、ピクチャ選択肢のコマンドを実行すると
//                  以前に選択した選択肢の番号に対応するピクチャが一瞬表示される問題を修正
// 1.2.1 2019/04/07 1.2.0で選択肢のインデックスが1つずれていた問題を修正
// 1.2.0 2019/04/07 複数のピクチャを選択肢に関連づけられる機能を追加
// 1.1.1 2017/05/27 競合の可能性のある記述（Objectクラスへのプロパティ追加）をリファクタリング
// 1.1.0 2016/02/20 選択肢拡張プラグイン（MPP_ChoiceEX.js）に対応
// 1.0.2 2016/01/24 マウス操作でピクチャが更新されない問題を修正
// 1.0.1 2016/01/24 起動しないバグ修正(笑)
// 1.0.0 2016/01/23 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc 選択肢のピクチャ表示プラグイン
 * @author トリアコンタン
 *
 * @help イベントコマンド「選択肢の表示」で選択肢にカーソルを合わせた際に
 * 選択肢に対応するピクチャを表示するようにします。
 *
 * あらかじめ不透明度0でピクチャを表示したうえで
 * プラグインコマンドを実行して、関連づけを指定してください。
 *
 * 選択肢を決定後、プラグイン側でピクチャを非表示にすることはないので
 * 自由にイベントコマンドで操作してください。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * 選択肢ピクチャ設定 or
 * MSP_SET [ピクチャ番号] [選択肢#(1-6)]
 * 　選択肢の番号と表示するピクチャ番号とを関連づけます。
 * 　関連づけは、選択肢を決定した時点で解除されます。
 * 　複数のピクチャを選択肢に関連づけたい場合は、その分コマンドを実行してください。
 *
 * 例：選択肢ピクチャ設定 1 1
 *
 * MPP_ChoiceEX.jsと併用する場合、このプラグインを下に配置してください。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';

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

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

    var getCommandName = function(command) {
        return (command || '').toUpperCase();
    };

    //=============================================================================
    // Game_Interpreter
    //  プラグインコマンドを追加定義します。
    //=============================================================================
    var _Game_Interpreter_pluginCommand      = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.apply(this, arguments);
        this.pluginCommandMessageSelectPicture(command, args);
    };

    Game_Interpreter.prototype.pluginCommandMessageSelectPicture = function(command, args) {
        switch (getCommandName(command)) {
            case '選択肢ピクチャ設定' :
            case 'MSP_SET':
                var index = getArgNumber(args[1], 1) - 1;
                var pictureId = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                $gameMessage.setSelectPictureId(index, pictureId);
                break;
        }
    };

    var _Game_Message_initialize      = Game_Message.prototype.initialize;
    Game_Message.prototype.initialize = function() {
        _Game_Message_initialize.apply(this, arguments);
        this.clearSelectPictures();
    };

    Game_Message.prototype.setSelectPictureId = function(index, pictureId) {
        this._selectPictures.push({index: index, pictureId: pictureId});
    };

    Game_Message.prototype.clearSelectPictures = function() {
        this._selectPictures = [];
    };

    Game_Message.prototype.getSelectPictures = function() {
        return this._selectPictures;
    };

    var _Game_Message_onChoice      = Game_Message.prototype.onChoice;
    Game_Message.prototype.onChoice = function(n) {
        _Game_Message_onChoice.apply(this, arguments);
        this.clearSelectPictures();
    };

    Game_Picture.prototype.setOpacity = function(value) {
        this._opacity = value;
    };

    var _Window_ChoiceList_update      = Window_ChoiceList.prototype.update;
    Window_ChoiceList.prototype.update = function() {
        _Window_ChoiceList_update.apply(this, arguments);
        if (this.isOpen()) {
            this.updateSelectPicture();
        }
    };

    Window_ChoiceList.prototype.updateSelectPicture = function() {
        $gameMessage.getSelectPictures().forEach(function(data) {
            var picture = $gameScreen.picture(data.pictureId);
            if (!picture) {
                return;
            }
            picture.setOpacity(data.index === this.findMessageIndex() ? 255 : 0);
        }, this);
    };

    // for MPP_ChoiceEX.js start
    Window_ChoiceList.prototype.findMessageIndex = function() {
        var index = this.index();
        if ($gameMessage.hiddenIndexList) {
            $gameMessage.hiddenIndexList.forEach(function(hidden, i) {
                if (hidden && index >= i) {
                    index++;
                }
            });
        }
        return index;
    };

    var _Game_Interpreter_setupChoices = Game_Interpreter.prototype.setupChoices;
    Game_Interpreter.prototype.setupChoices = function(params) {
        if (this.addChoices) {
            $gameMessage.hiddenIndexList = [];
        }
        _Game_Interpreter_setupChoices.apply(this, arguments);
    };

    var _Game_Interpreter_addChoices = Game_Interpreter.prototype.addChoices;
    Game_Interpreter.prototype.addChoices = function(params, i, data, d) {
        var regIf = /\s*if\((.+?)\)/;
        var hiddenIndexList = $gameMessage.hiddenIndexList;
        for (var n = 0; n < params[0].length; n++) {
            var str = params[0][n];
            if (regIf.test(str)) {
                str = str.replace(regIf, '');
                hiddenIndexList.push(RegExp.$1 && !this.evalChoice(RegExp.$1));
            } else {
                hiddenIndexList.push(false);
            }
        }
        return _Game_Interpreter_addChoices.apply(this, arguments);
    }
    // for MPP_ChoiceEX.js end
})();


code:
//=============================================================================
// MessageWindowHidden.js
// ----------------------------------------------------------------------------
// (C)2015-2018 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.0.0 2018/03/31 消去するトリガーを複数指定できる機能を追加。パラメータの指定方法を見直し。
// 1.4.0 2018/03/10 指定したスイッチがONの間はウィンドウ消去を無効化できる機能を追加
// 1.3.2 2017/08/02 ponidog_BackLog_utf8.jsとの競合を解消
// 1.3.1 2017/07/03 古いYEP_MessageCore.jsのネーム表示ウィンドウが再表示できない不具合の修正(by DarkPlasmaさま)
// 1.3.0 2017/03/16 連動して非表示にできるピクチャを複数指定できる機能を追加
// 1.2.1 2017/02/07 端末依存の記述を削除
// 1.2.0 2016/01/02 メッセージウィンドウと連動して指定したピクチャの表示/非表示が自動で切り替わる機能を追加
// 1.1.0 2016/08/25 選択肢の表示中はウィンドウを非表示にできないよう仕様変更
// 1.0.4 2016/07/22 YEP_MessageCore.jsのネーム表示ウィンドウと連携する機能を追加
// 1.0.3 2016/01/24 メッセージウィンドウが表示されていないときも非表示にできてしまう現象の修正
// 1.0.2 2016/01/02 競合対策
// 1.0.1 2015/12/31 コメント追加＋英語対応（仕様に変化なし）
// 1.0.0 2015/12/30 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc Erase message window
 * @author triacontane
 *
 * @param triggerButton
 * @desc Trigger buttons
 * (light_click or shift or control)
 * @default ["light_click"]
 * @type combo[]
 * @option light_click
 * @option shift
 * @option control
 * @option tab
 * @option pageup
 * @option pagedown
 * @option debug
 *
 * @param linkPictureNumbers
 * @desc Picture number of window show/hide
 * @default
 * @type number[]
 *
 * @param disableSwitchId
 * @desc 指定した番号のスイッチがONのとき、プラグインの機能が無効になります。
 * @default 0
 * @type switch
 *
 * @help Erase message window (and restore) when triggered
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc メッセージウィンドウ一時消去プラグイン
 * @author トリアコンタン
 *
 * @param triggerButton
 * @text ボタン名称
 * @desc ウィンドウを消去するボタンです。(複数登録可能) プラグイン等で入力可能なボタンを追加した場合は直接入力
 * @default ["右クリック"]
 * @type combo[]
 * @option 右クリック
 * @option shift
 * @option control
 * @option tab
 * @option pageup
 * @option pagedown
 * @option debug
 *
 * @param linkPictureNumbers
 * @text 連動ピクチャ番号
 * @desc ウィンドウ消去時に連動して不透明度を[0]にするピクチャの番号です。
 * @default
 * @type number[]
 *
 * @param disableSwitchId
 * @text 無効スイッチ番号
 * @desc 指定した番号のスイッチがONのとき、プラグインの機能が無効になります。
 * @default 0
 * @type switch
 *
 * @param hideMessage
 * @text メッセージ非表示中のメッセージ
 * @desc メッセージを非表示中にタイトルバーに表示されるメッセージです
 * @default ［！］メッセージウィンドウ消去中（キー操作で復帰）
 * @type string
 *
 * @help メッセージウィンドウを表示中に指定したボタンを押下することで
 * メッセージウィンドウを消去します。もう一度押すと戻ります。
 *
 * ウィンドウ消去時に連動して不透明度を[0]にするピクチャを指定することができます。
 * 背景に特定のピクチャを使用している場合などに指定してください。
 * 再表示すると不透明度は[255]になります。
 *
 * ver2.0.0よりパラメータの指定方法が一部変更になりました。
 * 以前のバージョンを使っていた方は再設定をお願いします。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
(function() {
    'use strict';

    /**
     * Create plugin parameter. param[paramName] ex. param.commandPrefix
     * @param pluginName plugin name(EncounterSwitchConditions)
     * @returns {Object} Created parameter
     */

    var gameTitle = document.title;
    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('MessageWindowHiddenRecoveryAnyKey');

    //=============================================================================
    // Game_Picture
    //  メッセージウィンドウの表示可否と連動します。
    //=============================================================================
    Game_Picture.prototype.linkWithMessageWindow = function(opacity) {
        this._opacity       = opacity;
        this._targetOpacity = opacity;
    };

    //=============================================================================
    // Window_Message
    //  指定されたボタン押下時にウィンドウとサブウィンドウを非表示にします。
    //=============================================================================
    var _Window_Message_updateWait      = Window_Message.prototype.updateWait;
    Window_Message.prototype.updateWait = function() {
        if (!this.isClosed() && this.isTriggeredHidden() && !$gameMessage.isChoice()) {
            if (!this.isHidden()) {
                this.hideAllWindow();
            } else {
                this.showAllWindow();
            }
        }
        else if (this.isHidden() && !this.isClosed() && this.isTriggeredVisible() && !$gameMessage.isChoice()){
            //$gameScreen.erasePicture(95);
            this.showAllWindow();
        }
        var wait = _Window_Message_updateWait.apply(this, arguments);
        if (this.isHidden() && this.visible) {
            this.hideAllWindow();
        }
        return wait;
    };

    Window_Message.prototype.hideAllWindow = function() {
        this.hide();
        this.subWindows().forEach(function(subWindow) {
            this.hideSubWindow(subWindow);
        }.bind(this));
        if (this.hasNameWindow() && !this.nameWindowIsSubWindow()) this.hideSubWindow(this._nameWindow);
        this.linkPictures(0);
        this._hideByMessageWindowHidden = true;
        gameTitle = document.title;
        document.title = param.hideMessage

        // バックログを開くフラグをリセット
    	this._waitForBacklogRelease = false;
    };

    Window_Message.prototype.showAllWindow = function() {
        this._waitCount += 10;
        this.show();
        this.subWindows().forEach(function(subWindow) {
            this.showSubWindow(subWindow);
        }.bind(this));
        if (this.hasNameWindow() && !this.nameWindowIsSubWindow()) this.showSubWindow(this._nameWindow);
        this.linkPictures(255);
        this._hideByMessageWindowHidden = false;
        document.title = gameTitle;
    };

    Window_Message.prototype.isHidden = function() {
        return this._hideByMessageWindowHidden;
    };

    Window_Message.prototype.linkPictures = function(opacity) {
        if (!param.linkPictureNumbers) {
            return;
        }
        param.linkPictureNumbers.forEach(function(pictureId) {
            this.linkPicture(opacity, pictureId);
        }, this);
    };

    Window_Message.prototype.linkPicture = function(opacity, pictureId) {
        var picture = $gameScreen.picture(pictureId);
        if (picture) {
            picture.linkWithMessageWindow(opacity);
        }
    };

    Window_Message.prototype.hideSubWindow = function(subWindow) {
        subWindow.prevVisible = subWindow.visible;
        subWindow.hide();
    };

    Window_Message.prototype.showSubWindow = function(subWindow) {
        if (subWindow.prevVisible) subWindow.show();
        subWindow.prevVisible = undefined;
    };

    Window_Message.prototype.hasNameWindow = function() {
        return this._nameWindow && typeof Window_NameBox !== 'undefined';
    };

    // 古いYEP_MessageCore.jsでは、ネーム表示ウィンドウはsubWindowsに含まれる
    Window_Message.prototype.nameWindowIsSubWindow = function() {
        return this.subWindows().filter(function(subWindow) {
            return subWindow === this._nameWindow;
        }, this).length > 0;
    };

    Window_Message.prototype.isTriggeredHidden = function() {
        if (param.disableSwitchId > 0 && $gameSwitches.value(param.disableSwitchId)) {
            return false;
        }
	    // バックログウィンドウが開いている場合は無効化
	    if ($gameTemp.isMessageBacklogOpened()) {
	        return false;
	    }

        return param.triggerButton.some(function(button) {
            switch (button) {
                case '':
                case '右クリック':
                case 'light_click':
                    return TouchInput.isCancelled();
                case 'ok':
                    return false;
                default:
                    return Input.isTriggered(button);
            }
        });
    };

    Window_Message.prototype.isTriggeredVisible = function(){
        return Input.isAnyTriggered();
    }

    var _Window_Message_updateInput      = Window_Message.prototype.updateInput;
    Window_Message.prototype.updateInput = function() {
        if (this.isHidden()) return true;
        return _Window_Message_updateInput.apply(this, arguments);
    };

    //=============================================================================
    // Window_ChoiceList、Window_NumberInput、Window_EventItem
    //  非表示の間は更新を停止します。
    //=============================================================================
    var _Window_ChoiceList_update      = Window_ChoiceList.prototype.update;
    Window_ChoiceList.prototype.update = function() {
        if (!this.visible) return;
        _Window_ChoiceList_update.apply(this, arguments);
    };

    var _Window_NumberInput_update      = Window_NumberInput.prototype.update;
    Window_NumberInput.prototype.update = function() {
        if (!this.visible) return;
        _Window_NumberInput_update.apply(this, arguments);
    };

    var _Window_EventItem_update      = Window_EventItem.prototype.update;
    Window_EventItem.prototype.update = function() {
        if (!this.visible) return;
        _Window_EventItem_update.apply(this, arguments);
    };
})();

(function(){
    'use strict';

    Input.isAnyTriggered = function(){
        var anyTrigger = false;
        Object.keys(Input.keyMapper).forEach(function(key){
            if(!anyTrigger){
                if(!!Input.isTriggered(Input.keyMapper[key])) anyTrigger = true;
            }
        });
        return anyTrigger;
    }
    for(var i=1;i<244;i++){
        if(Input.keyMapper[i] == null){
            Input.keyMapper[i] = 'anyKey';
        }
    }
})();


code:
//=============================================================================
// Mihil_AudioCondition.js
//
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================
/*:
 * @plugindesc 音声再生に条件を設定できます
 *
 * @author Mihiraghi
 *
 * @help つかいかた:
 * 音声再生条件(文字列)にて、
 * 制御する音声の種類(BGM, BGS, ME, SE)、
 * 前方一致で検索する文字列、
 * ON/OFFを制御するスイッチ番号、
 * を指定します。
 * 条件に一致した音声ファイルは、
 * スイッチがONの時のみ演奏されるようになります
 *
 *
 * Ver0.1.0 試作
 *
 * @param BGVVolumeName
 * @text BGV音量の表示名
 * @desc オプション画面に表示する「BGV音量」の項目名
 * @type string
 * @default BGV音量
 *
 * @param PrefixConditions
 * @text 音声再生条件(文字列)
 * @desc 文字列から前方一致で引っかかった
 * ファイル名の音声再生をスイッチで制御します
 * @type struct<PrefixCondition>[]
 * @default []

 */

/*~struct~Condition:
 *
 *
 * @param FileName
 * @text ファイル名
 * @desc
 * @type file
 * @dir audio
 *
 *
 * @param Switch
 * @text スイッチ
 * @desc 複数の条件を入れた場合はANDで判定します
 * @type switch
 * @parent database
 */
/*~struct~PrefixCondition:
 *
 * @param AudioType
 * @text 音声種類
 * @desc 音声の種類です
 * BGM, BGS, ME, SEから選択します
 * @type select
 * @option BGM
 * @value BGM
 * @option BGS
 * @value BGS
 * @option ME
 * @value ME
 * @option SE
 * @value SE
 *
 * @param FileString
 * @text ファイル検索文字列
 * @desc 条件を前方一致したファイル名全てに含むことができます
 * @type string
 *
 *
 * @param Switch
 * @text スイッチ
 * @desc 条件に一致したファイルが、スイッチがOFFの場合演奏しないようにします
 * @type switch
 * @parent database
 */

//-----------------------------------------------------------------------------

(() => {
    'use strict';
    const pluginName = document.currentScript.src.replace(/^.*\/(.*).js$/, function () {
        return arguments[1];
    });

    const pluginParameters = PluginManager.parameters(pluginName)
    var param = JSON.parse(JSON.stringify(pluginParameters, function(key, value) {
        try {
            return JSON.parse(value);
        } catch (e) {
            try {
                return eval(value);
            } catch (e) {
                return value;
            }
        }
    }));

    class AudioTypesDistributor{

        constructor(){
            this._bgm = [];
            this._bgs = [];
            this._me = [];
            this._se = [];
            //this.distributeCondition()
            this.distributePrefixCondition()
        }
        distributePrefixCondition(){
            for(const condition of param.PrefixConditions){
                const list = this.audioListTable()[condition.AudioType]
                list.push(condition)
            }
        }
        audioListTable(){
            return {
                BGM: this._bgm,
                BGS: this._bgs,
                ME: this._me,
                SE: this._se
            }
        }
        get bgm(){ return this._bgm; }
        get bgs(){ return this._bgs; }
        get me(){ return this._me; }
        get se(){ return this._se; }
    }

    const conditions = new AudioTypesDistributor()

    function checkAudioCondition(typeName, audio){
        if(!audio || !audio.name){ return true; }
        for(const condition of conditions[typeName]){
            if(!audio.name.startsWith(condition.FileString)){ continue; }
            if(!condition.Switch){ console.error(`$gameSwitches key is falsy`, {key:condition.Switch}); continue; }
            return $gameSwitches.value(condition.Switch)
        }
        return true;
    }

    const _AudioManager_playBgm = AudioManager.playBgm
    AudioManager.playBgm = function(bgm, pos) {
    	//歓楽街BGM
    	if(arguments[0].name=="[MAP]NightTown"){
    		if($gameVariables.value(277)==1){
    			arguments[0].name = "[MAP]NightTown2" 	//2章敗北ルート時BGM
    		}
    	//神社BGM
    	}else if(arguments[0].name=="[MAP]Shrine_01"){
    		if($gameVariables.value(2)>=3){
    			arguments[0].name = "" 	//夜BGM
    		}
    		if($gameVariables.value(2)<=2 && $gameVariables.value(25)<=9 && $gameVariables.value(287)==0){
    			arguments[0].name = "[Scene]Serious05" 	//初期イベントBGM
    		}
    	//市街地BGM
    	}else if(arguments[0].name=="[MAP]Yumemi_town01"){
    		if($gameVariables.value(2)==2){
    			arguments[0].name = "[MAP]School_main2" 	//夕方BGM
    		}
    		if($gameVariables.value(2)>=3){
    			arguments[0].name = "" 	//夜BGM
    		}
    	//学園BGM
    	}else if(arguments[0].name=="[MAP]School_main"){
    		if($gameSwitches.value(752) && $gameVariables.value(589)<100){
    			arguments[0].name = "[Theme]Kitou" 	//生徒指導イベントBGM
    		}
    		if($gameVariables.value(167)==1){
    			arguments[0].name = "[MAP]School_Bad1" 	//敗北ルート時BGM
    		}
    		if($gameVariables.value(167)==2){
    			arguments[0].name = "[MAP]School_Hypno" //催眠時BGM
    		}
    		if($gameVariables.value(2)==2){
    			arguments[0].name = "[MAP]School_main2" 	//夕方BGM
    		}
    		if($gameVariables.value(2)>=3){
    			arguments[0].name = "" 	//夜BGM
    		}
    	//駅前BGM
        }else if(arguments[0].name=="[MAP]Station_Rotary"){
    		if($gameVariables.value(2)==2){
    			arguments[0].name = "[MAP]School_main2" 	//夕方BGM
    		}
    		if($gameVariables.value(2)>=3){
    			arguments[0].name = "" 	//夜BGM
    		}
    		if($gameMap.mapId()==317 && $gameSwitches.value(649)){
    			arguments[0].name = "[Scene]Sukebe01" 	//ピアノBGM
    		}
    	//アクアキングダムBGM
        }else if(arguments[0].name=="[MAP]AquaKingdom_Front"){
    		if($gameVariables.value(23)>=81 && $gameVariables.value(23)<100){
    			arguments[0].name = "[MAP]AquaKingdom_Front2" 	//敗北期間BGM
    		}
        }
        if(!checkAudioCondition("bgm", bgm)){ return; }
        _AudioManager_playBgm.apply(this, arguments)
    }
    const _AudioManager_playBgs = AudioManager.playBgs
    AudioManager.playBgs = function(bgs, pos) {
    	//メモ　BGSは対象マップでロードするとバグる
    	/*if(arguments[0].name=="Wood"){
    		if($gameVariables.value(2)>=2){
    			arguments[0].name = "" 	//夕方からは何も流さない
    			if($gameVariables.value(2)>=3){
    				AudioManager.playSe({"name":"Animal_Owl01","volume":90,"pitch":100,"pan":0})
    			}else{
    				AudioManager.playSe({"name":"Animal_Crow01","volume":90,"pitch":100,"pan":0})
    			}
    		}
    	}*/
        if(!checkAudioCondition("bgs", bgs)){ return; }
        if (bgs && !!bgs.name && bgs.name.includes("[BGV]")) {
            bgs.volume = ConfigManager.bgvVolume; // オプション設定のBGV音量を適用
        }
        _AudioManager_playBgs.apply(this, arguments)
    }
    const _AudioManager_playMe = AudioManager.playMe
    AudioManager.playMe = function(me) {
        if(!checkAudioCondition("me", me)){ return; }
        _AudioManager_playMe.apply(this, arguments)
    }
    const _AudioManager_playSe = AudioManager.playSe
    AudioManager.playSe = function(se) {
        if(!checkAudioCondition("se", se)){ return; }
        if (se && !!se.name && se.name.includes("[BGV]")) {
            se.volume = ConfigManager.bgvVolume; // オプション設定のBGV音量を適用
        }
        _AudioManager_playSe.apply(this, arguments)
    }

    // オプション画面にBGV音量を追加
	ConfigManager.bgvVolume = 90; // 初期値を設定
    const _Window_Options_addVolumeOptions = Window_Options.prototype.addVolumeOptions;
    Window_Options.prototype.addVolumeOptions = function() {
        _Window_Options_addVolumeOptions.apply(this, arguments);
        this.addCommand(PluginManager.parameters('Mihil_AudioCondition')['BGVVolumeName'], "bgvVolume");
    };

})();


code:
//=============================================================================
// Mihil_CurrentVolume.js
//
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================
// Copyright (c) 2018-2019 uta_asakayu
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
/*:
 * @plugindesc 今鳴っているBGMとBGSの音量を変更できます
 *
 * @author uta_asakayu
 *
 * @help 既に鳴らしているBGMとBGSの音量を変更できます。
 *
 * BGMの場合はエディタのスクリプトコマンドを開いて
 * AudioManager.currentBgmVolume = 変更したい音量
 * BGSの場合は
 * AudioManager.currentBgsVolume = 変更したい音量
 *
 * に設定すれば即座に音量が切り替わります。
 * (+=や-=なども一応使えます)
 * また、コンソールにて何も代入せずに
 * AudioManager.currentBgmVolume
 * AudioManager.currentBgsVolume
 * と書くと現在の音量を取得できます。
 *
 * 応用すれば
 * AudioManager.fadeInBgm(秒数)
 * と組み合わせたりもできるはずです。
 *
 *
 *
 * ※コードレビュー歓迎しています。
 * Please feel free to throw me Masakari!
 *
 * Ver1.1.1 this._currentBgm表記をまとめてすっきりさせた
 * Ver1.1.0 インデントを揃えた。
 *          音量を変更した後再びAudioManager.currentxxxVolumeすると
 *          音量が正しく表記されなかった
 * Ver1.0.0 配布
 */
//-----------------------------------------------------------------------------

AudioManager.changeCurrentBgmVolume = function(value){
    this._currentBgm.volume = value
}
AudioManager.changeCurrentBgsVolume = function(value){
    this._currentBgs.volume = value
}

Object.defineProperty(AudioManager, 'currentBgmVolume', {
    get: function() {
        return this._currentBgm.volume;
    },
    set: function(value) {
        this.changeCurrentBgmVolume(value)
        this.updateBgmParameters(this._currentBgm);
    },
    configurable: true
});
Object.defineProperty(AudioManager, 'currentBgsVolume', {
    get: function() {
        return this._currentBgs.volume;
    },
    set: function(value) {
        this.changeCurrentBgsVolume(value)
        this.updateBgsParameters(this._currentBgm);
    },
    configurable: true
});


code:
//=============================================================================
// Mihil_tweaks.js
//=============================================================================
// Copyright (c) 2018-2019 uta_asakayu
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
/*:
 * @plugindesc ゲームの快適化や修正など
 * @author uta_asakayu
 * @Thanks Sigureya, Tsumio, eyn_kenzaki, Plasma
 *
 * @param ………  Fade  …………………………………………
 * @default ……………………………………………………………………………………
 *
 * @param LoadFadeMultiple
 * @desc セーブロード時のフェード(暗転)時間を
 * 何倍速にするか　(1.00でOFF)
 * @type number
 * @min 0.1
 * @max 48
 * @decimals 2
 * @default 1.00
 *
 * @param MapFadeMultiple
 * @desc マップ移動時のフェード(暗転)時間を
 * 何倍速にするか　(1.00でOFF)
 * @type number
 * @min 0.1
 * @max 24
 * @decimals 2
 * @default 1.00
 *
 * @param DisableTitleFade
 * @desc ゲーム開始時タイトル画面を表示するための
 * フェードインをなくします。動作高速化
 * @type boolean
 * @default false
 *
 * @param DisableNewgameFade
 * @desc ニューゲーム選択時の
 * フェードアウトをなくします。動作高速化
 * @type boolean
 * @default false
 *
 *
 * @param ………  Message   …………………………………………
 * @default ……………………………………………………………………………………
 *
 * @param DisableMessageInterval
 * @desc メッセージの間に挟まる
 * 操作を受け付けない時間を減らします(10でOFF)
 * @type number
 * @min 0
 * @max 100
 * @default 10
 *
 * @param WindowShiftSpeed
 * @desc ウィンドウの開閉速度を変更します
 * 倍率指定(1.00でOFF)
 * @type number
 * @min 0.1
 * @max 8
 * @decimals 2
 * @default 1.00
 *
 * @param BaloonAnimationMultiple
 * @desc フキダシアイコンの表示速度を変更します
 * 倍率指定(1.00でOFF)
 * @type number
 * @min 0.1
 * @max 64
 * @decimals 2
 * @default 1.00
 *
 * @param ………  InputTweak   …………………………………………
 * @default ……………………………………………………………………………………
 *
 * @param DisableAltkey
 * @desc Controlキーと同じ動作に割り当てられている
 * Altキーの動作を無効化します。
 * @type boolean
 * @default false
 *
 * @param KeyRepeatSpeed
 * @desc キー押しっぱなしの時の、連打速度を変更します
 * フレーム指定(6でOFF)
 * @type number
 * @min 1
 * @max 60
 * @default 6
 *
 * @param ………  Choice fix  …………………………………………
 * @default ……………………………………………………………………………………
 *
 * @param SideCursorCanPageUpDown
 * @desc 選択肢の左右キーにページ送り機能を追加します
 * @type boolean
 * @default false
 *
 * @param SideCursorCanLoop
 * @desc 選択肢の左右キーが最初と最後でループするように
 * ページ送り機能がオンの時のみ
 * @type boolean
 * @default false
 *
 * @param FixChoiceCursorUp
 * @desc 選択肢デフォルトが[なし]の時、
 * カーソル上を押すと下から2番目が選択される問題を修正
 * @type boolean
 * @default false
 *
 * @param ………  fix  …………………………………………
 * @default ……………………………………………………………………………………
 *
 * @param FixGraphicsRender
 * @desc たまに音楽だけ鳴って画面が固まる不具合を修正します
 * @type boolean
 * @default false
 *
 *
 * @help
 * ゲームを高速化して快適性を増したり、
 * MVのバグを修正したりします。
 *
 * -------高速化--------
 *
 *     LoadFadeMultiple
 * セーブファイルをロードした時の暗転時間を調節できます。
 * プラグインパラメータ(LoadFadeMultiple)の数値に合わせて、暗転が速くなります。
 * 1倍未満の数値も入れられます。(遅くなります)
 * 48以上の値は意味ないかも。
 * 1.00以外の数値にすると
 * Scene_Load.prototype.onLoadSuccess
 * を上書きします。
 *
 *     MapFadeMultiple
 * マップを移動した時の暗転時間を調節できます。
 * プラグインパラメータ(MapFadeMultiple)の数値に合わせて、暗転が速くなります。
 * 1倍未満の数値も入れられます。(遅くなります)
 * 24以上の値は意味ないかも。
 * 1.00以外の数値にすると
 * Scene_Map.prototype.fadeInForTransfer
 * Scene_Map.prototype.fadeOutForTransfer
 * を上書きします。
 *
 *     DisableTitleFade
 * タイトル画面を表示する時の、フェードインをなくします。
 * 動作は高速化しますが、演出が犠牲になるかもしれません。
 *
 *     DisableNewgameFade
 * ニューゲーム開始時の、フェードアウトをなくします。
 * 動作は高速化しますが、演出が犠牲になるかもしれません。
 *
 *
 *     DisableMessageInterval
 * ツクール標準仕様だと、メッセージウィンドウで文字が表示しきってから、
 * 10フレーム操作を受け付けないインターバルがあります。
 * このインターバルを数値変更します。
 * 値が0だとウェイトなし、
 * 10だと無効になります。
 *
 *     WindowShiftSpeed
 * ウィンドウを開いたり閉じたりする速度倍率を変更します。
 * 8倍速で一瞬で開閉させられます。
 *
 *     BaloonAnimationMultiple
 * フキダシアイコンの表示速度を変更します。
 * 標準で付与される12フレームのウェイトもカットしました。
 * 1.00以外の数値にすると
 * Sprite_Balloon.prototype.speed
 * Sprite_Balloon.prototype.waitTime
 * を上書きします
 *
 * -------入力の快適化--------
 *
 *     DisableAltkey
 * Ctrlキーでメッセージスキップ、
 * Altキーをスクリーンショットのホットキーに
 * 割り当てている場合などのために、
 * Altキーの役割をなくします。
 * trueにすると
 * Input.keyMapper[18]
 * を上書きします。
 *
 *     KeyRepeatSpeed
 * ツクールMVは今までのツクールと違い、キーをしばらく押しっぱなしにすると
 * 連打する仕様になりました。
 * その時の連打速度を変更します。値が小さい方が速いです。
 * デフォルトの値である6以外にすると、
 * Input.keyRepeatInterval
 * TouchInput.keyRepeatInterval
 * を上書きします
 *
 * -------本体の快適化・修正--------
 *
 *     SideCursorCanPageUpDown
 * 選択肢を選んでいる時に、
 * 左右キーでもページ送りが出来たらと思ったことはありませんか？
 * この機能をオンにすると、
 * 左右キーにページ送りキーと同じ機能を追加できます。
 * trueにすると
 * Window_Selectable.prototype.cursorRight
 * Window_Selectable.prototype.cursorLeft
 * を上書きします。
 *
 *     FixChoiceCursorUp
 * 選択肢のデフォルト設定が「なし」の時、
 * 選択肢を開いた後に上キーを押すと、
 * 最下部ではなく下から2番目の項目が選択される不具合を修正します。
 *
 *     FixGraphicsRender
 * ツクールMVの本体バージョンが1.6.1以下、
 * かつコミュニティ版コアスクリプトのv1.3bを導入していない場合に
 * サウンドだけ鳴り続けて画面が固まってしまう不具合を修正します。
 * (つまり、コミュニティ版コアスクリプトのv1.3b以上を導入している方は不要です)
 * trueにすると
 * Graphics.render
 * を上書きします。
 *
 *
 * 共存可能:
 * LoadComSim.js ver1.00
 * https://tm.lucky-duet.com/viewtopic.php?t=3085
 * 選択肢拡張 ver. 3.7
 * http://woodpenguin.web.fc2.com/MV_Plugin/MPP_ChoiceEX.html
 *
 * ※コードレビュー歓迎します。
 * Please feel free to throw me Masakari!
 *
 * Ver2.8.0 SideCursorCanLoopを追加
 * Ver2.7.1 MITライセンスを追加
 * Ver2.7.0 FixGraphicsRenderを追加
 * Ver2.6.2 デフォルトのパラメータを全てOFFの値に設定。
 * Ver2.6.1 DisableMessageIntervalを数値変更するように
 * Ver2.6.0 KeyRepeatSpeedを追加。Descriptionをカテゴライズ
 * Ver2.5.0 Scene_Title.prototype.startの上書きをフックに改善
 *          DisableNewgameFadeを追加
 * Ver2.4.0 BaloonAnimationMultiple(フキダシアイコン表示速度変更)を追加
 * Ver2.3.1 レイアウトを調整
 * Ver2.3.0 MapFadeMultiple機能追加
 * Ver2.2.1 SideCursorCanPageUpDownが常にオンになってしまっていた。
 * Ver2.2.0 SideCursorCanPageUpDown(左右キーでページ送り)追加。
 * Ver2.1.0 WindowShiftSpeed(ウィンドウの開閉速度変更)追加、LoadFadeMultipleの数値が1.00の時は動作しないように。
 *          FadeMultiple　→ LoadFadeMultiple　に名前変更。プラグインパラメータを設定し直してください。
 * Ver2.0.0 タイトルフェードインなし、メッセージインターバルなし、Altキー無効化、選択肢fix機能追加
 * Ver1.0.1 ~~おまけ(タイトル画面の暗転省略)を追加。
 * 　　　　　コードを見てコメントアウトを外してください。~~
 * Ver1.0.0 配布
 *
 */

(function() {
    'use strict';
// プラグインパラメータ設定
    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('Mihil_tweaks');

// ロード時のフェードアウト時間調整
    if(param.LoadFadeMultiple != 1){
        Scene_Load.prototype.fadeOutLoad = function() {
            var time = this.slowFadeSpeed() / 60;
            time /= param.LoadFadeMultiple
            AudioManager.fadeOutBgm(time);
            AudioManager.fadeOutBgs(time);
            AudioManager.fadeOutMe(time);
            this.startFadeOut(this.slowFadeSpeed() / param.LoadFadeMultiple);
        };

        Scene_Load.prototype.onLoadSuccess = function() {
            SoundManager.playLoad();
            this.fadeOutLoad();
            this.reloadMapIfUpdated();
            SceneManager.goto(Scene_Map);
            this._loadSuccess = true;
        };
    }

// マップ移動時のフェード時間変更
    if(param.MapFadeMultiple != 1){
        Scene_Map.prototype.fadeInForTransfer = function() {
            var fadeType = $gamePlayer.fadeType();
            switch (fadeType) {
            case 0: case 1:
                const fadeSpeedMulti = this.fadeSpeed() / param.MapFadeMultiple
                this.startFadeIn(fadeSpeedMulti, fadeType === 1);
                break;
            }
        };
        Scene_Map.prototype.fadeOutForTransfer = function() {
            var fadeType = $gamePlayer.fadeType();
            switch (fadeType) {
            case 0: case 1:
                const fadeSpeedMulti = this.fadeSpeed() / param.MapFadeMultiple
                this.startFadeOut(fadeSpeedMulti, fadeType === 1);
                break;
            }
        };
    }
// タイトル画面フェードインなし
    if(param.DisableTitleFade){
        const _Scene_Title_start = Scene_Title.prototype.start
        Scene_Title.prototype.start = function() {
            _Scene_Title_start.apply(this, arguments)
            this._fadeDuration = 1
        };
    }

// ニューゲームフェードアウトなし

    if(param.DisableNewgameFade){
        const _Scene_Title_commandNewGame = Scene_Title.prototype.commandNewGame
        Scene_Title.prototype.commandNewGame = function() {
            _Scene_Title_commandNewGame.apply(this, arguments)
            this.startFadeOut(1)
        };
    }

// メッセージのインターバルをなくす
    if(param.DisableMessageInterval != 10){
        const _Window_Message_startPause = Window_Message.prototype.startPause
        Window_Message.prototype.startPause = function() {
            _Window_Message_startPause.call(this)
            this.startWait(param.DisableMessageInterval);
        };
    }

// ウィンドウの開閉速度
    if(param.WindowShiftSpeed != 1){
        const _Window_Base_updateOpen = Window_Base.prototype.updateOpen
        Window_Base.prototype.updateOpen = function() {
            _Window_Base_updateOpen.call(this)
            if (this._opening) {
                this.openness -=32
                this.openness += (32*param.WindowShiftSpeed)
            }
        }
        const _Window_Base_updateClose = Window_Base.prototype.updateClose
        Window_Base.prototype.updateClose = function() {
            _Window_Base_updateClose.call(this)
            if (this._closing) {
                this.openness += 32;
                this.openness -= (32*param.WindowShiftSpeed)
            }
        };
    }

// フキダシアイコンの表示速度
    if(param.BaloonAnimationMultiple != 1){
        Sprite_Balloon.prototype.speed = function() {
            return 8/param.BaloonAnimationMultiple
        };
        Sprite_Balloon.prototype.waitTime = function() {
            return 0
        };
        /*没
        const _Sprite_Balloon_setup = Sprite_Balloon.prototype.setup
        Sprite_Balloon.prototype.setup = function(balloonId) {
            _Sprite_Balloon_setup.call(this, arguments)
            this._duration = 8 * this.speed() / param.BaloonAnimationMultiple + this.waitTime()
        };
        Sprite_Balloon.prototype.frameIndex = function() {
            var index = (this._duration - this.waitTime()) / this.speed() / param.BaloonAnimationMultiple
            return 7 - Math.max(Math.floor(index), 0);
        };
        */
    }

// Altキーを無効化
    if(param.DisableAltkey){
        Input.keyMapper[18] = '';
    }

// キーリピートの速度変更
    if(param.KeyRepeatSpeed != 6){
        /**
         * The interval of the key repeat in frames.
         *
         * @static
         * @property keyRepeatInterval
         * @type Number
         */
        Input.keyRepeatInterval = param.KeyRepeatSpeed || 6;    /**
         * The interval of the pseudo key repeat in frames.
         *
         * @static
         * @property keyRepeatInterval
         * @type Number
         */
        TouchInput.keyRepeatInterval = param.KeyRepeatSpeed || 6;
    }

// 選択肢の左右キーにページ送り機能を追加する
if(param.SideCursorCanPageUpDown){
    Window_Selectable.prototype.cursorRight = function(wrap) {
        var index = this.index();
        var maxItems = this.maxItems();
        var maxCols = this.maxCols();
        console.log(`index=${index}, maxItems=${maxItems}`)
        if(maxCols >= 2 && index===maxItems-1 && param.SideCursorCanLoop){
            this.select(0);
        } else if (maxCols >= 2 && (index < maxItems - 1 || (wrap && this.isHorizontal()))) {
            this.select((index + 1) % maxItems);
        } else if (maxCols <= 1 && this.topRow() + this.maxPageRows() < this.maxRows()) {
            this.setTopRow(this.topRow() + this.maxPageRows());
            this.select(Math.min(index + this.maxPageItems(), maxItems - 1));
        }
    };
    Window_Selectable.prototype.cursorLeft = function(wrap) {
        var index = this.index();
        var maxItems = this.maxItems();
        var maxCols = this.maxCols();
        if(maxCols >= 2 && index===0 && param.SideCursorCanLoop){
            this.select(maxItems-1);
        } else if (maxCols >= 2 && (index > 0 || (wrap && this.isHorizontal()))) {
            this.select((index - 1 + maxItems) % maxItems);
        } else if (maxCols <= 1 && this.topRow() > 0) {
            this.setTopRow(this.topRow() - this.maxPageRows());
            this.select(Math.max(index - this.maxPageItems(), 0));
        }
    };
}

// 選択肢の修正
    if(param.FixChoiceCursorUp){
        var _Window_ChoiceList_cursorUp = Window_ChoiceList.prototype.cursorUp;
        Window_ChoiceList.prototype.cursorUp = function (wrap) {
            if (this.index() === -1 && $gameMessage.choiceDefaultType() === -1) {
                this.select(0);
            }
            _Window_ChoiceList_cursorUp.call(this, wrap);
        };
    }

// FixGraphicsRender
    if(param.FixGraphicsRender){
        /**
         * Renders the stage to the game screen.
         *
         * @static
         * @method render
         * @param {Stage} stage The stage object to be rendered
         */
        Graphics.render = function(stage) {
            if (this._skipCount <= 0) {
                var startTime = Date.now();
                if (stage) {
                    this._renderer.render(stage);
                    if (this._renderer.gl && this._renderer.gl.flush) {
                        this._renderer.gl.flush();
                    }
                }
                var endTime = Date.now();
                var elapsed = endTime - startTime;
                this._skipCount = Math.min(Math.floor(elapsed / 15), this._maxSkip);
                this._rendered = true;
            } else {
                this._skipCount--;
                this._rendered = false;
            }
            this.frameCount++;
        };
    }

    var Scene_Base_prototype_updateFade = Scene_Base.prototype.updateFade;
	Scene_Base.prototype.updateFade = function() {
	    if (this._fadeDuration > 0) {
	        var d = this._fadeDuration;
	        if (this._fadeSign > 0) {
	        	if(this.fadeSpeed()*param.MapFadeMultiple>=this._fadeDuration){
	            	this._fadeSprite.opacity -= this._fadeSprite.opacity / d;
	            }
	        	this._fadeDuration--;
	        } else {
	            this._fadeSprite.opacity += (255 - this._fadeSprite.opacity) / (d*param.MapFadeMultiple);
	        	this._fadeDuration--;
	        }
	    }
	};

})();


code:
//=============================================================================
// MoveSpeedChangeByRegion.js
// ----------------------------------------------------------------------------
// (C)2015-2018 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.1 2018/02/15 フォロワーを連れているときにフォロワーの移動速度がおかしくなる問題を修正
// 1.0.0 2018/02/12 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc MoveSpeedChangeByRegionPlugin
 * @author triacontane
 *
 * @param slowlyTerrainTags
 * @desc 移動中に速度が低下する地形タグです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param fasterTerrainTags
 * @desc 移動中に速度が上昇する地形タグです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param slowlyRegions
 * @desc 移動中に速度が低下するリージョンです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param fasterRegions
 * @desc 移動中に速度が上昇するリージョンです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param deltaSpeed
 * @desc 速度が上昇、低下するときの変化量です。
 * @default 1
 * @type number
 *
 * @param commonEventID
 * @desc 移動速度が低下時に呼び出すコモンイベントを指定します。
 * @default 0
 * @type number
 *
 * @help MoveSpeedChangeByRegion.js
 *
 * 指定した地形もしくはリージョンに乗っている間だけキャラクターの移動速度を
 * 自動的に上昇もしくは低下させます。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc 地形による速度変化プラグイン
 * @author トリアコンタン
 *
 * @param slowlyTerrainTags
 * @text 速度低下地形
 * @desc 移動中に速度が低下する地形タグです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param fasterTerrainTags
 * @text 速度上昇地形
 * @desc 移動中に速度が上昇する地形タグです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param slowlyRegions
 * @text 速度低下リージョン
 * @desc 移動中に速度が低下するリージョンです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param fasterRegions
 * @text 速度上昇リージョン
 * @desc 移動中に速度が上昇するリージョンです。複数指定できます。
 * @default
 * @type number[]
 *
 * @param deltaSpeed
 * @text 速度変化量
 * @desc 速度が上昇、低下するときの変化量です。
 * @default 1
 * @type number
 *
 * @param commonEventID
 * @desc 移動速度が低下時に呼び出すコモンイベントを指定します。
 * @default 0
 * @type number
 *
 * @help MoveSpeedChangeByRegion.js
 *
 * 指定した地形もしくはリージョンに乗っている間だけキャラクターの移動速度を
 * 自動的に上昇もしくは低下させます。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';

    /**
     * Create plugin parameter. param[paramName] ex. param.commandPrefix
     * @param pluginName plugin name(MoveSpeedChangeByRegion)
     * @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('MoveSpeedChangeByRegion');
    if (!param.slowlyTerrainTags) {
        param.slowlyTerrainTags = [];
    }
    if (!param.fasterTerrainTags) {
        param.fasterTerrainTags = [];
    }
    if (!param.slowlyRegions) {
        param.slowlyRegions = [];
    }
    if (!param.fasterRegions) {
        param.fasterRegions = [];
    }

    //=============================================================================
    // Game_CharacterBase
    //  地形による速度変化を設定
    //=============================================================================
    var _Game_CharacterBase_realMoveSpeed      = Game_CharacterBase.prototype.realMoveSpeed;
    Game_CharacterBase.prototype.realMoveSpeed = function() {
        return _Game_CharacterBase_realMoveSpeed.apply(this, arguments) +
            this.changeSpeedByTerrainTags() + this.changeSpeedByRegions();
    };

    Game_CharacterBase.prototype.changeSpeedByTerrainTags = function() {
        var terrainTag = this.terrainTag();
        var speed      = 0;
        if (param.slowlyTerrainTags.contains(terrainTag)) {
            speed -= this.getDeltaSpeed();
        }
        if (param.fasterTerrainTags.contains(terrainTag)) {
            speed += this.getDeltaSpeed();
        }
        return speed;
    };

    Game_CharacterBase.prototype.changeSpeedByRegions = function() {
        var region = this.regionId();
        var speed  = 0;
        if (param.slowlyRegions.contains(region)) {
            speed -= this.getDeltaSpeed();
        }
        if (param.fasterRegions.contains(region)) {
            speed += this.getDeltaSpeed();
        }
        return speed;
    };

    Game_CharacterBase.prototype.getDeltaSpeed = function() {
        return param.deltaSpeed;
    };

    //=============================================================================
    // Game_Follower
    //  実移動速度を再定義
    //=============================================================================
    Game_Follower.prototype.realMoveSpeed = function() {
        return _Game_CharacterBase_realMoveSpeed.apply(this, arguments);
    };
})();


code:
//===========================================================================
// MpiComposePicture.js
//===========================================================================

/*:
 * @plugindesc 2つのピクチャを合成します。
 * @author 奏ねこま（おとぶき ねこま）
 *
 * @param Plugin Command
 * @desc プラグインコマンドを任意のコマンド名に変更できます。
 * @default compose_picture
 *
 * @help
 * [説明]
 *  2つのピクチャを合成して、新しいピクチャを作成します。
 *
 * [使用方法]
 *  合成したい２つの画像をあらかじめ、イベントコマンド「ピクチャの表示」で表示さ
 *  せておき（不透明度０でも可）、プラグインコマンドでピクチャ番号と合成方法を指
 *  定して合成します。
 *
 * [プラグインコマンド]
 *  compose_picture <pid1> <pid2> <type> <dx> <dy> <dw> <dh> <sx> <sy> <sw> <sh>
 *
 *  <実行例>
 *   compose_picture 1 2 xor
 *   compose_picture 1 2 xor 10 10
 *   compose_picture 1 2 xor 10 10 200 200
 *   compose_picture 1 2 xor 10 10 200 200 30 30
 *   compose_picture 1 2 xor 10 10 200 200 30 30 400 400
 *
 *  <引数に変数の値を使用する例>
 *   compose_picture \v[1] \v[2] xor \v[3] \v[4]
 *
 *  <引数説明>
 *   pid1    : 合成先ピクチャ番号
 *   pid2    : 合成元ピクチャ番号
 *   type    : 合成方法
 *   dx      : 合成先X座標（省略可）
 *   dy      : 合成先Y座標（省略可）
 *   dw      : 合成先横サイズ（省略可）
 *   dh      : 合成先縦サイズ（省略可）
 *   sx      : 合成元X座標（省略可）
 *   sy      : 合成元Y座標（省略可）
 *   sw      : 合成元横サイズ（省略可）
 *   sh      : 合成元縦サイズ（省略可）
 *
 *  <合成方法について>
 *   type（合成方法）に指定できるものには、以下のようなものがあります。
 *
 *   source-atop
 *   source-in
 *   source-out
 *   source-over
 *   destination-atop
 *   destination-in
 *   destination-out
 *   destination-over
 *   lighter
 *   copy
 *   xor
 *
 *   各合成方法の詳しい内容については、下記サイトなどをご参照下さい。
 *   http://www.html5.jp/canvas/ref/property/globalCompositeOperation.html
 *
 * [利用規約] ..................................................................
 *  - 本プラグインの利用は、RPGツクールMV/RPGMakerMVの正規ユーザーに限られます。
 *  - 商用、非商用、有償、無償、一般向け、成人向けを問わず、利用可能です。
 *  - 利用の際、連絡や報告は必要ありません。また、製作者名の記載等も不要です。
 *  - プラグインを導入した作品に同梱する形以外での再配布、転載はご遠慮ください。
 *  - 本プラグインにより生じたいかなる問題についても、一切の責任を負いかねます。
 * [改訂履歴] ..................................................................
 *   Version 1.00  2017/05/11  First edition.
 *   Version 1.01  2017/05/12  セーブ・ロードに対応。
 *   Version 1.02  2017/06/10  引数の変数指定が機能しなかった問題を修正
 * -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 *  Web Site: http://makonet.sakura.ne.jp/rpg_tkool/
 *  Twitter : https://twitter.com/koma_neko
 *  Copylight (c) 2017 Nekoma Otobuki
 */

var Imported = Imported || {};
var Makonet = Makonet || {};

(function(){
    'use strict';

    var plugin = 'MpiComposePicture';

    Imported[plugin] = true;
    Makonet[plugin] = {};

    var $mpi        = Makonet[plugin];
    $mpi.parameters = PluginManager.parameters(plugin);

    $mpi.plugin_command = $mpi.parameters['Plugin Command'];

    var _  = plugin;
    var __ = `$${_}`;

    //==============================================================================
    // Private Functions
    //==============================================================================

    // 文字列中の変数を値に変換
    function convertVariables(text) {
        if (typeof(text) !== 'string') return text;
        var pattern = '\\\\v\\[(\\d+)\\]';
        while (text.match(RegExp(pattern, 'i'))) {
            text = text.replace(RegExp(pattern, 'gi'), function(){
                return $gameVariables.value(+arguments[1]);
            });
        }
        return text;
    }

    // 画像を合成
    function executeComposition(condition) {
        var bitmap_d = null;
        var bitmap_s = null;
        if (condition.dname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.did);
            if (sprite && sprite._pictureName === condition.dname && sprite[_].condition) {
                bitmap_d = sprite.bitmap;
            } else {
                bitmap_d = executeComposition(condition.dcond);
            }
        } else {
            bitmap_d = ImageManager.loadPicture(condition.dname);
        }
        if (condition.sname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.sid);
            if (sprite && sprite._pictureName === condition.sname && sprite[_].condition) {
                bitmap_s = sprite.bitmap;
            } else {
                bitmap_s = executeComposition(condition.scond);
            }
        } else {
            bitmap_s = ImageManager.loadPicture(condition.sname);
        }
        var type = condition.type;
        var sx   = condition.sx;
        var sy   = condition.sy;
        var sw   = condition.sw || (bitmap_s.width - sx);
        var sh   = condition.sh || (bitmap_s.height - sy);
        var dx   = condition.dx;
        var dy   = condition.dy;
        var dw   = condition.dw || sw;
        var dh   = condition.dh || sh;
        var bitmap_c = new Bitmap(bitmap_d.width, bitmap_d.height);
        bitmap_c.blt(bitmap_d, 0, 0, bitmap_d.width, bitmap_d.height, 0, 0);
        bitmap_c.context.globalCompositeOperation = type;
        bitmap_c.context.drawImage(bitmap_s.canvas, sx, sy, sw, sh, dx, dy, dw, dh);
        bitmap_c._setDirty();
        return bitmap_c;
    }

    // Bitmapチェック
    function checkBitmap(condition) {
        if (condition.dname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.did);
            if (!sprite || sprite._pictureName !== condition.dname || !sprite[_].condition) {
                if (!checkBitmap(condition.dcond)) {
                    return false;
                }
            }
        } else if (!ImageManager.loadPicture(condition.dname).isReady()) {
            return false;
        }
        if (condition.sname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.sid);
            if (!sprite || sprite._pictureName !== condition.sname || !sprite[_].condition) {
                if (!checkBitmap(condition.scond)) {
                    return false;
                }
            }
        } else if (!ImageManager.loadPicture(condition.sname).isReady()) {
            return false;
        }
        return true;
    }

    // ピクチャIDからSprite_Pictureを取得
    function getSpritePicture(pictureId) {
        var sprite_picture = null;
        var spriteset = SceneManager._scene._spriteset;
        if (spriteset) {
            spriteset._pictureContainer.children.some(function(sprite) {
                if ((sprite instanceof Sprite_Picture) && sprite._pictureId === pictureId) {
                    sprite_picture = sprite;
                    return true;
                }
            });
        }
        return sprite_picture;
    }

    //==============================================================================
    // Game_Picture
    //==============================================================================

    Object.defineProperty(Game_Picture.prototype,_,{
        get:function(){return this[__]=this[__]||{ condition: null }},
        set:function(value){this[__]=value},
        configurable: true
    });

    //==============================================================================
    // Sprite_Picture
    //==============================================================================

    Object.defineProperty(Sprite_Picture.prototype,_,{
        get:function(){return this[__]=this[__]||{ condition: null }},
        set:function(value){this[__]=value},
        configurable: true
    });

    (function(o,p){
        var f=o[p];o[p]=function(){
            var picture = this.picture();
            if (picture) {
                var condition = picture[_].condition;
                if (condition && condition !== this[_].condition) {
                    this[_].condition = null;
                    if (checkBitmap(condition)) {
                        this.bitmap = executeComposition(condition);
                        this[_].condition = condition;
                    }
                }
            }
            f.apply(this,arguments);
        };
    }(Sprite_Picture.prototype,'updateBitmap'));

    (function(o,p){
        var f=o[p];o[p]=function(){
            if (!this._pictureName.match(/^::composed/)) {
                f.apply(this,arguments);
            }
        };
    }(Sprite_Picture.prototype,'loadBitmap'));

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

    (function(o,p){
        var f=o[p];o[p]=function(command, args){
            if (command === $mpi.plugin_command) {
                var did = +convertVariables(args[0]) || 0;
                var sid = +convertVariables(args[1]) || 0;
                var picture_d = $gameScreen.picture(did);
                var picture_s = $gameScreen.picture(sid);
                if (picture_d && picture_s) {
                    picture_d[_].condition = {
                        did:   did,
                        dname: picture_d.name(),
                        dcond: picture_d[_].condition,
                        sid:   sid,
                        sname: picture_s.name(),
                        scond: picture_s[_].condition,
                        type:  convertVariables(args[2])  || 'source-over',
                        dx:   +convertVariables(args[3])  || 0,
                        dy:   +convertVariables(args[4])  || 0,
                        dw:   +convertVariables(args[5])  || 0,
                        dh:   +convertVariables(args[6])  || 0,
                        sx:   +convertVariables(args[7])  || 0,
                        sy:   +convertVariables(args[8])  || 0,
                        sw:   +convertVariables(args[9])  || 0,
                        sh:   +convertVariables(args[10]) || 0
                    };
                    picture_d._name = '::composed' + Date.now();
                } else {
                    var id = [];
                    if (!picture_d) id.push(did);
                    if (!picture_s) id.push(sid);
                    throw new Error('[' + plugin + '] Picture does not exist. [id:' + id.join(',') + ']');
                }
            }
            f.apply(this,arguments);
        };
    }(Game_Interpreter.prototype,'pluginCommand'));
}());


code:
//==============================================================================
// MpiSuspendMessage
//==============================================================================

/*:
 * @plugindesc 文章の表示を一時中断
 * @author 奏ねこま（おとぶき ねこま）
 *
 * @param Suspend Switch ID
 * @type switch
 * @desc 文章の表示を一時中断させるスイッチの番号を指定してください。
 * @default 0
 *
 * @help
 * [説明]
 *  指定のスイッチがONになっている状態で「文章の表示」イベントを実行すると、
 *  文章を表示したあともウインドウを閉じず、その次の「文章の表示」イベント時に、
 *  現在表示している文章から続けて表示します。
 *
 * [使い方]
 *  一時中断させたい「文章の表示」イベントの直前で、プラグインパラメータで指定し
 *  たスイッチをONにします。
 *  スイッチをONにした状態で実行した「文章の表示」イベントが一時中断対象となりま
 *  すので、通常の動作をさせたい場合はイベント実行前にOFFにしてください。
 *
 * [補足]
 *  一時中断時でも入力待ちは発生します。一時中断～次の文章表示をノンストップで行
 *  いたい場合は、制御文字の「\^」をご利用ください。
 *  制御文字についてはRPGツクールMVのヘルプ、もしくは「文章の表示」イベント設定
 *  画面で入力欄にマウスカーソルを合わせたときに表示される説明をご参照ください。
 *
 * [利用規約] ..................................................................
 *  - 本プラグインの利用は、RPGツクールMV/RPGMakerMVの正規ユーザーに限られます。
 *  - 商用、非商用、有償、無償、一般向け、成人向けを問わず、利用可能です。
 *  - 利用の際、連絡や報告は必要ありません。また、製作者名の記載等も不要です。
 *  - プラグインを導入した作品に同梱する形以外での再配布、転載はご遠慮ください。
 *  - 本プラグインにより生じたいかなる問題についても、一切の責任を負いかねます。
 * [改訂履歴] ..................................................................
 *   Version 1.01  2018/06/27  YEP_MessageCoreの競合対策
 *   Version 1.00  2018/05/18  初版
 * -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 *  Web Site: http://makonet.sakura.ne.jp/rpg_tkool/
 *  Twitter : https://twitter.com/koma_neko
 *  Copylight (c) 2018 Nekoma Otobuki
 */

var Imported = Imported || {};
var Makonet = Makonet || {};

(function(){
	'use strict';

    var plugin = 'MpiSuspendMessage';

    Imported[plugin] = true;
    Makonet[plugin] = {};

    var $mpi = Makonet[plugin];
    $mpi.parameters = PluginManager.parameters(plugin);

    $mpi.switchId = Number($mpi.parameters['Suspend Switch ID']) || 0;

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

    (function(o,p){
		var f=o[p];o[p]=function(){
            return f.apply(this,arguments) || !!$gameSystem._MSM_textState;
		};
	}(Window_Message.prototype,'doesContinue'));

    (function(o,p){
		var f=o[p];o[p]=function(){
            var _contents = this.contents;
            var _clear = this.contents.clear;
            if ($gameSystem._MSM_textState) {
                this.contents.clear = function(){};
            }
            f.apply(this,arguments);
            if ($gameSystem._MSM_textState) {
                this._textState = $gameSystem._MSM_textState;
                this._textState.text += this.convertEscapeCharacters($gameMessage.allText());
                $gameSystem._MSM_textState = null;
                if (this.contents === _contents) {
                    this.contents.clear = _clear;
                }
                if (this.contents !== $gameTemp._MSM_contents) {
                    var _index = this._textState.index;
                    this._textState.index = 0;
                    this.newPage(this._textState);
                    while (this._textState.index < _index) {
                        this.processCharacter(this._textState);
                    }
                    this.clearFlags();
                    $gameTemp._MSM_contents = this.contents;
                }
            }
		};
	}(Window_Message.prototype,'startMessage'));

    (function(o,p){
		var f=o[p];o[p]=function(){
            if ($mpi.switchId && $gameSwitches.value($mpi.switchId)) {
                $gameSystem._MSM_textState = this._textState;
                $gameTemp._MSM_contents = this.contents;
            }
            f.apply(this,arguments);
		};
	}(Window_Message.prototype,'onEndOfText'));
}());


code:
//=============================================================================
// MultiStackState.js
//=============================================================================

/*:en
 * @plugindesc Implementing Multi-stackable States
 * @author Souji Kenzaki
 *
 *
 *
 * @help
 * This is a plugin for implementing States which can be stacked multiple times.
 * in the memo section of state, write in format of <maxstack: [number of maximum stack of this state]>
 * such as <maxstack:2>. In this case, that state can be stacked 2 times max instead of 1.
 */

/*:ja
 * @plugindesc ステート重複可能数拡張
 * @author 剣崎宗二
 *
 *
 * @help
 * タグのついたステートを、重複可能にするプラグインです。
 * ステートのメモに<maxstack:2> (数字は最大重複数）を入れると、その数までステートを重複して付与できるようになります。
 * 尚、可能な限り競合に対して防御策は施しましたが、ステート付与、除去系のプラグインとは依然相性が悪い事が予想されますので、
 * 使用時は十分にご注意ください。
 */

(function() {

Game_BattlerBase.prototype.countState = function(stateId) {
    var stateCount = 0;
    this._states.forEach(function(item)
    {
        if (item == stateId)
        {
            stateCount++;
        }
    });
    return stateCount;
}

var kz_Game_Battler_prototype_addState = Game_Battler.prototype.addState;
Game_Battler.prototype.addState = function(stateId) {
    var preCount = this.countState(stateId);
    kz_Game_Battler_prototype_addState.call(this, stateId);
    if ($dataStates[stateId])
    {
       var maxStack = $dataStates[stateId].meta.maxstack || 1;
       var postCount = this.countState(stateId);
       if (this.isStateAddable(stateId) && preCount == postCount && postCount < maxStack)
       {
          this.addNewState(stateId);
       }
       if (stateId == 153){
          $gameVariables.setValue(596,Math.min(preCount+1,maxStack))
          if($gameVariables.value(596) == maxStack){$gameVariables.setValue(596,"MAX")}
       }
    }
};

var kz_Game_Battler_prototype_removeState = Game_Battler.prototype.removeState;
Game_Battler.prototype.removeState = function(stateId) {
    while (this.countState(stateId) > 0)
    {
        var lastCount = this.countState(stateId);
        kz_Game_Battler_prototype_removeState.call(this, stateId);

        //For certain plugins which creates non-removable state
        if (lastCount == this.countState(stateId)) {break;}
    }
};
})();


code:
//=============================================================================
// NRP_EnemyRoutineKai.js
//=============================================================================

/*:
 * @plugindesc v1.01 敵行動ルーチンを改善します。
 * @author 砂川赳（http://newrpg.seesaa.net/）
 *
 * @help 敵の行動ルーチンを以下の通り改善します。
 * ・ターン開始時だけでなく行動直前にも行動再選択を行う。
 * ・ＨＰ＆ＭＰ回復時に最も減っている対象を選択する。
 * ・既にかかっているステートを重ねがけしない。
 * ・既に限界となっている能力変化を重ねがけしない。
 * ・有効な対象が存在しない場合、回復や治療、蘇生を行わない。
 *
 * ■個別設定
 * 敵キャラのメモ欄に以下を記入すれば個別設定も可能です。
 * ・行動直前の再設定を行うか？     ：<RoutineReset:[true or false]>
 * ・無意味な行動をしないか？       ：<RoutineTest:[true or false]>
 * ・回復系行動を制御するか？       ：<RoutineRecover:[true or false]>
 * ・HP回復を行う条件              ：<RoutineIfHp:[condition]>
 * ・MP回復を行う条件              ：<RoutineIfMp:[condition]>
 * ・蘇生系行動を制御するか？       ：<RoutineForDead:[true or false]>
 * ・対アクター使用効果を制御するか？：<RoutineActorEffect:[true or false]>
 * ・対エネミー使用効果を制御するか？：<RoutineEnemyEffect:[true or false]>
 * ・ステート耐性を見るか？         ：<RoutineWatchResist:[true or false]>
 *
 * ■注意点
 * ・回復時の対象制御はタイプが回復系のスキルのみ行います。
 * ・ステートなど使用効果の有効判定は、タイプが『なし』のスキルのみ行います。
 * ・タイプがダメージ・吸収系に該当するスキルは使用効果に依らず制御しません。
 * ・ターン制かつターン開始時に速度補正技が選ばれた場合、行動再選択を行いません。
 * ・また、行動再選択時に速度補正技を選ぶこともありません。
 *
 * ■利用規約
 * 特に制約はありません。
 * 改変、再配布自由、商用可、権利表示も任意です。
 * 作者は責任を負いませんが、不具合については可能な範囲で対応します。
 *
 * @param ＜基本設定＞
 * @desc 見出しです。
 *
 * @param resetAction
 * @text 行動直前の再設定
 * @parent ＜基本設定＞
 * @type boolean
 * @default false
 * @desc ONならば、行動直前にも再度の行動決定を行います。
 * 一人ずつ行動するCTBでは無意味なので、OFF推奨です。
 *
 * @param testApply
 * @text 行動判定の実行
 * @parent ＜基本設定＞
 * @type boolean
 * @default true
 * @desc ONならば効果の得られないスキルは使用しなくなります。
 *
 * @param ＜回復関連＞
 * @desc 見出しです。
 *
 * @param controlRecover
 * @text 回復系行動の制御
 * @parent ＜回復関連＞
 * @type boolean
 * @default true
 * @desc ONならば回復系スキルの制御を行います。
 *
 * @param ifHpRecover
 * @text HP回復行動の条件
 * @parent ＜回復関連＞
 * @type text
 * @default b.hpRate() < 1.0
 * @desc 指定した条件でHP回復を行います。
 * 『b.hpRate() < 1.0』で誰かのHPが100%未満になった時です。
 *
 * @param ifMpRecover
 * @text MP回復行動の条件
 * @parent ＜回復関連＞
 * @type text
 * @default b.mpRate() < 1.0
 * @desc MP回復系行動を行う条件を設定します。
 * 『b.mpRate() < 1.0』で誰かのMPが100%未満になった時です。
 *
 * @param controlForDead
 * @text 蘇生系行動の制御
 * @parent ＜回復関連＞
 * @type boolean
 * @default true
 * @desc ONならば戦闘不能者を対象にしたスキルの制御を行います。
 *
 * @param ＜使用効果関連＞
 * @desc 見出しです。
 *
 * @param controlEnemyEffect
 * @text 対エネミーの使用効果制御
 * @parent ＜使用効果関連＞
 * @type boolean
 * @default true
 * @desc ONならば仲間（エネミー）サイドに対する使用効果系スキルの制御を行います。（支援系ステートなど）
 *
 * @param controlActorEffect
 * @text 対アクターの使用効果制御
 * @parent ＜使用効果関連＞
 * @type boolean
 * @default true
 * @desc ONならば相手（アクター）サイドに対する使用効果系スキルの制御を行います。（異常系ステートなど）
 *
 * @param watchResist
 * @text ステート耐性を見るか
 * @parent ＜使用効果関連＞
 * @type boolean
 * @default false
 * @desc ONならば対象の耐性を確認し、無効なステートは使用しません。
 */
(function() {
"use strict";

function setDefault(str, def) {
    return str ? str : def;
}
function toBoolean(val, def) {
    if (val == "") {
        return def; // 空白なら初期値を返す
    }
    // 文字列ならboolean型に変換して返す
    return val.toLowerCase() == "true";
}

var parameters = PluginManager.parameters("NRP_EnemyRoutineKai");

var pResetAction = toBoolean(parameters["resetAction"], true);
var pTestApply = toBoolean(parameters["testApply"], true);

var pControlRecover = toBoolean(parameters["controlRecover"], true);
var pIfHpRecover = setDefault(parameters["ifHpRecover"], "b.hpRate() < 1.0");
var pIfMpRecover = setDefault(parameters["ifMpRecover"], "b.mpRate() < 1.0");
var pControlForDead = toBoolean(parameters["controlForDead"], true);

var pControlActorEffect = toBoolean(parameters["controlActorEffect"], true);
var pControlEnemyEffect = toBoolean(parameters["controlEnemyEffect"], true);
var pWatchResist = toBoolean(parameters["watchResist"], true);

/**
 * ●行動再決定を行うか？
 */
function isResetAction(subject) {
    // メモ欄のmeta情報を確認
    var flg = eval(subject.enemy().meta.RoutineReset);
    // 設定がある場合
    if (flg == true || flg == false) {
        return flg;
    }
    // 未定義の場合
    return pResetAction;
}

/**
 * ●行動判定の実行を行うか？
 */
function isTestApply(subject) {
    var flg = eval(subject.enemy().meta.RoutineTest);
    if (flg == true || flg == false) {
        return flg;
    }
    return pTestApply;
}

/**
 * ●回復系行動の制御を行うか？
 */
function isControlRecover(subject) {
    var flg = eval(subject.enemy().meta.RoutineRecover);
    if (flg == true || flg == false) {
        return flg;
    }
    return pControlRecover;
}

/**
 * ●HP回復を行うかを判定する。
 * @param a 行動主体
 * @param b 対象
 */
function isRoutineHpRecover(a, b) {
    var flg = eval(a.enemy().meta.RoutineIfHp);
    if (flg == true || flg == false) {
        return flg;
    }
    return eval(pIfHpRecover);
}

/**
 * ●MP回復を行うかを判定する。
 * @param a 行動主体
 * @param b 対象
 */
function isRoutineMpRecover(a, b) {
    var flg = eval(a.enemy().meta.RoutineIfMp);
    if (flg == true || flg == false) {
        return flg;
    }
    return eval(pIfMpRecover);
}

/**
 * ●蘇生系行動の制御を行うか？
 */
function isControlForDead(subject) {
    var flg = eval(subject.enemy().meta.RoutineForDead);
    if (flg == true || flg == false) {
        return flg;
    }
    return pControlForDead;
}

/**
 * ●対エネミーの使用効果制御を行うか？
 */
function isControlEnemyEffect(subject) {
    var flg = eval(subject.enemy().meta.RoutineEnemyEffect);
    if (flg == true || flg == false) {
        return flg;
    }
    return pControlEnemyEffect;
}

/**
 * ●対アクターの使用効果制御を行うか？
 */
function isControlActorEffect(subject) {
    var flg = eval(subject.enemy().meta.RoutineActorEffect);
    if (flg == true || flg == false) {
        return flg;
    }
    return pControlActorEffect;
}

/**
 * ●無効なステートを使用しないか？
 */
function isRoutineWatchResist(subject) {
    var flg = eval(subject.enemy().meta.RoutineWatchResist);
    if (flg == true || flg == false) {
        return flg;
    }
    return pWatchResist;
}

/**
 * ●速度補正技の除外処理を行うか？
 */
function isSpeedException(action) {
    // CTTBなら速度補正の意味が異なるので除外しない
    // _cttbCountの有無で判定
    if (BattleManager._cttbCount || BattleManager._isCttb || BattleManager._isCtb) {
        return false;
    }
    // 速度補正技なので除外する
    if (action.item().speed != 0) {
        return true;
    }
    return false;
}

// 行動再設定を判定するフラグ
var resetActionFlg = false;

/**
 * ●戦闘行動の処理
 */
var _BattleManager_processTurn = BattleManager.processTurn;
BattleManager.processTurn = function() {
    var subject = this._subject;

    // 敵の場合、行動直前の再設定を実行
    if (subject.isEnemy() && isResetAction(subject)) {
        var action = subject.currentAction();
        // 敵の場合、行動前のタイミングでアクション再設定
        if (action && subject.isEnemy()) {
            // ただし、速度補正技は除く
            if (!action.item() || !isSpeedException(action)) {
                resetActionFlg = true;
                subject.makeActions();
                resetActionFlg = false;
            }
        }
    }

    // 元処理実行
    _BattleManager_processTurn.apply(this);
};

/**
 * ●敵のターン参照
 */
var _Game_Troop_turnCount = Game_Troop.prototype.turnCount;
Game_Troop.prototype.turnCount = function() {
    var turnCount = _Game_Troop_turnCount.apply(this);

    // 行動再設定時はターン-1
    // そうしないとターン最初の行動決定と条件が一致しない
    if (resetActionFlg) {
        turnCount -= 1;
    }
    return turnCount;
};

/**
 * ●仲間への対象選択
 */
var _Game_Action_targetsForFriends = Game_Action.prototype.targetsForFriends;
Game_Action.prototype.targetsForFriends = function() {
    var subject = this.subject();

    /*
     * 以下の条件を全て満たす場合が対象
     * ・行動主体が敵
     * ・死亡者向けではない
     * ・対象が使用者ではない
     * ・単体が対象
     * ・対象がランダム（敵の単体対象は原則ランダム扱い）
     * ・ダメージ・吸収ではない
     */
    if (subject.isEnemy() && !this.isForDeadFriend() && !this.isForUser() && this.isForOne()
            && this._targetIndex < 0 && !this.isDamage() && !this.isDrain()) {
        var targets = [];
        var target;
        var unit = this.friendsUnit();

        // 回復制御を行う場合
        if (isControlRecover(subject)) {
            // HP回復の場合
            if (this.isHpRecover()) {
                // HPが最も減っている対象を選択
                target = unit.aliveMembers().reduce(function(a, b) {
                    return a.hpRate() < b.hpRate() ? a : b;
                });
                targets.push(target);
                return targets;

            // MP回復の場合
            } else if (this.isMpRecover()) {
                // MPが最も減っている対象を選択
                target = unit.aliveMembers().reduce(function(a, b) {
                    return a.mpRate() < b.mpRate() ? a : b;
                });
                targets.push(target);
                return targets;
            }
        }

        // ダメージタイプがなしで、かつ使用効果がある場合
        if (this.checkDamageType([0]) && this.item().effects.length > 0) {
            // 効果のある対象だけに候補を絞る
            var filterTargets = unit.aliveMembers().filter(function(m) {
                return this.testApplyEnemy(m);
            }, this);

            // 行動判定を行う場合、または有効な対象が存在する場合
            // ※行動判定を行わない、かつ有効な対象がない場合は通常の処理をさせる。
            if (isTestApply(subject) || filterTargets.length > 0) {
                // 絞った候補からさらにランダムで選択する。
                targets.push(randomTargetFilter(filterTargets));
                return targets;
            }
        }
    }

    // 条件を満たさない場合は元処理実行
    return _Game_Action_targetsForFriends.apply(this);
};

/**
 * ●相手サイドへの対象選択
 */
var _Game_Action_targetsForOpponents = Game_Action.prototype.targetsForOpponents;
Game_Action.prototype.targetsForOpponents = function() {
    var subject = this.subject();

    /*
     * 以下の条件を全て満たす場合が対象
     * ・行動主体が敵
     * ・単体が対象
     * ・対象がランダム（敵の単体対象は原則ランダム扱い）
     * ・ダメージタイプがなし
     * ・使用効果が存在する
     */
    if (subject.isEnemy() && this.isForOne()
            && this._targetIndex < 0 && this.checkDamageType([0]) && this.item().effects.length > 0) {
        var targets = [];
        var unit = this.opponentsUnit();

        // 効果のある対象だけに候補を絞る
        var filterTargets = unit.aliveMembers().filter(function(m) {
            return this.testApplyEnemy(m);
        }, this);

        // 行動判定を行う場合、または有効な対象が存在する場合
        // ※行動判定を行わない、かつ有効な対象がない場合は通常の処理をさせる。
        if (isTestApply(subject) || filterTargets.length > 0) {
            // 絞った候補からさらにランダムで選択する。
            targets.push(randomTargetFilter(filterTargets));
            return targets;
        }
    }

    // 条件を満たさない場合は元処理実行
    return _Game_Action_targetsForOpponents.apply(this);
};

/**
 * 【独自定義】指定した対象集団の狙われ率合計を求める。
 */
function tgrSumFilter(targets) {
    return targets.reduce(function(r, member) {
        return r + member.tgr;
    }, 0);
}

/**
 * 【独自定義】指定した対象集団から狙われ率に従ってランダムで選択する。
 */
function randomTargetFilter(targets) {
    var tgrRand = Math.random() * tgrSumFilter(targets);
    var target = null;
    targets.forEach(function(member) {
        tgrRand -= member.tgr;
        if (tgrRand <= 0 && !target) {
            target = member;
        }
    });
    return target;
}

/**
 * ●敵の行動有効判定
 * ここで無効にした行動は取らない。
 */
var Game_Enemy_isActionValid = Game_Enemy.prototype.isActionValid;
Game_Enemy.prototype.isActionValid = function(action) {
    // 元処理実行（通常の使用条件判定）
    var ret = Game_Enemy_isActionValid.apply(this, arguments);
    // 使用不可なら、そこで終了
    if (ret == false) {
        return ret;
    }

    // 行動判定の実行を行う場合のみ
    if (isTestApply(this)) {
        // 引数のactionはJSONのパラメータそのままなので、
        // Game_Actionに変換する。
        var gameAction = new Game_Action(this);
        gameAction.setSkill(action.skillId);

        // 既にターン実行中ならば、速度補正技は使用候補から外す。
        if (isResetAction(this) && BattleManager.isInTurn()) {
            if (gameAction.item() && isSpeedException(gameAction)) {
                return false;
            }
        }

        // 使用者が対象
        if (gameAction.isForUser()) {
            // 効果が無効ならば、使用候補から外す。
            if (!gameAction.testApplyEnemy(this)) {
                return false;
            }

        // それ以外
        } else {
            // 対象がアクター向けかつ全員無効ならば、使用候補から外す。
            if (gameAction.isForOpponent()
                    && $gameParty.members().every(function(m){return !gameAction.testApplyEnemy(m);})) {
                return false;

            // 対象がエネミー向けかつ全員無効ならば、使用候補から外す。
            } else if (gameAction.isForFriend()
                    && $gameTroop.members().every(function(m){return !gameAction.testApplyEnemy(m);})) {
                return false;
            }
        }
    }

    // 使用可能と認定
    return true;
};

/**
 * 【独自実装】敵行動の有効判定
 * ここでtrueを返した場合に使用可能な行動となる。
 */
Game_Action.prototype.testApplyEnemy = function(target) {
    var subject = this.subject();

    // 対象が戦闘不能の仲間向け
    if (this.isForDeadFriend()) {
        // 蘇生制御を行わない場合は常に有効
        if (!isControlForDead(subject)) {
            return true;
        }
        // 対象が戦闘不能なら有効
        if (target.isDead()) {
            return true;
        }
        // それ以外は無効
        return false;

    // それ以外で対象が戦闘不能（逃走も含む）なら無効
    } else if (!target.isAlive()) {
        return false;
    }

    // ダメージまたは吸収は常に有効
    if (this.isDamage() || this.isDrain()) {
        return true;

    // 回復系の場合
    } else if (this.isRecover()) {
        // 回復制御を行わない場合は常に有効
        if (!isControlRecover(subject)) {
            return true;
        }

        // 効果がHP回復、かつ対象のHPが減っている。
        if (this.isHpRecover() && isRoutineHpRecover(subject, target)) {
            return true;
        // 効果がMP回復、かつ対象のMPが減っている。
        } else if (this.isMpRecover() && isRoutineMpRecover(subject, target)) {
            return true;
        }

    // ダメージタイプがなし
    } else if (this.checkDamageType([0])) {
        // 対象がアクター、かつ使用効果制御を行わない場合は有効
        if (target.isActor() && !isControlActorEffect(subject)) {
            return true;
        // 対象がエネミー、かつ使用効果制御を行わない場合は有効
        } else if (target.isEnemy() && !isControlEnemyEffect(subject)) {
            return true;
        }

        // 使用効果が空（様子を見るなどの何もしない行動）なら有効
        if (this.item().effects.length == 0) {
            return true;
        // 何らかの使用効果が得られるなら有効
        } else if (this.hasItemAnyValidEffects(target)) {
            return true;
        }
    }

    // それ以外は無効と判定
    return false;
};

/**
 * ●使用効果を得られるか？
 */
var _Game_Action_testItemEffect = Game_Action.prototype.testItemEffect;
Game_Action.prototype.testItemEffect = function(target, effect) {
    // 敵限定
    if (this.subject().isEnemy()) {
        // ステート追加の場合のみ、無効かどうかを判定
        switch (effect.code) {
        case Game_Action.EFFECT_ADD_STATE:
            // 対象の耐性を参照する。
            if (isRoutineWatchResist(this.subject())) {
                // 対象がステート無効である。
                if (target.isStateResist(effect.dataId)) {
                    return false;
                // 行動が必中ではない。かつ、ステート成功率が０
                } else if (!this.isCertainHit() && target.stateRate(effect.dataId) == 0) {
                    return false;
                }
            }
        }
    }

    // 元処理実行
    return _Game_Action_testItemEffect.apply(this, arguments);
};

/**
 * ●バトラーに対する戦闘行動の強制
 */
var Game_Battler_forceAction = Game_Battler.prototype.forceAction;
Game_Battler.prototype.forceAction = function(skillId, targetIndex) {
    // 対象が-1（ランダム）の場合、decideRandomTarget()を経由せず、
    // そのまま返すように修正。
    // ここで確定してしまうと対象の補正を行えなくなる。
    if (targetIndex === -1) {
        this.clearActions();
        var action = new Game_Action(this, true);
        action.setSkill(skillId);
        action.setTarget(targetIndex);
        this._actions.push(action);
        return;
    }

    // 元処理実行
    Game_Battler_forceAction.apply(this, arguments);
};

})();


code:
//=============================================================================
// NRP_StopSelfMovement.js
//=============================================================================
/*:
 * @target MV MZ
 * @plugindesc v1.00 Stops the self-movement during event execution.
 * @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
 * @url http://newrpg.seesaa.net/article/486149145.html
 *
 * @help Stops self-movement for each event during event execution.
 *
 * If an event is running in parallel, it is not eligible.
 * However, only message display processing is exceptionally eligible.
 *
 * This function is equivalent to
 * the existing "StopSelfMovementWithPlayer.js",
 * but addresses the problem that the load increases dramatically
 * in proportion to the square of the number of events.
 *
 * -------------------------------------------------------------------
 * [Usage]
 * -------------------------------------------------------------------
 * Just apply the plugin and it will take effect.
 *
 * If you want to switch depending on the situation,
 * specify the plugin parameter "StopSwitch".
 * Only when the switch is on,
 * self-movement during event execution will stop.
 *
 * -------------------------------------------------------------------
 * [Note of Events]
 * -------------------------------------------------------------------
 * <ForceSelfMovement>
 * Forces self-movement to be performed regardless of the situation.
 * This is applicable, for example, to objects that are animated
 * by self-movement and would feel uncomfortable
 * if stopped during an event.
 *
 * -------------------------------------------------------------------
 * [Reference]
 * -------------------------------------------------------------------
 * The following plugin was used as references
 * in the creation of this plugin.
 *
 * StopSelfMovementWithPlayer.js (Sasuke KANNAZUKI)
 * https://forum.tkool.jp/index.php?threads/189/
 *
 * -------------------------------------------------------------------
 * [Terms]
 * -------------------------------------------------------------------
 * There are no restrictions.
 * Modification, redistribution freedom, commercial availability,
 * and rights indication are also optional.
 * The author is not responsible,
 * but will deal with defects to the extent possible.
 *
 * @------------------------------------------------------------------
 * @ [Plugin Parameters]
 * @------------------------------------------------------------------
 *
 * @param StopSwitch
 * @type switch
 * @desc Switch to stop self-movement during event execution.
 * Always enabled if not specified.
 *
 * @param StopParallelMessage
 * @type boolean
 * @default true
 * @desc Self-movement is also stopped during message display by parallel processing.
 */

/*:ja
 * @target MV MZ
 * @plugindesc v1.00 イベント実行中の自律移動を停止します。
 * @author 砂川赳（http://newrpg.seesaa.net/）
 * @url http://newrpg.seesaa.net/article/486149145.html
 *
 * @help イベント実行中に、各イベントの自律移動を停止します。
 *
 * 並列処理でイベントが実行されている場合は、対象外となります。
 * ただし、メッセージ表示処理のみ例外的に対象となります。
 *
 * 既存の『StopSelfMovementWithPlayer.js』と同等の機能ですが、
 * イベント数の二乗に比例して負荷が激増する問題に対処しています。
 *
 * -------------------------------------------------------------------
 * ■使用方法
 * -------------------------------------------------------------------
 * プラグインを適用するだけで有効になります。
 *
 * 状況によって切り替えたい場合は、
 * プラグインパラメータの『停止スイッチ』を指定してください。
 * スイッチがオンの場合のみ、イベント実行中の自律移動が停止します。
 *
 * -------------------------------------------------------------------
 * ■イベントのメモ欄
 * -------------------------------------------------------------------
 * <ForceSelfMovement>
 * 状況に関わらず、強制的に自律移動を実行させます。
 * 例えば、自律移動でアニメーションさせているオブジェクトなど、
 * イベント中に停止しては違和感があるものに活用できます。
 *
 * -------------------------------------------------------------------
 * ■参考
 * -------------------------------------------------------------------
 * このプラグインの制作に当たって、
 * 以下のプラグインを参考にさせていただきました。
 *
 * StopSelfMovementWithPlayer.js（神無月サスケ様）
 * https://forum.tkool.jp/index.php?threads/189/
 *
 * -------------------------------------------------------------------
 * ■利用規約
 * -------------------------------------------------------------------
 * 特に制約はありません。
 * 改変、再配布自由、商用可、権利表示も任意です。
 * 作者は責任を負いませんが、不具合については可能な範囲で対応します。
 *
 * @------------------------------------------------------------------
 * @ プラグインパラメータ
 * @------------------------------------------------------------------
 *
 * @param StopSwitch
 * @text 停止スイッチ
 * @type switch
 * @desc イベント実行中の自律移動を停止するスイッチです。
 * 未指定の場合は常に有効とします。
 *
 * @param StopParallelMessage
 * @text 並列メッセージ中も停止
 * @type boolean
 * @default true
 * @desc 並列処理によるメッセージ表示中も自律移動を停止します。
 */

(function() {
"use strict";

function toBoolean(str, def) {
    if (str === true || str === "true") {
        return true;
    } else if (str === false || str === "false") {
        return false;
    }
    return def;
}
function toNumber(str, def) {
    if (str == undefined || str == "") {
        return def;
    }
    return isNaN(str) ? def : +(str || def);
}
function setDefault(str, def) {
    if (str == undefined || str == "") {
        return def;
    }
    return str;
}

const PLUGIN_NAME = "NRP_StopSelfMovement";
const parameters = PluginManager.parameters(PLUGIN_NAME);
const pStopSwitch = toNumber(parameters["StopSwitch"]);
const pStopParallelMessage = toBoolean(parameters["StopParallelMessage"], true);

// イベントを停止するかどうかの判定
let mIsEventsStop = false;

// ----------------------------------------------------------------------------
// Game_Map
// ----------------------------------------------------------------------------

/**
 * ●イベントの更新
 */
const _Game_Map_updateEvents = Game_Map.prototype.updateEvents;
Game_Map.prototype.updateEvents = function() {
    // 動作軽量化のため判定は一度だけ
    // ※特に$gameMap.isEventRunning()は非常に重いので毎回実行しない。
    mIsEventsStop = isStop();

    _Game_Map_updateEvents.apply(this, arguments);
};

// ----------------------------------------------------------------------------
// Game_Event
// ----------------------------------------------------------------------------

/**
 * ●初期化
 */
const _Game_Event_initialize = Game_Event.prototype.initialize;
Game_Event.prototype.initialize = function(mapId, eventId) {
    _Game_Event_initialize.apply(this, arguments);

    // 強制実行フラグ
    this._forceSelfMovement = this.event().meta.ForceSelfMovement;
};

/**
 * ●自律移動更新
 */
const _Game_Event_updateSelfMovement = Game_Event.prototype.updateSelfMovement;
Game_Event.prototype.updateSelfMovement = function() {
    // 停止条件を満たしている。
    // かつ、イベントが強制実行状態ではない。
    if (mIsEventsStop && !this._forceSelfMovement) {
        return;
    }
    _Game_Event_updateSelfMovement.apply(this, arguments);
};

// ----------------------------------------------------------------------------
// 共通関数
// ----------------------------------------------------------------------------

/**
 * ●停止判定
 */
function isStop() {
    // イベント実行中またはメッセージ表示中の場合が対象
    if ($gameMap.isEventRunning() || isMessage()) {
        // 停止スイッチが未指定、または停止スイッチを満たしている。
        return !pStopSwitch || $gameSwitches.value(pStopSwitch);
    }
}

/**
 * ●メッセージ表示中かつ停止処理を行うかどうか？
 */
function isMessage() {
    // メッセージウィンドウが開かれているかどうか？
    return pStopParallelMessage && SceneManager._scene._messageWindow.isOpen();
}

})();