code:
//=============================================================================
// MenuSubCommand.js
// ----------------------------------------------------------------------------
// (C) 2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 4.1.0 2022/06/13 サブウィンドウを透過しない設定を追加、サブウィンドウの開閉にアニメーションを付ける設定を追加
// 4.0.2 2022/06/10 コマンド選択時に消去：OFF、メンバー選択あり：ON、親がひとつしかないサブコマンドを選択するとエラーになる現象を修正
// 4.0.1 2022/05/20 コマンドのデフォルト揃えが中央揃えになっていたので、プラグイン側もデフォルトを中央揃えに変更
// 4.0.0 2022/02/11 サブメニューの表示位置のパラメータ仕様を変更し、ウィンドウの好きな位置に追加できるよう修正
// 3.1.0 2021/12/09 サブメニューで選択したアクターのIDをマップ遷移時以外でも設定するよう変更
// 3.0.1 2020/10/15 スクリプトに凡例追加
// 3.0.0 2020/10/10 MZ向けに全面リファクタリング
// 2.7.3 2020/08/18 イベントの一時消去後にサブコマンドマップに移動して戻ってきたときに消去状態が復元されるよう修正
// 2.7.2 2020/04/03 2.5.0で適用したMOG_SceneMenu.jsとの競合解消と、2.0.1で適用したMOG_MenuCursor.jsとの競合解消を両立できるよう修正
// 2.7.1 2020/03/13 Window_MenuCommandの初期化で引数を渡し忘れていたのを修正
// 2.7.0 2019/10/25 メニューマップと通常マップのピクチャの表示状態を別々に管理できる機能を追加
// 2.6.1 2019/10/12 2.6.0の修正で、メニューを開いたあと一度もサブコマンドを開かずにメニューを閉じるとエラーになる問題を修正
//                  その他軽微な不具合の修正
// 2.6.0 2019/09/16 サブコマンドのスクリプト実行後、マップに戻る機能を追加
//                  MOG_MenuBackground.jsとの競合を解消
//                  サブコマンドをキャンセル後、スキルや装備コマンドを選択して戻ると、再度サブコマンドにフォーカスする問題を修正
//                  サブコマンドの座標固定値設定で、XかYいずれかひとつの値を設定していると設定が有効になるよう仕様変更
// 2.5.2 2019/09/08 2.0.1で対策して、2.5.0で何らかの理由で元に戻した競合対策を再度有効化
// 2.5.1 2019/07/11 FixCursorSeByMouse.jsとの競合対策のためメソッド名を変更
// 2.5.0 2018/11/25 サブメニューの絶対座標と揃えを設定できる機能を追加
//                  MOG_SceneMenu.jsとの競合を解消
// 2.4.1 2018/11/24 用語辞典プラグインと連携する方法をヘルプに記載
// 2.4.0 2018/09/26 サブコマンドを逐次消去するオプションを追加
// 2.3.0 2018/09/26 サブコマンドを横並べにするオプションを追加
// 2.2.1 2018/01/28 サブコマンドを選択後メニューに戻って通常コマンドを選択し、さらにメニューに戻ったときに最初のサブコマンドが展開される問題を修正
// 2.2.0 2018/01/07 同名の親コマンドを指定できる機能を追加
// 2.1.0 2017/12/24 対象メンバーを選択するサブコマンド選択時にメニューコマンドをその名前に置き換える処理を追加
//                  メニューへ戻った際に対象メンバー選択やサブコマンド選択に戻るように変更
// 2.0.1 2017/11/19 MOG_MenuCursor.jsとの併用時、カーソルがサブコマンドの下に隠れてしまう競合の解消
// 2.0.0 2017/09/04 メニューコマンドやサブコマンドを好きなだけ追加できるようパラメータの仕様を変更
// 1.1.0 2017/05/14 デフォルトのオプションとゲーム終了コマンドを削除できる機能を追加
//                  カンマ(,)を含むスクリプトを正しく実行できない問題を修正
// 1.0.3 2017/04/09 サブコマンドマップから戻ってきたときにイベント位置を復元できるよう修正
// 1.0.2 2017/04/08 サブコマンドマップから戻ってきたときにフォロワー位置を復元できるよう修正
// 1.0.1 2017/04/08 サブコマンドマップから戻ってきたタイミングでセーブしたときにロード時の位置がサブコマンドマップに
//                  なってしまう問題を修正
//                  戦闘リトライプラグインと併用したときにリトライ中は、マップ移動するメニューを使用禁止に設定
// 1.0.0 2017/04/01 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc メニュー画面のサブコマンドプラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/MenuSubCommand.js
 * @author トリアコンタン
 * @base PluginCommonBase
 *
 * @param subCommands
 * @text サブコマンド
 * @desc サブコマンド情報です。
 * @default
 * @type struct<SubCommand>[]
 *
 * @param commandPosition
 * @text コマンド追加位置
 * @desc サブコマンド群を追加する位置です。0を指定すると、ウィンドウの先頭に追加されます。
 * @default 0
 * @type number
 *
 * @param subMenuWidth
 * @text サブメニュー横幅
 * @desc サブメニューを表示するウィンドウの横幅です。指定しない場合デフォルト値「240」が適用されます。
 * @default 0
 * @type number
 *
 * @param selectActorIdVariable
 * @text 選択アクターID変数
 * @desc サブコマンドからアクターを選択したとき、そのアクターのIDを格納する変数番号です。
 * @default 0
 * @type variable
 *
 * @param windowSkin
 * @text ウィンドウスキン
 * @desc サブコマンド用のウィンドウに専用のスキンを設定します。
 * @default
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param hideOption
 * @text オプション消去
 * @desc メインメニューからオプションを消去します。
 * @default false
 * @type boolean
 *
 * @param hideGameEnd
 * @text ゲーム終了消去
 * @desc メインメニューからゲーム終了を消去します。
 * @default false
 * @type boolean
 *
 * @param horizontalSubMenu
 * @text 横並び
 * @desc サブメニューのコマンドを横に並べます。
 * @default false
 * @type boolean
 *
 * @param clearSubMenuOneByObe
 * @text コマンド選択時に消去
 * @desc サブコマンドを選択したタイミングでウィンドウを消去します。
 * @default true
 * @type boolean
 *
 * @param subMenuX
 * @text サブメニューX座標
 * @desc 指定するとサブコマンドのX座標が固定値になります。
 * @default 0
 * @type number
 *
 * @param subMenuY
 * @text サブメニューY座標
 * @desc 指定するとサブコマンドのY座標が固定値になります。
 * @default 0
 * @type number
 *
 * @param adjustX
 * @text サブメニューX座標補正
 * @desc サブコマンドのX座標を指定した値だけ補正します。
 * @default 0
 * @type number
 * @min -9999
 *
 * @param adjustY
 * @text サブメニューY座標補正
 * @desc サブコマンドのY座標を指定した値だけ補正します。
 * @default 0
 * @type number
 * @min -9999
 *
 * @param subMenuAlign
 * @text サブメニュー揃え
 * @desc サブコマンドの揃えを設定します。
 * @default
 * @type select
 * @option 左揃え
 * @value left
 * @option 中央揃え(デフォルト)
 * @value center
 * @option 右揃え
 * @value right
 *
 * @param overlapOther
 * @text 他ウィンドウに重ねる
 * @desc サブメニューウィンドウを透過し、背後のウィンドウが見えるようにします。
 * @type boolean
 * @default true
 *
 * @param openAnimation
 * @text 開閉アニメ表示
 * @desc サブメニューウィンドウを表示するとき開閉アニメーションを表示します。
 * @type boolean
 * @default false
 *
 * @param anotherPicInMenuMap
 * @text メニューピクチャ別管理
 * @desc メニューマップと通常マップのピクチャの表示状態を別々に管理します。
 * @default false
 * @type boolean
 *
 * @param autoTransparent
 * @text 自動で透明化
 * @desc サブマップ移動時に自働でプレイヤーを透明にします。
 * @default true
 * @type boolean
 *
 * @help MenuSubCommand.js
 *
 * メインメニュー画面に任意の名前のコマンドおよび
 * ツリー表示されるサブコマンドを好きなだけ追加できます。
 * サブコマンドを実行（決定）すると、任意のスクリプトが実行されるか、
 * もしくは指定したマップに移動します。（両方も可能）
 *
 * スクリプトは、主にスクリプトで組まれた別画面に遷移する場合に使用します。
 * もちろん他のプラグインで追加された画面にも遷移可能です。
 * マップ移動は主にイベントによる自作メニュー画面に遷移する場合に使用します。
 * 自作メニュー画面から戻る際は、再度メニューを開いてください。
 * 元々メニューを開いていた場所は別途保存しているので意識する必要はありません。
 *
 * また、通常の縦レイアウトとメニュー画面はもちろん、
 * プラグインによる横レイアウトのメニュー画面にも対応しています。
 *
 * サブコマンドが全て非表示だった場合、親項目自体も非表示になります。
 * 同じく全て使用禁止だった場合、親項目自体も使用禁止になります。
 *
 * サブコマンドがひとつしかない場合、サブコマンドウィンドウは表示されず
 * 親コマンドを選択した時点でサブコマンドを実行します。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~SubCommand:
 *
 * @param CommandId
 * @text コマンドID
 * @desc サブコマンドの識別番号。この番号と名称とでコマンドがまとめられます。通常は全て0で問題ありません。
 * @default 0
 *
 * @param Name
 * @text コマンド名称
 * @desc サブコマンドとして表示される名称
 * @default サブコマンド1
 *
 * @param ParentName
 * @text 親名称
 * @desc メインコマンドに表示されるサブコマンドの親名称。同一の名称の親を持つサブコマンドは一つに纏められます。
 * @default 親コマンド1
 *
 * @param HiddenSwitchId
 * @text 非表示スイッチ番号
 * @desc ONのときコマンドが非表示になるスイッチID
 * @default 0
 * @type switch
 *
 * @param DisableSwitchId
 * @text 使用禁止スイッチ番号
 * @desc ONのときコマンドが使用禁止になるスイッチID
 * @default 0
 * @type switch
 *
 * @param Script
 * @text スクリプト
 * @desc コマンドを決定したときに実行されるスクリプト
 * @default
 * @type combo
 * @option this.commandItem(); // アイテム画面を開く
 * @option this.commandSave(); // セーブ画面を開く
 * @option this.commandOptions(); // オプション画面を開く
 * @option this.commandGlossary(1); // 用語辞典を呼ぶ(用語辞典プラグイン使用時)
 * @option $gameSwitches.setValue(1, true); // スイッチ[1]をONにする
 * @option $gameVariables.setValue(1, 10); // 変数[1]に[10]を代入する
 * @option $gameTemp.reserveCommonEvent(1); // マップに戻った後でコモンイベント[1]を呼ぶ
 *
 * @param ReturnMap
 * @text マップに戻るかどうか
 * @desc スクリプト実行後にマップに戻ります。
 * @default false
 * @type boolean
 *
 * @param MapId
 * @text 遷移先マップID
 * @desc コマンドを決定したときに移動するマップID
 * @default 0
 *
 * @param SelectMember
 * @text メンバー選択あり
 * @desc コマンド実行前に対象メンバーを選択するかどうか
 * @default false
 * @type boolean
 */

(function() {
    'use strict';
    const script = document.currentScript;
    const param = PluginManagerEx.createParameter(script);
    if (!param.subCommands) {
        param.subCommands = [];
    }

    //=============================================================================
    // Game_Temp
    //  メニューコマンド情報を構築して保持します。
    //=============================================================================
    const _Game_Temp_initialize      = Game_Temp.prototype.initialize;
    Game_Temp.prototype.initialize = function() {
        _Game_Temp_initialize.apply(this, arguments);
        this.createMenuCommands();
    };

    Game_Temp.prototype.createMenuCommands = function() {
        this._menuParentCommands = new Map();
        param.subCommands.forEach(function(commands) {
            this.createMenuCommand(commands);
        }, this);
        /* 最後に選択したサブコマンド */
        this._lastSubCommand = {
            parent: null,
            index : 0
        };
    };

    Game_Temp.prototype.createMenuCommand = function(commands) {
        const parentName = commands.ParentName + commands.CommandId;
        if (!this._menuParentCommands.has(parentName)) {
            this._menuParentCommands.set(parentName, []);
        }
        const parent = this._menuParentCommands.get(parentName);
        parent.push(new Game_MenuSubCommand(commands));
    };

    Game_Temp.prototype.iterateMenuParents = function(callBackFunc, thisArg) {
        this._menuParentCommands.forEach(callBackFunc, thisArg);
    };

    Game_Temp.prototype.getSubMenuCommands = function(parentName) {
        return this._menuParentCommands.get(parentName);
    };

    /**
     * 最後に選択したサブコマンドを取得する
     */
    Game_Temp.prototype.getLastSubCommand = function() {
        return this._lastSubCommand;
    };

    Game_Temp.prototype.setLastSubCommandParent = function(parentName) {
        this._lastSubCommand.parent = parentName;
    };

    Game_Temp.prototype.setLastSubCommandIndex = function(index) {
        this._lastSubCommand.index = index;
    };

    /**
     * 最後に選択したサブコマンドをリセットする
     */
    Game_Temp.prototype.resetLastSubCommand = function() {
        this._lastSubCommand = {
            parent: null,
            index : 0
        };
    };

    //=============================================================================
    // Game_CharacterBase
    //  サブコマンドマップへ移動します。
    //=============================================================================
    Game_CharacterBase.prototype.savePosition = function() {
        this._originalX         = this.x;
        this._originalY         = this.y;
        this._originalDirection = this.direction();
    };

    Game_CharacterBase.prototype.restorePosition = function() {
        this.locate(this._originalX, this._originalY);
        this.setDirection(this._originalDirection);
    };

    //=============================================================================
    // Game_Player
    //  サブコマンドマップへ移動します。
    //=============================================================================
    Game_Player.prototype.reserveTransferToSubCommandMap = function(subCommandMapId) {
        this.saveOriginalMap();
        this.reserveTransfer(subCommandMapId, 0, 0, 0, 2);
        if (param.autoTransparent) {
            this.setTransparent(true);
            this._followers.data().forEach(follower => follower.setTransparent(true));
        }
        if (param.anotherPicInMenuMap) {
            $gameScreen.setupMenuMapPictures();
        }
        this._originalMapData = $dataMap;
    };

    Game_Player.prototype.reserveTransferToOriginalMap = function() {
        $dataMap = this._originalMapData;
        this.reserveTransfer(this._originalMapId, this._originalX, this._originalY, this._originalDirection, 2);
        if (param.autoTransparent) {
            this.setTransparent(this._originalTransparent);
            this._followers.data().forEach(follower => follower.setTransparent(this._originalTransparent));
        }
        this._originalMapId             = 0;
        this._transferringToOriginalMap = true;
        if (param.anotherPicInMenuMap) {
            $gameScreen.restoreNormalMapPictures();
        }
    };

    Game_Player.prototype.isInSubCommandMap = function() {
        return this._originalMapId > 0;
    };

    Game_Player.prototype.isTransferringToOriginalMap = function() {
        return this._transferringToOriginalMap;
    };

    Game_Player.prototype.saveOriginalMap = function() {
        this._originalMapId       = $gameMap.mapId();
        this._originalTransparent = this._transparent;
        this.savePosition();
    };

    const _Game_Player_performTransfer      = Game_Player.prototype.performTransfer;
    Game_Player.prototype.performTransfer = function() {
        _Game_Player_performTransfer.apply(this, arguments);
        if (this.isTransferringToOriginalMap()) {
            this.restorePosition();
            this._transferringToOriginalMap = false;
        }
    };

    Game_Player.prototype.savePosition = function() {
        Game_CharacterBase.prototype.savePosition.call(this, arguments);
        this._followers.data().forEach(follower => follower.savePosition());
        $gameMap.saveAllEventPosition();
    };

    Game_Player.prototype.restorePosition = function() {
        Game_CharacterBase.prototype.restorePosition.call(this, arguments);
        this._followers.data().forEach(follower => follower.restorePosition());
        $gameMap.restoreAllEventPosition();
    };

    //=============================================================================
    // Game_Map
    //  すべてのイベントの位置を保存します。
    //=============================================================================
    Game_Map.prototype.saveAllEventPosition = function() {
        this._eventPositions = [];
        this._eventErases = [];
        this.events().forEach(function(event) {
            const position                          = {};
            position.x                            = event.x;
            position.y                            = event.y;
            position.direction                    = event.direction();
            this._eventPositions[event.eventId()] = position;
            this._eventErases[event.eventId()]    = event._erased;
        }, this);
    };

    Game_Map.prototype.restoreAllEventPosition = function() {
        this.events().forEach(function(event) {
            const position = this._eventPositions[event.eventId()];
            if (position) {
                event.locate(position.x, position.y);
                event.setDirection(position.direction);
            }
            const erase = this._eventErases[event.eventId()];
            if (erase) {
                event.erase();
            }
        }, this);
        this._eventPositions = [];
    };

    //=============================================================================
    // Game_Party
    //  無効なアクター設定時のエラーを回避します。
    //=============================================================================
    const _Game_Party_setMenuActor      = Game_Party.prototype.setMenuActor;
    Game_Party.prototype.setMenuActor = function(actor) {
        if (!actor) return;
        _Game_Party_setMenuActor.apply(this, arguments);
    };

    Game_Screen.prototype.setupMenuMapPictures = function() {
        this._normalMapPictures = this._pictures;
        this.clearPictures();
    };

    Game_Screen.prototype.restoreNormalMapPictures = function() {
        if (this._normalMapPictures) {
            this._pictures = this._normalMapPictures;
        }
        this._normalMapPictures = null;
    };

    //=============================================================================
    // AudioManager
    //  システム効果音を消音します。
    //=============================================================================
    AudioManager.stopAllStaticSe = function() {
        this._staticBuffers.forEach(function(buffer) {
            buffer.stop();
        });
        this._staticBuffers = [];
    };

    //=============================================================================
    // SceneManager
    //  メニュー用マップではキャプチャを無効にします。
    //=============================================================================
    const _SceneManager_snapForBackground = SceneManager.snapForBackground;
    SceneManager.snapForBackground      = function() {
        if ($gamePlayer.isInSubCommandMap()) return;
        _SceneManager_snapForBackground.apply(this, arguments);
    };

    //=============================================================================
    // Scene_Map
    //  自作ゲーム用マップ遷移の場合、一部演出を無効化します。
    //=============================================================================
    const _Scene_Map_callMenu      = Scene_Map.prototype.callMenu;
    Scene_Map.prototype.callMenu = function() {
        _Scene_Map_callMenu.apply(this, arguments);
        if ($gamePlayer.isInSubCommandMap()) {
            AudioManager.stopAllStaticSe();
            SoundManager.playCancel();
        }
    };

    const _Scene_Map_onMapLoaded      = Scene_Map.prototype.onMapLoaded;
    Scene_Map.prototype.onMapLoaded = function() {
        _Scene_Map_onMapLoaded.apply(this, arguments);
        if ($gamePlayer.isInSubCommandMap()) {
            this._transfer = false;
        }
    };

    //=============================================================================
    // Scene_Menu
    //  メインメニューにコマンドを追加します。
    //=============================================================================
    const _Scene_Menu_create      = Scene_Menu.prototype.create;
    Scene_Menu.prototype.create = function() {
        _Scene_Menu_create.apply(this, arguments);
        this.loadSubCommandWindowSkin();
        if ($gamePlayer.isInSubCommandMap()) {
            $gamePlayer.reserveTransferToOriginalMap();
        }
        if (this._isSubCommandOkAfterCreate) {
            this.onSubCommandOk();
        }
    };

    Scene_Menu.prototype.loadSubCommandWindowSkin = function() {
        if (param.windowSkin) {
            ImageManager.loadSystem(param.windowSkin);
        }
    };

    const _Scene_Menu_isReady      = Scene_Menu.prototype.isReady;
    Scene_Menu.prototype.isReady = function() {
        return _Scene_Menu_isReady.apply(this, arguments) &&
            (!$gamePlayer.isTransferringToOriginalMap() || DataManager.isMapLoaded());
    };

    const _Scene_Menu_start      = Scene_Menu.prototype.start;
    Scene_Menu.prototype.start = function() {
        _Scene_Menu_start.apply(this, arguments);
        if ($gamePlayer.isTransferringToOriginalMap()) {
            $gamePlayer.performTransfer();
        }
    };

    const _Scene_Menu_createCommandWindow      = Scene_Menu.prototype.createCommandWindow;
    Scene_Menu.prototype.createCommandWindow = function() {
        _Scene_Menu_createCommandWindow.apply(this, arguments);
        $gameTemp.iterateMenuParents((subCommands, parentName) => {
            this._commandWindow.setHandler('parent' + parentName, this.commandParent.bind(this));
        });
        this._commandWindow.rightInputMode = this.isRightInputMode();
        this.selectLastCommand();
    };

    Scene_Menu.prototype.commandParent = function() {
        const parentName  = this._commandWindow.currentExt();
        const subCommands = $gameTemp.getSubMenuCommands(parentName);
        $gameTemp.setLastSubCommandParent(parentName);
        if (subCommands.length === 1) {
            this.onSubCommandOk(subCommands[0]);
        } else {
            if (!param.clearSubMenuOneByObe && this._subMenuWindow) {
                this._subMenuWindow.activate();
            } else {
                this.createSubMenuCommandWindow(parentName);
            }
        }
    };

    Scene_Menu.prototype.createSubMenuCommandWindow = function(parentName) {
        this._subMenuWindow = new Window_MenuSubCommand(this.createSubCommandRect(), parentName);
        this._subMenuWindow.updatePlacement(this._commandWindow);
        this._subMenuWindow.setHandler('ok', this.onSubCommandOk.bind(this));
        this._subMenuWindow.setHandler('cancel', this.onSubCommandCancel.bind(this));
        // for MOG_MenuBackground.js
        if (typeof this._subMenuWindow.updateBackgroundOpacity === 'function') {
            this._subMenuWindow.updateBackgroundOpacity();
        }
        this.addWindow(this._subMenuWindow);
        if (this._subMenuClosing) {
            this._windowLayer.removeChild(this._subMenuClosing);
            this._subMenuClosing = null;
        }
    };

    Scene_Menu.prototype.createSubCommandRect = function() {
        return new Rectangle(this.x, this.y, 1, 1);
    };

    Scene_Menu.prototype.removeSubMenuCommandWindow = function() {
        if (this._subMenuWindow) {
            if (param.openAnimation) {
                this._subMenuWindow.close();
                this._subMenuClosing = this._subMenuWindow;
            } else {
                this._windowLayer.removeChild(this._subMenuWindow);
            }
        }
        this._subMenuWindow = null;
    };

    Scene_Menu.prototype.onSubCommandOk = function(subCommand) {
        this._subCommand = (this._subMenuWindow ? this._subMenuWindow.currentExt() : subCommand);
        $gameTemp.setLastSubCommandIndex(this._subMenuWindow ? this._subMenuWindow.index() : 0);
        if (this._subCommand.isNeedSelectMember()) {
            if (this._subMenuWindow) {
                this._commandWindow.maskCommand(this._subCommand.getName());
                if (param.clearSubMenuOneByObe) {
                    this.removeSubMenuCommandWindow();
                } else {
                    this._subMenuWindow.deactivate();
                }
            }
            this._statusWindow.selectLast();
            this._statusWindow.activate();
            this._statusWindow.setHandler('ok', this.executeSubCommand.bind(this));
            this._statusWindow.setHandler('cancel', this.onPersonalCancel.bind(this));
        } else {
            this.executeSubCommand();
        }
    };

    Scene_Menu.prototype.onSubCommandCancel = function() {
        this.removeSubMenuCommandWindow();
        $gameTemp.resetLastSubCommand();
        this._commandWindow.activate();
    };

    const _Scene_Menu_onPersonalCancel      = Scene_Menu.prototype.onPersonalCancel;
    Scene_Menu.prototype.onPersonalCancel = function() {
        _Scene_Menu_onPersonalCancel.apply(this);
        this._commandWindow.maskOff();
        this.selectLastCommand();
    };

    Scene_Menu.prototype.selectLastCommand = function() {
        const lastSubCommand = $gameTemp.getLastSubCommand();
        if (lastSubCommand.parent) {
            this._commandWindow.selectSymbol('parent' + lastSubCommand.parent);
            const subCommands = $gameTemp.getSubMenuCommands(lastSubCommand.parent);
            if (subCommands.length !== 1) {
                this.commandParent();
                this._commandWindow.deactivate();
                this._subMenuWindow.select(lastSubCommand.index);
                /* 別シーンからキャラ選択に戻った時 */
                const subCommand = subCommands[lastSubCommand.index];
                if (subCommand.isNeedSelectMember()) {
                    this._isSubCommandOkAfterCreate = true;
                }
            }
        }
        $gameTemp.resetLastSubCommand();
    };

    Scene_Menu.prototype.executeSubCommand = function() {
        this.executeSubScript();
        this.moveSubCommandMap();
        if (param.selectActorIdVariable && this._subCommand.isNeedSelectMember()) {
            $gameVariables.setValue(param.selectActorIdVariable, this._statusWindow.getSelectedActorId());
        }
        if (!SceneManager.isSceneChanging()) {
            this.onSubCommandCancel();
            this._statusWindow.deselect();
            this._commandWindow.maskOff();
        } else {
            this._subCommandSelected = true;
        }
    };

    Scene_Menu.prototype.executeSubScript = function() {
        const script = this._subCommand.getSelectionScript();
        if (!script) return;
        try {
            eval(script);
        } catch (e) {
            SoundManager.playBuzzer();
            console.error(`実行スクリプトエラー[${script}] メッセージ[${e.message}]`);
        }
        if (this._subCommand.isReturnMap()) {
            SceneManager.pop();
        }
    };

    Scene_Menu.prototype.moveSubCommandMap = function() {
        const mapId = this._subCommand.getMoveTargetMap();
        if (mapId <= 0) {
            return;
        }
        $gamePlayer.reserveTransferToSubCommandMap(mapId);
        SceneManager.pop();
    };

    const _Scene_Menu_terminate      = Scene_Menu.prototype.terminate;
    Scene_Menu.prototype.terminate = function() {
        _Scene_Menu_terminate.apply(this, arguments);
        if (this._subCommand && this._subCommand.getMoveTargetMap() <= 0) {
            $gameTemp.resetLastSubCommand();
        }
    };

    const _Scene_Menu_createField      = Scene_Menu.prototype.createField;
    Scene_Menu.prototype.createField = function() {
        _Scene_Menu_createField.apply(this, arguments);
        if (this._subMenuWindow) {
            this.addChild(this._subMenuWindow);
        }
    };

    //=============================================================================
    // Window_MenuCommand
    //  サブコマンドを追加します。
    //=============================================================================
    const _Window_MenuCommand_initialize          = Window_MenuCommand.prototype.initialize;
    Window_MenuCommand.prototype.initialize     = function() {
        this._maskedName = {};
        this.rightInputMode = true;
        _Window_MenuCommand_initialize.apply(this, arguments);
    };

    const _Window_MenuCommand_initCommandPosition = Window_MenuCommand.initCommandPosition;
    Window_MenuCommand.initCommandPosition      = function() {
        if ($gamePlayer.isInSubCommandMap()) return;
        _Window_MenuCommand_initCommandPosition.apply(this, arguments);
    };

    const _Window_MenuCommand_makeCommandList = Window_MenuCommand.prototype.makeCommandList;
    Window_MenuCommand.prototype.makeCommandList = function() {
        _Window_MenuCommand_makeCommandList.apply(this, arguments);
        this.makeSubCommandList();
    };

    const _Window_MenuCommand_addGameEndCommand      = Window_MenuCommand.prototype.addGameEndCommand;
    Window_MenuCommand.prototype.addGameEndCommand = function() {
        if (this.needsCommand('gameEnd')) {
            _Window_MenuCommand_addGameEndCommand.apply(this, arguments);
        }
    };

    const _Window_MenuCommand_needsCommand      = Window_MenuCommand.prototype.needsCommand;
    Window_MenuCommand.prototype.needsCommand = function(name) {
        const need = _Window_MenuCommand_needsCommand.apply(this, arguments);
        if (name === 'options' && param.hideOption) {
            return false;
        }
        if (name === 'gameEnd' && param.hideGameEnd) {
            return false;
        }
        return need;
    };

    Window_MenuCommand.prototype.makeSubCommandList = function() {
        let addCount = 0;
        $gameTemp.iterateMenuParents((subCommands, parentName) => {
            this._subCommands = subCommands;
            if (this.checkSubCommands('isVisible')) {
                const commandName = this._maskedName[parentName] ? this._maskedName[parentName] : subCommands[0].getParentName();
                this.addCommand(commandName, 'parent' + parentName, this.checkSubCommands('isEnable'), parentName);
                const command = this._list.pop();
                this._list.splice(param.commandPosition + addCount, 0, command);
                addCount++;
            }
        });
    };

    Window_MenuCommand.prototype.checkSubCommands = function(methodName) {
        return this._subCommands.some(function(subCommand) {
            return subCommand[methodName]();
        });
    };

    Window_MenuCommand.prototype.calculateSubCommandX = function(width) {
        if (param.subMenuX) {
            return param.subMenuX;
        }
        let x = this.x;
        if (this.isHorizontalMenu()) {
            x += this._cursorRect.x;
        } else {
            x += this.rightInputMode ? -width : this.width;
        }
        x += param.adjustX || 0;
        return x.clamp(0, $dataSystem.advanced.uiAreaWidth - width);
    };

    Window_MenuCommand.prototype.calculateSubCommandY = function(height) {
        if (param.subMenuY) {
            return param.subMenuY;
        }
        let y = this.y;
        if (this.isHorizontalMenu()) {
            y += this.height;
        } else {
            y += this._cursorRect.y;
        }
        y += param.adjustY || 0;
        return y.clamp(0, $dataSystem.advanced.uiAreaHeight - height);
    };

    Window_MenuCommand.prototype.isHorizontalMenu = function() {
        return this.maxCols() >= this.maxPageRows();
    };

    Window_MenuCommand.prototype.maskCommand = function(maskName) {
        this._maskedName                                 = {};
        this._maskedName[this.commandName(this.index())] = maskName;
        this.refresh();
    };

    Window_MenuCommand.prototype.maskOff = function() {
        this._maskedName = {};
        this.refresh();
    };

    //=============================================================================
    // Window_MenuStatus
    //  選択しているアクターのIDを取得します。
    //=============================================================================
    Window_MenuStatus.prototype.getSelectedActorId = function() {
        return $gameParty.members()[this._index].actorId();
    };

    //=============================================================================
    // Window_MenuSubCommand
    //  サブコマンドウィンドウのクラスです。
    //=============================================================================
    function Window_MenuSubCommand() {
        this.initialize.apply(this, arguments);
    }

    Window_MenuSubCommand.prototype             = Object.create(Window_Command.prototype);
    Window_MenuSubCommand.prototype.constructor = Window_MenuSubCommand;

    Window_MenuSubCommand.prototype.initialize = function(rectangle, parentName) {
        this._parentName = parentName;
        Window_Command.prototype.initialize.call(this, rectangle);
        if (param.overlapOther) {
            this._isWindow = false;
        }
        if (param.openAnimation) {
            this._openness = 0;
            this.open();
        }
    };

    Window_MenuSubCommand.prototype.makeCommandList = function() {
        const subMenus = $gameTemp.getSubMenuCommands(this._parentName);
        subMenus.forEach(subMenu => {
            if (subMenu.isVisible()) {
                this.addCommand(subMenu.getName(), 'ok', subMenu.isEnable(), subMenu);
            }
        });
        this.width = this.windowWidth();
        this.height = this.fittingHeight(this.numVisibleRows());
        this.createContents();
    };

    Window_MenuSubCommand.prototype.numVisibleRows = function() {
        return param.horizontalSubMenu ? 1 : this.maxItems();
    };

    Window_MenuSubCommand.prototype.maxCols = function() {
        return param.horizontalSubMenu ? this.maxItems() : 1;
    };

    Window_MenuSubCommand.prototype.windowWidth = function() {
        return param.subMenuWidth || 240;
    };

    Window_MenuSubCommand.prototype.updatePlacement = function(commandWindow) {
        this.x = commandWindow.calculateSubCommandX(this.width);
        this.y = commandWindow.calculateSubCommandY(this.height);
    };

    Window_MenuSubCommand.prototype.standardFontSize = function() {
        return userSetting.subCommandWindow.fontSize || Window_Command.prototype.standardFontSize.call(this);
    };

    Window_MenuSubCommand.prototype.standardPadding = function() {
        return userSetting.subCommandWindow.padding || Window_Command.prototype.standardPadding.call(this);
    };

    Window_MenuSubCommand.prototype.loadWindowskin = function() {
        if (param.windowSkin) {
            this.windowskin = ImageManager.loadSystem(param.windowSkin);
        } else {
            Window_Command.prototype.loadWindowskin.call(this);
        }
    };

    const _Window_MenuSubCommand_itemTextAlign      = Window_MenuSubCommand.prototype.itemTextAlign;
    Window_MenuSubCommand.prototype.itemTextAlign = function() {
        return param.subMenuAlign || _Window_MenuSubCommand_itemTextAlign.apply(this, arguments);
    };

    //=============================================================================
    // Game_MenuSubCommand
    //  サブコマンドを扱うクラスです。
    //=============================================================================
    class Game_MenuSubCommand {
        constructor(subCommandData) {
            this._data = subCommandData;
        }

        getName() {
            return this._data.Name;
        }

        getParentName() {
            return this._data.ParentName;
        }

        isReturnMap() {
            return (!this.getMoveTargetMap()) && this._data.ReturnMap;
        }

        isVisible() {
            return !$gameSwitches.value(this._data.HiddenSwitchId);
        }

        isEnable() {
            return !$gameSwitches.value(this._data.DisableSwitchId) &&
                !(SceneManager.isSceneRetry && SceneManager.isSceneRetry() && this.getMoveTargetMap() > 0);
        }

        isNeedSelectMember() {
            return this._data.SelectMember;
        }

        getSelectionScript() {
            return this._data.Script;
        }

        getMoveTargetMap() {
            return this._data.MapId;
        }
    }
})();


code:
//=============================================================================
// MenubackGround.js
//=============================================================================

/*:
 * @plugindesc メニュー画面の背景を変更します。
 * @author Yoji Ojima, Sasuke KANNAZUKI,
 *
 * @param backGroundBitmap
 * @desc 背景にするビットマップファイルです。
 * img/pictures に置いてください。
 * @default
 *
 * @help このプラグインには、プラグインコマンドはありません。
 *
 *　デフォルトのメニューのみ対応。
 *　AltMenuScreen3.jsから、背景設定機能を移植しました。
 *　デフォルトのメニューに背景を指定できます。
 *
 * 使用報告不要・クレジット不要・改変可・商用利用可
 * もし何か問題が起きても、当方は一切責任を負いません。ご了承ください。
 */

(function() {

    // set parameters
    var parameters = PluginManager.parameters('MenubackGround');
    var backGroundBitmap = parameters['backGroundBitmap'] || '';

    // load bitmap that set in plugin parameter
    var _Scene_Menu_createBackground = Scene_Menu.prototype.createBackground;
    Scene_Menu.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_Menu_createBackground.call(this);
    };

    var _Scene_Item_createBackground = Scene_Item.prototype.createBackground;
    Scene_Item.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_Item_createBackground.call(this);
    };

    var _Scene_Skill_createBackground = Scene_Skill.prototype.createBackground;
    Scene_Skill.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_Skill_createBackground.call(this);
    };

    var _Scene_Equip_createBackground = Scene_Equip.prototype.createBackground;
    Scene_Equip.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_Equip_createBackground.call(this);
    };

    var _Scene_Status_createBackground =
     Scene_Status.prototype.createBackground;
    Scene_Status.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_Status_createBackground.call(this);
    };

    var _Scene_Options_createBackground =
     Scene_Options.prototype.createBackground;
    Scene_Options.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_Options_createBackground.call(this);
    };

    var _Scene_File_createBackground = Scene_File.prototype.createBackground;
    Scene_File.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_File_createBackground.call(this);
    };

    var _Scene_GameEnd_createBackground =
     Scene_GameEnd.prototype.createBackground;
    Scene_GameEnd.prototype.createBackground = function(){
        if(backGroundBitmap){
            this._backgroundSprite = new Sprite();
            this._backgroundSprite.bitmap =
             ImageManager.loadPicture(backGroundBitmap);
            this.addChild(this._backgroundSprite);
            return;
        }
        // if background file is invalid, it does original process.
        _Scene_GameEnd_createBackground.call(this);
    };

})();

repo_name: onms/sister

license: unknown


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);
    };
})();


code:
//=============================================================================
// MessageSkip.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.16.1 2021/08/29 スキップ中はウィンドウ背景が変わってもウィンドウを閉じないよう修正
// 1.16.0 2021/06/15 ピクチャによるクリックは押し続けスキップの対象外とするよう仕様変更
// 1.15.1 2021/06/01 1.15.0でループボイスを再生するとオートモードで文章が送られなくなる問題を修正
// 1.15.0 2021/05/31 SimpleVoice.jsと併用したとき、ボイス演奏中はオートモードによる文章送りを待機するよう変更
// 1.14.1 2020/10/15 ヘルプに注釈を追加
// 1.14.0 2020/08/02 クリックすることで任意のスイッチをONにできるピクチャをメッセージウィンドウに表示する機能を追加
// 1.13.0 2020/03/26 オート、スキップピクチャの表示方法をメッセージウィンドウからの相対座標と絶対座標とを選択できる機能を追加
// 1.12.1 2020/03/25 アイコン表示位置をメッセージウィンドウの位置やサイズの変更に追従するよう修正
// 1.12.0 2019/05/26 オート、スキップアイコンの位置を自由に指定できる機能を追加
// 1.11.0 2018/06/16 オート及びスキップの機能を一時的に無効化するスイッチを追加
// 1.10.1 2018/05/07 オートモードで途中に「\!」が含まれる場合の待機フレームが正しく計算されない問題を修正
// 1.10.0 2018/05/01 スキップモードとオートモードをスイッチで自動制御できる機能を追加
// 1.9.0 2018/02/18 イベント終了時にオート、スキップを解除するかどうかを任意のスイッチで判定できるように仕様変更
// 1.8.0 2018/02/16 オート待機フレーム数の計算式にウィンドウに表示した文字数を組み込める機能を追加
// 1.7.0 2017/12/12 SkipAlreadyReadMessage.jsとの連携したときに当プラグインのスキップ機能が既読スキップになるよう修正
//                  スキップピクチャの条件スイッチが0(指定なし)のときに同ピクチャが表示されない問題を修正
// 1.6.1 2017/09/21 オートモード時 改ページを伴わない入力待ちの後のメッセージを一瞬でスキップする問題を修正(by DarkPlasmaさん)
// 1.6.0 2017/08/03 キーを押している間だけスキップが有効にできる機能を追加
// 1.5.0 2017/05/27 オートおよびスキップボタンの原点指定と表示可否を変更できるスイッチの機能を追加
// 1.4.0 2017/05/26 クリックでオートおよびスキップを切り替えるボタンを追加
// 1.3.1 2017/05/13 アイコンの量を増やしたときにオートとスキップのアイコンが正常に表示されない問題を修正
// 1.3.0 2017/05/05 スキップ中はメッセージのウェイトを無視するよう修正
// 1.2.0 2017/04/29 並列実行のイベントでも通常イベントが実行中でなければスキップを解除するよう修正
//                  キーコードの「右」と「上」が逆になっていた問題を修正
//                  オート待機フレームを制御文字を使って動的に変更できる機能を追加
// 1.1.0 2016/12/14 並列処理イベントが実行されている場合にスキップが効かなくなる問題を修正
// 1.0.1 2016/02/15 モバイル端末での動作が遅くなる不具合を修正
// 1.0.0 2016/01/15 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc MessageSkipPlugin
 * @author triacontane
 *
 * @param SkipKey
 * @desc メッセージスキップに該当するキー(controlを選択するとAltキーも対象に含まれます)
 * (キーのアルファベット/shift/control/tab)
 * @default S
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option S
 *
 * @param AutoKey
 * @desc メッセージオートに該当するキー(controlを選択するとAltキーも対象に含まれます)
 * (キーのアルファベット/shift/control/tab)
 * @default A
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option A
 *
 * @param SkipSwitchId
 * @desc 指定した番号のスイッチがONになっている場合は常にスキップします。
 * @default 0
 * @type switch
 *
 * @param AutoSwitchIId
 * @desc 指定した番号のスイッチがONになっている場合は常にオートします。スキップが優先されます。
 * @default 0
 * @type switch
 *
 * @param SkipIcon
 * @desc メッセージスキップ中にウィンドウ右下に表示されるアイコン
 * @default 140
 * @type number
 *
 * @param AutoIcon
 * @desc メッセージオート中にウィンドウ右下に表示されるアイコン
 * @default 75
 * @type number
 *
 * @param IconX
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param IconY
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param PressingSkip
 * @desc スキップの判定が指定のキーを押している間のみになります。
 * @default false
 * @type boolean
 *
 * @param AutoWaitFrame
 * @desc オートモードが有効の場合にメッセージを表示しておくフレーム数。制御文字\v[n]および計算式が指定できます。
 * @default 100 + textSize * 10
 *
 * @param ResetOnEndSwitch
 * @desc 指定した番号のスイッチがONのとき、イベント終了時にスキップ、オート状態を解除します。0の場合は常に解除します。
 * @default 0
 * @type switch
 *
 * @param SkipPicture
 * @desc ウィンドウ内に表示するスキップピクチャのファイル名です。クリックするとスキップモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param SkipPictureX
 * @desc ウィンドウ内に表示するスキップピクチャのX座標です。
 * @default 500
 * @type number
 *
 * @param SkipPictureY
 * @desc ウィンドウ内に表示するスキップピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param AutoPicture
 * @desc ウィンドウ内に表示するオートピクチャのファイル名です。クリックするとオートモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param AutoPictureX
 * @desc ウィンドウ内に表示するオートピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param AutoPictureY
 * @desc ウィンドウ内に表示するオートピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param SwitchPicture
 * @desc ウィンドウ内に表示するスイッチピクチャのファイル名です。クリックすると指定したスイッチがONになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param SwitchPictureTrigger
 * @desc スイッチピクチャをクリックしたときにONにするスイッチ番号です。
 * @default 0
 * @type switch
 *
 * @param SwitchPictureX
 * @desc ウィンドウ内に表示するスイッチピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param SwitchPictureY
 * @desc ウィンドウ内に表示するスイッチピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param PictureSwitchId
 * @desc 指定した番号のスイッチがONのときのみスキップ、オートの各ピクチャボタンを表示します。0の場合は無条件で表示します。
 * @default 0
 * @type switch
 *
 * @param PictureAnchor
 * @desc スキップ、オートの各ピクチャボタン座標の原点です。（0:左上、1:右上、2:左下、3:右下）
 * @default 0
 * @type select
 * @option 0
 * @option 1
 * @option 2
 * @option 3
 *
 * @param PicturePosType
 * @desc オート、スキップピクチャの配置方法です。相対座標を選択するとウィンドウ表示位置からの相対座標となります。
 * @default relative
 * @type select
 * @option absolute
 * @option relative
 *
 * @param InvalidSwitchId
 * @desc 指定したスイッチがONのときプラグインの全機能が無効になります。
 * @default 0
 * @type switch
 *
 * @help メッセージウィンドウでメッセージのスキップやオートモードの切替ができます。
 * イベントが終了すると自働でスキップやオートモードは解除されます。
 * 並列実行イベントは、通常イベントが実行中でない場合のみ解除されます。
 * 明示的に解除したい場合は、以下のスクリプトを実行してください。
 *
 * $gameMessage.clearSkipInfo();
 *
 * ・SkipAlreadyReadMessage.jsとの連携
 * SkipAlreadyReadMessage.js（奏ねこま様作）と併用したときに
 * 当プラグインのスキップ機能は「既読スキップ」機能になります。
 * http://makonet.sakura.ne.jp/rpg_tkool/
 *
 * ・パラメータ「オート待機フレーム」を設定するとオートモード時の待機フレームを変更できます。
 * 制御文字\v[n]のほか、JavaScript計算式が使えます。
 * さらにtextSizeで表示文字数を計算式に組み込むことができます。
 *
 * 指定例：
 * 100 + textSize * 10
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * This plugin is released under the MIT License.
 */

/*:ja
 * @plugindesc メッセージスキッププラグイン
 * @author トリアコンタン
 *
 * @param スキップキー
 * @desc メッセージスキップに該当するキー
 * (キーのアルファベット/shift/control/tab)
 * @default S
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option S
 *
 * @param オートキー
 * @desc メッセージオートに該当するキー
 * (キーのアルファベット/shift/control/tab)
 * @default A
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option A
 *
 * @param スキップスイッチ
 * @desc 指定した番号のスイッチがONになっている場合は常にスキップします。
 * @default 0
 * @type switch
 *
 * @param オートスイッチ
 * @desc 指定した番号のスイッチがONになっている場合は常にオートします。スキップが優先されます。
 * @default 0
 * @type switch
 *
 * @param スキップアイコン
 * @desc メッセージスキップ中にウィンドウ右下に表示されるアイコン
 * @default 140
 * @type number
 *
 * @param オートアイコン
 * @desc メッセージオート中にウィンドウ右下に表示されるアイコン
 * @default 75
 * @type number
 *
 * @param アイコンX
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param アイコンY
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param 押し続けスキップ
 * @desc スキップの判定が指定のキーを押している間のみになります。
 * @default false
 * @type boolean
 *
 * @param オート待機フレーム
 * @desc オートモードが有効の場合にメッセージを表示しておくフレーム数。制御文字\v[n]および計算式が指定できます。
 * @default 100 + textSize * 10
 *
 * @param 終了解除スイッチID
 * @desc 指定した番号のスイッチがONのとき、イベント終了時にスキップ、オート状態を解除します。0の場合は常に解除します。
 * @default 0
 * @type switch
 *
 * @param スキップピクチャ
 * @desc ウィンドウ内に表示するスキップピクチャのファイル名です。クリックするとスキップモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param スキップピクチャX
 * @desc ウィンドウ内に表示するスキップピクチャのX座標です。
 * @default 500
 * @type number
 *
 * @param スキップピクチャY
 * @desc ウィンドウ内に表示するスキップピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param オートピクチャ
 * @desc ウィンドウ内に表示するオートピクチャのファイル名です。クリックするとオートモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param オートピクチャX
 * @desc ウィンドウ内に表示するオートピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param オートピクチャY
 * @desc ウィンドウ内に表示するオートピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param スイッチピクチャ
 * @desc ウィンドウ内に表示するスイッチピクチャのファイル名です。クリックすると指定したスイッチがONになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param スイッチピクチャトリガー
 * @desc スイッチピクチャをクリックしたときにONにするスイッチ番号です。
 * @default 0
 * @type switch
 *
 * @param スイッチピクチャX
 * @desc ウィンドウ内に表示するスイッチピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param スイッチピクチャY
 * @desc ウィンドウ内に表示するスイッチピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param ボタン原点
 * @desc スキップ、オートの各ピクチャボタン座標の原点です。（0:左上、1:右上、2:左下、3:右下）
 * @default 0
 * @type select
 * @option 0
 * @option 1
 * @option 2
 * @option 3
 *
 * @param ボタン表示スイッチID
 * @desc 指定した番号のスイッチがONのときのみスキップ、オートの各ピクチャボタンを表示します。0の場合は無条件で表示します。
 * @default 0
 * @type switch
 *
 * @param ピクチャ座標タイプ
 * @desc オート、スキップピクチャの配置方法です。相対座標を選択するとウィンドウ表示位置からの相対座標となります。
 * @default relative
 * @type select
 * @option 絶対座標
 * @value absolute
 * @option 相対座標
 * @value relative
 *
 * @param 無効化スイッチ
 * @desc 指定したスイッチがONのときプラグインの全機能が無効になります。
 * @default 0
 * @type switch
 *
 * @help メッセージウィンドウでメッセージのスキップやオートモードの切替ができます。
 * イベントが終了すると自働でスキップやオートモードは解除されます。
 * 並列実行イベントは、通常イベントが実行中でない場合のみ解除されます。
 * 明示的に解除したい場合は、以下のスクリプトを実行してください。
 *
 * $gameMessage.clearSkipInfo();
 *
 * ・SkipAlreadyReadMessage.jsとの連携
 * SkipAlreadyReadMessage.js（奏ねこま様作）と併用したときに
 * 当プラグインのスキップ機能は「既読スキップ」機能になります。
 * http://makonet.sakura.ne.jp/rpg_tkool/
 *
 * ・パラメータ「オート待機フレーム」を設定するとオートモード時の待機フレームを変更できます。
 * 制御文字\v[n]のほか、JavaScript計算式が使えます。
 * さらにtextSizeで表示文字数を計算式に組み込むことができます。
 *
 * 指定例：
 * 100 + textSize * 10
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/**
 * メッセージボタンスプライト
 * @constructor
 */
function Sprite_MessageButton() {
    this.initialize.apply(this, arguments);
}

/**
 * アイコン描画用スプライト
 * @constructor
 */
function Sprite_Frame() {
    this.initialize.apply(this, arguments);
}

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

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

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

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

    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 convertEscapeCharacters = function(text) {
        if (isNotAString(text)) text = '';
        var windowLayer = SceneManager._scene._windowLayer;
        return windowLayer ? windowLayer.children[0].convertEscapeCharacters(text) : text;
    };

    var isNotAString = function(args) {
        return String(args) !== args;
    };

    Number.prototype.times = function(handler) {
        var i = 0;
        while (i < this) handler.call(this, i++);
    };

    Input.keyCodeReverseMapper = {
        a        : 65, b: 66, c: 67, d: 68, e: 69, f: 70, g: 71,
        h        : 72, i: 73, j: 74, k: 75, l: 76, m: 77, n: 78,
        o        : 79, p: 80, q: 81, r: 82, s: 83, t: 84, u: 85,
        v        : 86, w: 87, x: 88, y: 89, z: 90,
        backspace: 8, tab: 9, enter: 13, shift: 16, ctrl: 17, alt: 18, pause: 19, esc: 27, space: 32,
        page_up  : 33, page_down: 34, end: 35, home: 36, left: 37, right: 39, up: 38, down: 40, insert: 45, delete: 46
    };
    (9).times(function(i) {
        Input.keyCodeReverseMapper[i] = i + 48;
    });
    (12).times(function(i) {
        Input.keyCodeReverseMapper['f' + (i + 1)] = i + 112;
    });

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var skipKeyName = getParamString(['SkipKey', 'スキップキー']).toLowerCase();
    var skipKeyCode = Input.keyCodeReverseMapper[skipKeyName];
    var autoKeyName = getParamString(['AutoKey', 'オートキー']).toLowerCase();
    var autoKeyCode = Input.keyCodeReverseMapper[autoKeyName];
    if (skipKeyCode) {
        if (!Input.keyMapper[skipKeyCode]) {
            Input.keyMapper[skipKeyCode] = 'messageSkip';
        } else {
            skipKeyName = Input.keyMapper[skipKeyCode];
        }
    }
    if (autoKeyCode) {
        if (!Input.keyMapper[autoKeyCode]) {
            Input.keyMapper[autoKeyCode] = 'messageAuto';
        } else {
            autoKeyName = Input.keyMapper[autoKeyCode];
        }
    }
    var paramSkipPicture          = getParamString(['SkipPicture', 'スキップピクチャ']);
    var paramSkipPictureX         = getParamNumber(['SkipPictureX', 'スキップピクチャX']);
    var paramSkipPictureY         = getParamNumber(['SkipPictureY', 'スキップピクチャY']);
    var paramAutoPicture          = getParamString(['AutoPicture', 'オートピクチャ']);
    var paramAutoPictureX         = getParamNumber(['AutoPictureX', 'オートピクチャX']);
    var paramAutoPictureY         = getParamNumber(['AutoPictureY', 'オートピクチャY']);
    var paramSwitchPicture        = getParamString(['SwitchPicture', 'スイッチピクチャ']);
    var paramSwitchPictureX       = getParamNumber(['SwitchPictureX', 'スイッチピクチャX']);
    var paramSwitchPictureY       = getParamNumber(['SwitchPictureY', 'スイッチピクチャY']);
    var paramSwitchPictureTrigger = getParamNumber(['SwitchPictureTrigger', 'スイッチピクチャトリガー'], 0);
    var paramPictureAnchor        = getParamNumber(['PictureAnchor', 'ボタン原点']);
    var paramPictureSwitchId      = getParamNumber(['PictureSwitchId', 'ボタン表示スイッチID'], 0);
    var paramPressingSkip         = getParamBoolean(['PressingSkip', '押し続けスキップ']);
    var paramSkipSwitchId         = getParamNumber(['SkipSwitchId', 'スキップスイッチ'], 0);
    var paramAutoSwitchIId        = getParamNumber(['AutoSwitchIId', 'オートスイッチ'], 0);
    var paramInvalidSwitchId      = getParamNumber(['InvalidSwitchId', '無効化スイッチ'], 0);
    var paramIconX                = getParamNumber(['IconX', 'アイコンX'], 0);
    var paramIconY                = getParamNumber(['IconY', 'アイコンY'], 0);
    var paramPicturePosType       = getParamString(['PicturePosType', 'ピクチャ座標タイプ']);

    //=============================================================================
    // Game_Message
    //  メッセージスキップ情報を保持します。
    //=============================================================================
    var _Game_Message_initialize      = Game_Message.prototype.initialize;
    Game_Message.prototype.initialize = function() {
        _Game_Message_initialize.apply(this, arguments);
        this.clearSkipInfo();
        this._autoClearSkipSwitch = getParamNumber(['ResetOnEndSwitch', '終了解除スイッチID']);
    };

    Game_Message.prototype.toggleSkip = function() {
        this.setSkipFlg(!this._skipFlg);
    };

    Game_Message.prototype.toggleAuto = function() {
        this.setAutoFlg(!this._autoFlg);
    };

    Game_Message.prototype.skipFlg = function() {
        return this._skipFlg;
    };

    Game_Message.prototype.autoFlg = function() {
        return this._autoFlg;
    };

    Game_Message.prototype.setSkipFlg = function(value) {
        this._skipFlg = value;
        if (this._skipFlg) this._autoFlg = false;
    };

    Game_Message.prototype.setAutoFlg = function(value) {
        if (!this._skipFlg) {
            this._autoFlg = value;
        }
    };

    Game_Message.prototype.clearSkipInfo = function() {
        this._skipFlg = false;
        this._autoFlg = false;
    };

    Game_Message.prototype.terminateEvent = function() {
        if (!this._autoClearSkipSwitch || $gameSwitches.value(this._autoClearSkipSwitch)) {
            this.clearSkipInfo();
        }
    };

    //=============================================================================
    // Game_Interpreter
    //  マップイベント終了時にメッセージスキップフラグを初期化します。
    //=============================================================================
    var _Game_Interpreter_terminate      = Game_Interpreter.prototype.terminate;
    Game_Interpreter.prototype.terminate = function() {
        _Game_Interpreter_terminate.apply(this, arguments);
        if (this.isNeedClearSkip()) {
            $gameMessage.terminateEvent();
        }
    };

    Game_Interpreter.prototype.isNeedClearSkip = function() {
        return ($gameMap.isMapInterpreterOf(this) || !$gameMap.isEventRunning()) && this._depth === 0;
    };

    //=============================================================================
    // Game_Map
    //  指定されたインタプリタがマップイベントかどうかを返します。
    //=============================================================================
    Game_Map.prototype.isMapInterpreterOf = function(interpreter) {
        return this._interpreter === interpreter;
    };

    //=============================================================================
    // Window_Message
    //  メッセージスキップ状態を描画します。
    //=============================================================================
    var _Window_Message_initialize      = Window_Message.prototype.initialize;
    Window_Message.prototype.initialize = function() {
        _Window_Message_initialize.apply(this, arguments);
        this.createSpriteFrame();
        this.createSpriteSkipButton();
        this.createSpriteAutoButton();
        this.createSpriteSwitchButton();
    };

    Window_Message.prototype.createSpriteFrame = function() {
        this._icon = new Sprite_Frame(ImageManager.loadSystem('IconSet'), -1);
        this.addChild(this._icon);
        this.updatePlacementIcon();
    };

    Window_Message.prototype.updatePlacementIcon = function() {
        this._icon.x = (paramIconX ? paramIconX - this.x : this.width - this._icon.width);
        this._icon.y = (paramIconY ? paramIconY - this.y : this.height - this._icon.height);
    };

    Window_Message.prototype.createSpriteSkipButton = function() {
        if (!paramSkipPicture) return;
        this._skipButton = new Sprite_MessageButton(paramSkipPicture);
        this.addChild(this._skipButton);
    };

    var _Window_Message_areSettingsChanged = Window_Message.prototype.areSettingsChanged;
    Window_Message.prototype.areSettingsChanged = function() {
        var result = _Window_Message_areSettingsChanged.apply(this, arguments);
        if ($gameMessage.skipFlg()) {
            return this._positionType !== $gameMessage.positionType();
        } else {
            return result;
        }
    };

    Window_Message.prototype.createSpriteAutoButton = function() {
        if (!paramAutoPicture) return;
        this._autoButton = new Sprite_MessageButton(paramAutoPicture);
        this.addChild(this._autoButton);
    };

    Window_Message.prototype.createSpriteSwitchButton = function() {
        if (!paramSwitchPicture) return;
        this._switchButton = new Sprite_MessageButton(paramSwitchPicture);
        this.addChild(this._switchButton);
    };

    Window_Message.prototype.getRelativeButtonX = function(originalX) {
        if (paramPictureAnchor === 1 || paramPictureAnchor === 3) {
            originalX += this.width;
        }
        if (paramPicturePosType === 'absolute') {
            originalX -= this.x;
        }
        return originalX;
    };

    Window_Message.prototype.getRelativeButtonY = function(originalY) {
        if (paramPictureAnchor === 2 || paramPictureAnchor === 3) {
            originalY += this.height;
        }
        if (paramPicturePosType === 'absolute') {
            originalY -= this.y;
        }
        return originalY;
    };

    var _Window_Message_startMessage      = Window_Message.prototype.startMessage;
    Window_Message.prototype.startMessage = function() {
        _Window_Message_startMessage.apply(this, arguments);
        this.initializeMessageAutoCount();
    };

    Window_Message.prototype.initializeMessageAutoCount = function() {
        var textSize = 0;
        if (this._textState) {
            var index = this._textState.index;
            var text  = this._textState.text;
            while (text[index] && !(text[index] === '\x1b' && text[index + 1] === '!')) {
                index++;
            }
            // use in eval
            textSize = index - this._textState.index;
        }
        var paramValue         = convertEscapeCharacters(getParamString(['AutoWaitFrame', 'オート待機フレーム'])) || 1;
        this._messageAutoCount = eval(paramValue);
    };

    var _Window_Message_update      = Window_Message.prototype.update;
    Window_Message.prototype.update = function() {
        this.updateAutoIcon();
        return _Window_Message_update.apply(this, arguments);
    };

    var _Window_Message_updatePlacement      = Window_Message.prototype.updatePlacement;
    Window_Message.prototype.updatePlacement = function() {
        _Window_Message_updatePlacement.apply(this, arguments);
        if (this._skipButton) {
            this.updateSkipButtonPlacement();
        }
        if (this._autoButton) {
            this.updateAutoButtonPlacement();
        }
        if (this._switchButton) {
            this.updateSwitchButtonPlacement();
        }
    };

    Window_Message.prototype.updateSkipButtonPlacement = function() {
        var x = this.getRelativeButtonX(paramSkipPictureX);
        var y = this.getRelativeButtonY(paramSkipPictureY);
        this._skipButton.move(x, y);
    };

    Window_Message.prototype.updateAutoButtonPlacement = function() {
        var x = this.getRelativeButtonX(paramAutoPictureX);
        var y = this.getRelativeButtonY(paramAutoPictureY);
        this._autoButton.move(x, y);
    };

    Window_Message.prototype.updateSwitchButtonPlacement = function() {
        var x = this.getRelativeButtonX(paramSwitchPictureX);
        var y = this.getRelativeButtonY(paramSwitchPictureY);
        this._switchButton.move(x, y);
    };

    Window_Message.prototype.updateAutoIcon = function() {
        if (this.messageSkip() && this.openness === 255) {
            this._icon.refresh(getParamNumber(['SkipIcon', 'スキップアイコン']));
            this._icon.flashSpeed = 16;
            this._icon.flash      = true;
            this.updatePlacementIcon();
        } else if (this.messageAuto() && this.openness === 255) {
            this._icon.refresh(getParamNumber(['AutoIcon', 'オートアイコン']));
            this._icon.flashSpeed = 2;
            this._icon.flash      = true;
            this.updatePlacementIcon();
        } else {
            this._icon.refresh(0);
            this._icon.flash = false;
        }
    };

    var _Window_Message_updateWait      = Window_Message.prototype.updateWait;
    Window_Message.prototype.updateWait = function() {
        this.updateSkipAuto();
        this.updateSwitchPicture();
        if (this.messageSkip()) {
            this._waitCount = 0;
        }
        return _Window_Message_updateWait.apply(this, arguments);
    };

    Window_Message.prototype.updateSkipAuto = function() {
        if (this.isClosed()) return;
        if (this.isAnySubWindowActive()) {
            $gameMessage.clearSkipInfo();
        } else {
            this.setSkipAutoFlagByTrigger();
            this.setSkipAutoFlagBySwitch();
        }
        this.updateSkipForSkipAlreadyReadMessage();
    };

    Window_Message.prototype.updateSwitchPicture = function() {
        if (this.isTriggeredMessageSwitchButton()) {
            $gameSwitches.setValue(paramSwitchPictureTrigger, true);
        }
    };

    Window_Message.prototype.setSkipAutoFlagByTrigger = function() {
        if (this.isTriggeredMessageSkip()) {
            if (!paramPressingSkip) {
                $gameMessage.toggleSkip();
            }
            this._pressSkipStop = false;
        } else if (this.isTriggeredMessageSkipButton()) {
            $gameMessage.toggleSkip();
            this._pressSkipStop = true;
        } else if (this.isTriggeredMessageAuto()) {
            $gameMessage.toggleAuto();
        } else if (paramPressingSkip && !this._pressSkipStop) {
            $gameMessage.setSkipFlg(this.isPressedMessageSkip());
        }
    };

    Window_Message.prototype.setSkipAutoFlagBySwitch = function() {
        if (paramInvalidSwitchId > 0 && $gameSwitches.value(paramInvalidSwitchId)) {
            $gameMessage.setSkipFlg(false);
            $gameMessage.setAutoFlg(false);
            return;
        }
        if (paramSkipSwitchId > 0) {
            $gameMessage.setSkipFlg($gameSwitches.value(paramSkipSwitchId));
        }
        if (paramAutoSwitchIId > 0) {
            $gameMessage.setAutoFlg($gameSwitches.value(paramAutoSwitchIId));
        }
    };

    // for SkipAlreadyReadMessage.js
    Window_Message.prototype.updateSkipForSkipAlreadyReadMessage = function() {
        var pluginName = 'SkipAlreadyReadMessage';
        if ($gameMessage[pluginName] && !$gameMessage[pluginName].already_read) {
            $gameMessage.setSkipFlg(false);
        }
    };

    Window_Message.prototype.messageAuto = function() {
        return $gameMessage.autoFlg();
    };

    Window_Message.prototype.messageSkip = function() {
        return $gameMessage.skipFlg();
    };

    var _Window_Message_updateInput      = Window_Message.prototype.updateInput;
    Window_Message.prototype.updateInput = function() {
        if (this.messageAuto() && this._messageAutoCount > 0 && this.visible) this._messageAutoCount--;
        return _Window_Message_updateInput.apply(this, arguments);
    };

    Window_Message.prototype.isTriggeredMessageSkip = function() {
        return Input.isTriggered('messageSkip') ||
            Input.isTriggered(skipKeyName);
    };

    Window_Message.prototype.isPressedMessageSkip = function() {
        return Input.isPressed('messageSkip') ||
            Input.isPressed(skipKeyName);
    };

    Window_Message.prototype.isTriggeredMessageSkipButton = function(pressed) {
        return this.isTriggeredButton(this._skipButton, pressed);
    };

    Window_Message.prototype.isTriggeredMessageAuto = function() {
        return Input.isTriggered('messageAuto') ||
            Input.isTriggered(autoKeyName) ||
            this.isTriggeredMessageAutoButton();
    };

    Window_Message.prototype.isTriggeredMessageAutoButton = function() {
        return this.isTriggeredButton(this._autoButton, false);
    };

    Window_Message.prototype.isTriggeredMessageSwitchButton = function() {
        return this.isTriggeredButton(this._switchButton, false);
    };

    Window_Message.prototype.isTriggeredButton = function(button, pressed) {
        if (!button) {
            return false;
        }
        var x = this.canvasToLocalX(TouchInput.x);
        var y = this.canvasToLocalY(TouchInput.y);
        return button.isTriggered(x, y, pressed);
    };

    var _Window_Message_isTriggered      = Window_Message.prototype.isTriggered;
    Window_Message.prototype.isTriggered = function() {
        if (this.isTriggeredAnyButton()) {
            return false;
        }
        if (this.messageAuto() && this._messageAutoCount <= 0) {
            if (!AudioManager.isExistVoice()) {
                this.initializeMessageAutoCount();
                return true;
            }
        }
        return _Window_Message_isTriggered.apply(this, arguments) || this.messageSkip();
    };

    Window_Message.prototype.isTriggeredAnyButton = function() {
        return this.isTriggeredMessageSkipButton() ||
            this.isTriggeredMessageAutoButton() ||
            this.isTriggeredMessageSwitchButton();
    };

    var _Window_Message_startPause      = Window_Message.prototype.startPause;
    Window_Message.prototype.startPause = function() {
        _Window_Message_startPause.apply(this, arguments);
        if (this.messageSkip()) this.startWait(2);
    };

    AudioManager.isExistVoice = function() {
        if (!AudioManager._voiceBuffers) {
            return false;
        }
        this.filterPlayingVoice();
        return this._voiceBuffers.some(function(buffer) {
            return !buffer._sourceNode.loop;
        });
    }

    //=============================================================================
    // Sprite_MessageButton
    //  メッセージボタン描画用スプライトです。
    //=============================================================================
    Sprite_MessageButton.prototype             = Object.create(Sprite.prototype);
    Sprite_MessageButton.prototype.constructor = Sprite_MessageButton;

    Sprite_MessageButton.prototype.initialize = function(fileName) {
        Sprite.prototype.initialize.call(this);
        this.bitmap   = ImageManager.loadPicture(fileName);
        this.anchor.x = 0.5;
        this.anchor.y = 0.5;
        this.visible  = false;
    };

    Sprite_MessageButton.prototype.update = function() {
        Sprite.prototype.update.call(this);
        this.updateOpacity();
        this.updateVisibility();
    };

    Sprite_MessageButton.prototype.updateOpacity = function() {
        this.opacity = this.parent.openness;
    };

    Sprite_MessageButton.prototype.updateVisibility = function() {
        if (paramInvalidSwitchId > 0 && $gameSwitches.value(paramInvalidSwitchId)) {
            this.visible = false;
            return;
        }
        this.visible = (!paramPictureSwitchId || $gameSwitches.value(paramPictureSwitchId));
    };

    Sprite_MessageButton.prototype.isTriggered = function(targetX, targetY, pressed) {
        var realX       = targetX + this._frame.width * this.anchor.x;
        var realY       = targetY + this._frame.height * this.anchor.y;
        var triggeredOk = (pressed ? TouchInput.isPressed() : TouchInput.isTriggered());
        return triggeredOk && this.isInSprite(realX, realY);
    };

    Sprite_MessageButton.prototype.isInSprite = function(targetX, targetY) {
        return this.x <= targetX && this.x + this._frame.width >= targetX &&
            this.y <= targetY && this.y + this._frame.height >= targetY;
    };

    //=============================================================================
    // Sprite_Frame
    //  アイコン描画用スプライトです。
    //=============================================================================
    Sprite_Frame.prototype             = Object.create(Sprite.prototype);
    Sprite_Frame.prototype.constructor = Sprite_Frame;

    Sprite_Frame.prototype.initialize = function(bitmap, index) {
        Sprite.prototype.initialize.call(this);
        bitmap.addLoadListener(function() {
            this._column = Math.floor(bitmap.width / Window_Base._iconWidth);
            this._row    = Math.floor(bitmap.height / Window_Base._iconHeight);
        }.bind(this));
        this.bitmap      = bitmap;
        this.anchor.x    = 0.5;
        this.anchor.y    = 0.5;
        this.flash       = false;
        this.flashSpeed  = 2;
        this._flashAlpha = 0;
        this.refresh(index ? index : 0);
    };

    Sprite_Frame.prototype.refresh = function(index) {
        if (!this.bitmap.isReady()) return;
        var w = Window_Base._iconWidth;
        var h = Window_Base._iconHeight;
        this.setFrame((index % this._column) * w, Math.floor(index / this._column) * h, w, h);
    };

    Sprite_Frame.prototype.update = function() {
        if (this.flash) {
            if (this._flashAlpha <= -64) this._flashAlpha = 192;
            this.setBlendColor([255, 255, 255, this._flashAlpha]);
            this._flashAlpha -= this.flashSpeed;
        }
    };
})();


code:
//=============================================================================
// MessageSpeedCustomize.js
// ----------------------------------------------------------------------------
// (C)2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.3.0 2019/12/27 瞬間表示の利用可否をゲーム中にスイッチで変更できるようにしました
// 1.2.3 2018/11/28 BugFixWaitOfTextEnd.jsと組み合わせたとき、末尾の動作がおかしくなる問題を修正
// 1.2.2 2018/07/22 瞬間表示機能が有効なとき、\!を使用すると以後のメッセージまで瞬間表示されてしまう問題を修正
// 1.2.1 2017/12/30 パラメータの型指定機能に対応し、ヘルプの記述を修正
// 1.2.0 2016/11/05 ノベルゲーム総合プラグインから、メッセージ表示速度を調整する制御文字を流用
// 1.1.2 2016/07/24 複数行「\>」が指定されている場合もデフォルトと同じ動作をするよう修正
// 1.1.1 2016/07/23 制御文字「\>\<」が指定されている場合、そちらを優先するよう修正
// 1.1.0 2016/07/12 文章の表示中に決定キーもしくは左クリックで文章を瞬間表示する機能を追加
// 1.0.0 2016/04/12 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc Message speed customize
 * @author triacontane
 *
 * @param VariableSpeed
 * @desc Variable number of Message speed
 * @default 1
 * @type variable
 *
 * @param RapidShowSwitch
 * @desc Rapid show if triggered(ON/OFF)
 * @default 0
 * @type switch
 *
 * @help Customize for message speed
 * 0    : Rapid
 * 1    : Normal
 * 2... : Slowly
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc メッセージ速度調整プラグイン
 * @author トリアコンタン
 *
 * @param 表示速度変数
 * @desc メッセージ表示速度を格納する変数の番号
 * @default 1
 * @type variable
 *
 * @param 瞬間表示スイッチ
 * @desc 指定した番号のスイッチがONになっているとき、文章の表示中に決定ボタンや左クリックで文章を瞬間表示します。
 * @default 0
 * @type switch
 *
 * @help メッセージ表示速度を調整します。
 * パラメータで指定した番号の変数に対して以下の値を代入してください。
 * 0     : 瞬間表示
 * 1     : 通常と同様の表示速度
 * 2以上 : 指定したフレーム間隔で一文字を表示します。
 *
 * ※ パラメータで指定するのは表示速度自体ではなく
 * 表示速度を取得する変数の値です。
 * 変数値が大きければ大きいほどゆっくりと表示されます。
 *
 * ※ 公開中の「オプション任意項目作成プラグイン」と組み合わせれば
 * 対象の変数をオプション画面から操作できます。
 * https://raw.githubusercontent.com/triacontane/RPGMakerMV/master/CustomizeConfigItem.js
 *
 * 制御文字「\ms[n]」を利用すると、そのメッセージ中のみ表示速度を
 * 任意の値に設定することができます。一時的にメッセージ表示速度を変更したい場合に
 * 有効です。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

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

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

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

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var paramVariableSpeed   = getParamNumber(['VariableSpeed', '表示速度変数'], 1, 5000);
    var paramRapidShowSwitch = getParamNumber(['RapidShowSwitch', '瞬間表示スイッチ'], 1, 5000);

    //=============================================================================
    // Window_Message
    //  メッセージの表示間隔を調整します。
    //=============================================================================
    var _Window_Message_clearFlags      = Window_Message.prototype.clearFlags;
    Window_Message.prototype.clearFlags = function() {
        _Window_Message_clearFlags.apply(this, arguments);
        this._tempMessageSpeed = null;
        this._showAll = false;
    };

    var _Window_Message_updateWait = Window_Message.prototype.updateWait;
    Window_Message.prototype.updateWait = function() {
        if ($gameSwitches.value(paramRapidShowSwitch) && this._textState &&
            this.isTriggered() && !this.pause) {
            this._showAll = true;
        }
        return _Window_Message_updateWait.apply(this, arguments);
    };

    var _Window_Message_updateMessage = Window_Message.prototype.updateMessage;
    Window_Message.prototype.updateMessage = function() {
        var speed = this.getMessageSpeed();
        if (this._textState && !this._lineShowFast) {
            if (speed <= 0 || this._showAll) {
                this._showFast = true;
            } else if (!this.isEndOfText(this._textState)) {
                this._waitCount = speed - 1;
            }
        }
        return _Window_Message_updateMessage.apply(this, arguments);
    };

    var _Window_Message_startPause = Window_Message.prototype.startPause;
    Window_Message.prototype.startPause = function() {
        _Window_Message_startPause.apply(this, arguments);
        this._showAll = false;
    };

    Window_Message.prototype.getMessageSpeed = function() {
        return this._tempMessageSpeed !== null ? this._tempMessageSpeed : $gameVariables.value(paramVariableSpeed);
    };

    Window_Message.prototype.setTempMessageSpeed = function(speed) {
        if (speed >= 0) {
            this._tempMessageSpeed = speed;
            if (speed > 0) this._showFast = false;
        } else {
            this._tempMessageSpeed = null;
        }
    };

    var _Window_Message_processEscapeCharacter = Window_Message.prototype.processEscapeCharacter;
    Window_Message.prototype.processEscapeCharacter = function(code, textState) {
        if (code === '>') this._waitCount = 0;
        switch (code) {
            case 'MS':
                this.setTempMessageSpeed(this.obtainEscapeParam(textState));
                break;
            default:
                _Window_Message_processEscapeCharacter.apply(this, arguments);
        }
    };
})();


code:
//=============================================================================
// MessageTriggerSe.js
// ----------------------------------------------------------------------------
// (C)2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.2.1 2020/03/06 ページ送りSEを演奏後すぐに通常のSEを演奏すると、SEの停止で当該SEが停止されない問題を修正
// 1.2.0 2018/06/22 メッセージに続きがある場合のみ効果音を演奏する設定を追加
// 1.1.0 2017/12/06 効果音の音量、ピッチ、左右バランスを後から変更できる機能を追加
// 1.0.0 2017/12/05 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc メッセージ送りSEプラグイン
 * @author トリアコンタン
 *
 * @param validateSwitchId
 * @text 有効スイッチID
 * @desc プラグインの機能が有効になるスイッチ番号です。0を指定すると常に有効となります。
 * @default 0
 * @type switch
 *
 * @param soundEffect
 * @text 効果音
 * @desc ページ送り時に演奏される効果音情報です。
 * @default
 * @type struct<SE>
 *
 * @param doseContinueOnly
 * @text 続きがある場合のみ
 * @desc メッセージに続きがある場合のみメッセージ送りSEを演奏します。
 * @default false
 * @type boolean
 *
 * @help MessageTriggerSe.js
 *
 * メッセージ送りの際に指定された効果音を演奏します。
 * 「\!」による待機や「\^」によるスキップ時も演奏されます。
 *
 * ・スクリプト詳細
 * ページ送り効果音を以下の通りに変更します。
 * 指定しなかった項目は変更されません。
 *  名称         : Book2
 *  音量         : 90
 *  ピッチ       : 100
 *  左右バランス : 0
 *
 * $gameSystem.setMessageTriggerSe('Book2', 90, 100, 0);
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~SE:
 * @param name
 * @desc SEのファイル名称です。
 * @default Book1
 * @require 1
 * @dir audio/se/
 * @type file
 *
 * @param volume
 * @desc SEのボリュームです。
 * @default 90
 * @type number
 * @min 0
 * @max 100
 *
 * @param pitch
 * @desc SEのピッチです。
 * @default 100
 * @type number
 * @min 50
 * @max 150
 *
 * @param pan
 * @desc SEの左右バランスです。
 * @default 0
 * @type number
 * @min -100
 * @max 100
 */

(function() {
    'use strict';

    //=============================================================================
    // ローカル関数
    //  プラグインパラメータやプラグインコマンドパラメータの整形やチェックをします
    //=============================================================================
    /**
     * 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('MessageTriggerSe');

    //=============================================================================
    // Game_System
    //  メッセージ送りSEを保持します。
    //=============================================================================
    Game_System.prototype.initMessageTriggerSeIfNeed = function() {
        if (!this._messageTriggerSe) {
            this._messageTriggerSe = this.createMessageTriggerSe();
        }
    };

    Game_System.prototype.createMessageTriggerSe = function() {
        var se    = param.soundEffect;
        se.volume = parseInt(se.volume);
        se.pitch  = parseInt(se.pitch);
        se.pan    = parseInt(se.pan);
        return se;
    };

    Game_System.prototype.getMessageTriggerSe = function() {
        this.initMessageTriggerSeIfNeed();
        return this._messageTriggerSe;
    };

    Game_System.prototype.setMessageTriggerSe = function(name, volume, pitch, pan) {
        this.initMessageTriggerSeIfNeed();
        if (name || name === '') {
            this._messageTriggerSe.name = name;
        }
        if (volume || volume === 0) {
            this._messageTriggerSe.volume = volume;
        }
        if (pitch || pitch === 0) {
            this._messageTriggerSe.pitch = pitch;
        }
        if (pan || pan === 0) {
            this._messageTriggerSe.pan = pan;
        }
    };

    //=============================================================================
    // Window_Message
    //  メッセージ送りSEを演奏します。
    //=============================================================================
    var _Window_Message_updateInput      = Window_Message.prototype.updateInput;
    Window_Message.prototype.updateInput = function() {
        var wasPause = this.pause;
        var input = _Window_Message_updateInput.apply(this, arguments);
        if (wasPause && !this.pause) {
            if (this.doesContinue()) {
                this.playMessageTriggerSe();
            } else {
                this._needMessageSe = true;
            }
        }
        return input;
    };

    var _Window_Message_terminateMessage = Window_Message.prototype.terminateMessage;
    Window_Message.prototype.terminateMessage = function() {
        if (this._pauseSkip) {
            this._needMessageSe = true;
        }
        _Window_Message_terminateMessage.apply(this, arguments);
    };

    var _Window_Message_checkToNotClose = Window_Message.prototype.checkToNotClose;
    Window_Message.prototype.checkToNotClose = function() {
        if (this.isClosing() && this.isOpen() && this._needMessageSe) {
            if (this.doesContinue() || !param.doseContinueOnly) {
                this.playMessageTriggerSe();
            }
            this._needMessageSe = false;
        }
        _Window_Message_checkToNotClose.apply(this, arguments);
    };

    Window_Message.prototype.playMessageTriggerSe = function() {
        if (this.isValidMessageTriggerSe()) {
            AudioManager.playStaticSe($gameSystem.getMessageTriggerSe());
        }
    };

    Window_Message.prototype.isValidMessageTriggerSe = function() {
        return param.validateSwitchId === 0 || $gameSwitches.value(param.validateSwitchId);
    };
})();


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
 *
 * @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 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('MessageWindowHidden');

    //=============================================================================
    // 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();
            }
        }
        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;
    };

    Window_Message.prototype.showAllWindow = function() {
        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;
    };

    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;
        }
        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);
            }
        });
    };

    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);
    };
})();


code:
//===========================================================================
// MpiCallMapEvent.js
//===========================================================================

/*:
 * @plugindesc プラグインコマンドでマップイベントを呼び出します。
 * @author 奏ねこま（おとぶき ねこま）
 *
 * @param Plugin Command
 * @desc プラグインコマンド名を任意のコマンド名に変更できます。
 * @default CallMapEvent
 *
 * @help
 * [使用方法]
 *  プラグインコマンドにて、以下のようにコマンドを指定してください。
 *
 *   CallMapEvent 数字
 *   CallMapEvent 文字列
 *   CallMapEvent \v[変数番号]
 *
 * [使用例] 引数に数字を指定した場合
 *
 *   CallMapEvent 2
 *
 *  ID:002のイベントを呼び出します。（同マップ内のイベント）
 *
 * [使用例] 引数に文字列を指定した場合
 *
 *   CallMapEvent ABC
 *
 *  メモ欄に「<ABC>」と書かれたイベントを呼び出します。（同マップ内のイベント）
 *
 * [使用例] 引数に変数を指定した場合
 *
 *   CallMapEvent \v[3]
 *
 *  変数#0003番の値を引数として、プラグインコマンドを実行します。
 *  変数の値が数字であれば「引数に数字を指定した場合」の挙動となり、
 *  変数の値が文字列であれば「引数に文字列を指定した場合」の挙動となります。
 *
 * [利用規約] ..................................................................
 *  - 本プラグインの利用は、RPGツクールMV/RPGMakerMVの正規ユーザーに限られます。
 *  - 商用、非商用、有償、無償、一般向け、成人向けを問わず、利用可能です。
 *  - 利用の際、連絡や報告は必要ありません。また、製作者名の記載等も不要です。
 *  - プラグインを導入した作品に同梱する形以外での再配布、転載はご遠慮ください。
 *  - 本プラグインにより生じたいかなる問題についても、一切の責任を負いかねます。
 * [改訂履歴] ..................................................................
 *   Version 1.00  2017/06/10  First edition.
 * -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 *  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 = 'MpiCallMapEvent';

    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 Methods
    //==============================================================================

    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;
    }

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

    (function(o,p){
        var f=o[p];o[p]=function(command, args){
            f.apply(this,arguments);
            if (command === $mpi.plugin_command) {
                var tag = convertVariables(args[0]);
                var id = +tag;
                console.log(tag);
                if (id) {
                    this.setupChild($gameMap._events[id].list(), this._eventId);
                } else {
                    $gameMap._events.some(function(event) {
                        if (event && event.event().meta[tag]) {
                            this.setupChild(event.list(), this._eventId);
                            return true;
                        }
                    }, this);
                }
            }
        };
    }(Game_Interpreter.prototype,'pluginCommand'));
}());