code:
//=============================================================================
// TDDP_FluidTimestep
// Version: 1.0.2
//=============================================================================
var Imported = Imported || {};
Imported.TDDP_FluidTimestep = "1.0.2";
/*:
 * @plugindesc 1.0.2 Fixes MV's framerate dependent timestepping. Makes the gamespeed the same regardless of framerate.
 * @author Tor Damian Design / Galenmereth
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Information
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * For updates and easy to use documentation, please go to the plugin's website:
 * http://mvplugins.tordamian.com/?p=437
 *
 * This plugin replaces MV's update loop with a semi-fixed timestep solution based
 * on http://gafferongames.com/game-physics/fix-your-timestep/
 *
 * This makes the game run at normal speed (animation, movement, and anything else)
 * regardless of framerate. By default, MV run on a 144hz monitor would run at
 * 144fps and everything would move at 2,4 times normal speed. Likewise, if
 * someone ran the game and only managed 30fps, everything would move at half
 * normal speed.
 *
 * This solution decouples visual updates from logic updates so that the latter
 * always occur at 60 times per second, while frames get updated as fast as the
 * user's computer can display it.
 *
 * There you can also download a PDF of the documentation for offline use, and
 * having the documentation in one cleanly presented place means you can always
 * be sure it's the most recent available.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This plugin is free for both non-commercial and commercial use. Please see
 * http://mvplugins.tordamian.com/terms-of-use for the full terms of use.
 */

(function () {
    /**
    * Get current world time in ms
    *
    * @method getTimeInMs()
    */
    SceneManager.getTimeInMs = function () {
        return performance.now();
    };

    /**
    * This is the passed logic update time, useful for other plugins
    *
    * @var _t
    */
    SceneManager._t = 0.0;

    /**
    * The delta time for logic updates, set to 1/60th of a second. Since MV bases all
    * its logic on a 60fps frame update, this is the best solution.
    *
    * @var _dt
    */
    SceneManager._dt = 1.0 / 60.0;

    /**
    * The current time in milliseconds
    *
    * @var _currentTime
    */
    SceneManager._currentTime = SceneManager.getTimeInMs();

    /**
    * The frame accumulator, for when the framerate is faster than the logic should update
    *
    * @var _accumulator
    */
    SceneManager._accumulator = 0.0;

    /**
    * CHANGED The frame update
    */
    SceneManager.update = function () {
        try {
            this.tickStart();
            // this.updateInputData(); REMOVED - We need to fetch input on scene update instead, in the new rewritten updateMain()
            this.updateMain();
            this.tickEnd();
        } catch (e) {
            this.catchException(e);
        }
    };

    /**
    * CHANGED The main update function
    */
    SceneManager.updateMain = function () {

        var newTime = this.getTimeInMs();
        var frameTime = (newTime - this._currentTime) / 1000;
        if (frameTime > 0.25) frameTime = 0.25;
        this._currentTime = newTime;

        this._accumulator += frameTime;

        while (this._accumulator >= this._dt) {
            this.updateInputData(); // While the frame accumulator is greater than the logic update delta, we keep updating the game's logic and catching input
            this.changeScene();
            this.updateScene();
            this._accumulator -= this._dt;
            this._t += this._dt;
        }

        this.renderScene();
        this.requestUpdate();
    }
})();


code:
//=============================================================================
// TDDP_ManageDashing
// Version: 1.0.0
//=============================================================================
/*:
 * @plugindesc 1.0.0 Lets you manage the dashing mode in your game with simple plugin options.
 * @author Tor Damian Design / Galenmereth
 *
 * @param Disable Auto-dash
 * @desc If set to true this disables touch and mouse input to cause auto-dashing behavior. Can still use dash button.
 * @default false
 *
 * @param Disable Dashing
 * @desc If set to true this disables dashing in the game. This will also remove the "Always Dash" game option.
 * @default false
 *
 * @param Remove Dash Option
 * @desc If set to true this removes the "Always Dash" option from the game's options.
 * @default false
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Information
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP_ManageDashing lets you manage the dashing mode in your game with simple
 * plugin options.
 *
 * For updates and easy to use documentation, please go to the plugin's website:
 * http://mvplugins.tordamian.com/plugins/manage-dashing/
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Changelog:
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  1.0.0  Stable initial release.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This plugin is free for both non-commercial and commercial use. Please see
 * http://mvplugins.tordamian.com/terms-of-use for the full terms of use.
 */
/*:ja
 * @plugindesc ゲーム内でのダッシュモードの利用が可能になります。
 * @author Tor Damian Design / Galenmereth
 *
 * @param Disable Auto-dash
 * @desc trueにすることで、タッチおよびマウスのインプットを無効化し、
 * オートダッシュが発動します。ダッシュボタンの利用も可能です。
 * @default false
 *
 * @param Disable Dashing
 * @desc trueにすることで、ダッシュを無効化します。
 * 同時に、「常時ダッシュ」のオプションを削除します。
 * @default false
 *
 * @param Remove Dash Option
 * @desc trueにすることで、「常時ダッシュ」のオプションをゲームから削除します。
 * @default false
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Information
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP_ManageDashingはシンプルなオプションによって、
 * ゲーム内でのダッシュモードを可能にするプラグインです。
 *
 * アップデートと簡易使用方法については、
 * こちらのプラグインのサイトを参照してください。
 * http://mvplugins.tordamian.com/plugins/manage-dashing/
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Changelog:
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  1.0.0  Stable initial release.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * このプラグインは、商用利用・非商用利用どちらにもフリーで公開されています。
 * 使用方法の全文についてはこちらのサイトを確認してください。
 * http://mvplugins.tordamian.com/terms-of-use
 */
var Imported = Imported || {};
Imported.TDDP_ManageDashing = "1.0.0";

var TDDP_ManageDashing = {};
(function () {
    "use strict";
    var parameters = PluginManager.parameters('TDDP_ManageDashing');
    TDDP_ManageDashing.disableAutoDash = Boolean(parameters['Disable Auto-dash'] === 'true' || false);
    TDDP_ManageDashing.disableDashing = Boolean(parameters['Disable Dashing'] === 'true' || false);
    TDDP_ManageDashing.removeDashOption = Boolean(parameters['Remove Dash Option'] === 'true' || false);
    /**
    * Whether Always Dash option should be shown
    */
    TDDP_ManageDashing.showDashOption = function () {
        if (this.disableDashing || this.removeDashOption) return false;
        return true;
    }
    /**
    * Extended check for dashing based on plugin parameters
    */
    TDDP_ManageDashing.dashing = function (gamePlayer) {
        if (this.disableDashing) return false;
        if (this.disableAutoDash) {
            return gamePlayer.isDashButtonPressed();
        } else {
            // Default behavior
            return (gamePlayer.isDashButtonPressed() || $gameTemp.isDestinationValid());
        }
    }
    /**
    * Add check to see if Dash option should be removed
    */
    Window_Options.prototype.addGeneralOptions = function () {
        if (TDDP_ManageDashing.showDashOption()) this.addCommand(TextManager.alwaysDash, 'alwaysDash');
        this.addCommand(TextManager.commandRemember, 'commandRemember');
    };
    /**
    * Alter functionality so that touch input doesn't force auto dash
    */
    Game_Player.prototype.updateDashing = function () {
        if (this.isMoving()) {
            return;
        }
        if (this.canMove() && !this.isInVehicle() && !$gameMap.isDashDisabled()) {
            this._dashing = TDDP_ManageDashing.dashing(this);
        } else {
            this._dashing = false;
        }
    };
    /**
    * Extend with a check to see if the Always Dash option is available
    */
    Game_Player.prototype.isDashButtonPressed = function () {
        var shift = Input.isPressed('shift');
        // If Dash option is removed, don't respect Always Dash option settings.
        if (ConfigManager.alwaysDash && TDDP_ManageDashing.showDashOption()) {
            return !shift;
        } else {
            return shift;
        }
    };
})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// TDDP_MouseSystemEx.js
//=============================================================================

var Imported = Imported || {};
Imported.TDDP_MouseSystemEx = "1.8.2";

//=============================================================================
/*:
 * @plugindesc 1.8.2 Custom mouse cursors, highlight menu items on hover, custom event mouse interaction and much more! See Help.                      id:TDDP_MouseSystemEx
 *
 * @author Tor Damian Design / Galenmereth
 *
 * @param ---Custom Cursor---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Use Custom Cursor?
 * @desc Whether you want to use a custom mouse cursor image.
 * true => ON       false => OFF
 * @default false
 *
 * @param Custom Cursor Image
 * @desc The filename for the custom cursor. It looks for this in your project's Custom Cursor Folder.
 * @default default.png
 *
 * @param Custom Cursors Folder
 * @desc The folder you wish to store the custom cursors in. Must end with a forward slash. Default: img/cursors/
 * @default img/cursors/
 *
 * @param ---Auto Change Cursors---
 * @desc Options for automatically changing the mouse cursor when hovering over events with the given event commands in them.
 * @default
 *
 * @param Show Text Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Show Text commands in them.
 *
 * @param Transfer Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Transfer Player commands in them.
 *
 * @param Change Gold Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Gold commands in them.
 *
 * @param Change Items Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Items commands in them.
 *
 * @param Change Weapons Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Weapons commands in them.
 *
 * @param Change Armors Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Armors commands in them.
 *
 * @param Battle Processing Cursor
 * @desc Automatically show this cursor when hovering over events with Battle Processing commands in them.
 *
 * @param ---Auto Change Icons---
 * @desc Options for automatically showing an icon when hovering over events with the given event commands in them.
 * @default
 *
 * @param Show Text Icon
 * @desc Automatically show this icon when hovering over events with Show Text commands in them.
 *
 * @param Transfer Icon
 * @desc Automatically show this icon when hovering over events with Transfer Player commands in them.
 *
 * @param Change Gold Icon
 * @desc Automatically show this icon when hovering over events with Change Gold commands in them.
 *
 * @param Change Items Icon
 * @desc Automatically show this icon when hovering over events with Change Items commands in them.
 *
 * @param Change Weapons Icon
 * @desc Automatically show this icon when hovering over events with Change Weapons commands in them.
 *
 * @param Change Armors Icon
 * @desc Automatically show this icon when hovering over events with Change Armors commands in them.
 *
 * @param Battle Processing Icon
 * @desc Automatically show this icon when hovering over events with Battle Processing commands in them.
 *
 * @param ---Hover Select---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Highlight On Hover
 * @desc Highlight menu items when hovering over them with the mouse.
 * true => ON       false => OFF
 * @default false
 *
 * @param Hover SE Cooldown
 * @desc Audio cooldown (in frames) between playing Cursor SE when Highlight On Hover is set to true. Default 4.
 * @default 4
 *
 * @param ---Customizeable Notetags---
 * @desc These are options for activating events by mouse interaction instead of player character.
 * @default
 *
 * @param No Auto Cursor Notetag
 * @desc The notetag used to disable auto cursor switching on this event or event page.
 * @default no_auto_cursor!
 *
 * @param No Auto Icon Notetag
 * @desc The notetag used to disable auto icon switching on this event or event page.
 * @default no_auto_icon!
 *
 * @param Click Notetag
 * @desc The notetag used to trigger the event when it is clicked on.
 * Default: click_activate!
 * @default click_activate!
 *
 * @param Hover Notetag
 * @desc The notetag used to trigger the event when the mouse is over it.
 * Default: hover_activate!
 * @default hover_activate!
 *
 * @param Leave Notetag
 * @desc The notetag used to trigger the event when the mouse leaves it.
 * Default: leave_activate!
 * @default leave_activate!
 *
 * @param ---Mouse Icons---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Hide Cursor
 * @desc Hide the default mouse cursor when an icon is shown.
 * true => ON       false => OFF
 * @default false
 *
 * @param Icon Offset X
 * @desc The icon's offset from the mouse horizontally.
 * Default: 9
 * @default 9
 *
 * @param Icon Offset Y
 * @desc The icon's offset from the mouse vertically.
 * Default: 14
 * @default 14
 *
 * @param ---Mouse Icon Tags---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Icon Tag 1
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default quest: 191
 *
 * @param Icon Tag 2
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default chest: 210
 *
 * @param Icon Tag 3
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default door: 106
 *
 * @param Icon Tag 4
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default world_map: 190
 *
 * @param Icon Tag 5
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default potion: 176
 *
 * @param Icon Tag 6
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default poison: 177
 *
 * @param Icon Tag 7
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default four_leaf_clover: 182
 *
 * @param Icon Tag 8
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default notebook: 187
 *
 * @param Icon Tag 9
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default letter: 192
 *
 * @param Icon Tag 10
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 11
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 12
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 13
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 14
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 15
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Information
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP - MouseSystem is a collection of methods for modifying mouse-based
 * interaction in your games. You can set custom mouse cursors, show icons beside
 * the mouse when hovering over events, activate events by mouse, and more.
 *
 * For updates and easy to use documentation, please go to the plugin's website:
 * http://mvplugins.tordamian.com/?p=26
 *
 * There you can also download a PDF of the documentation for offline use, and
 * having the documentation in one cleanly presented place means you can always
 * be sure it's the most recent available.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This plugin is free for both non-commercial and commercial use. Please see
 * http://mvplugins.tordamian.com/terms-of-use for the full terms of use.
 *
 * A big thank you to Degica for making this plugin free for commercial use for
 * everyone!
 */
/*:ja
* @plugindesc ver 1.8.2 マウスカーソルのカスタム、メニューアイテムの
* ハイライトなどを行います。詳しくはHelpをご覧ください。
*
* @author Tor Damian Design / Galenmereth
*
* @param ---Custom Cursor---
* @desc カーソルをカスタムするオプションです。(見出しのため変更不要)
* @default
*
* @param Use Custom Cursor?
* @desc カスタムマウスカーソル画像を利用するかどうか選択します。
* true => ON       false => OFF
* @default false
*
* @param Custom Cursor Image
* @desc カスタムカーソルのファイル名です。プロジェクト内のカスタムカーソルフォルダで、このファイル名を探します。
* @default default.png
*
* @param Custom Cursors Folder
* @desc カスタムカーソルを入れておきたいフォルダです。「/」で終わるように設定してください。デフォルト設定: img/cursors/
* @default img/cursors/
*
* @param ---Auto Change Cursors---
* @desc イベントのマウスオーバー時に、自動的にカーソルを変更するオプションです。(見出しのため変更不要)
* @default
*
* @param Show Text Cursor
* @desc Show Textのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param Transfer Cursor
* @desc Transfer Playerのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param Change Gold Cursor
* @desc Change Goldのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param Change Items Cursor
* @desc Change Itemsのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param Change Weapons Cursor
* @desc Change Weaponsのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param Change Armors Cursor
* @desc Change Armorsのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param Battle Processing Cursor
* @desc Battle Processingのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
*
* @param ---Auto Change Icons---
* @desc イベントのマウスオーバー時に、自動的にアイコンを表示するオプションです。(見出しのため変更不要)
* @default
*
* @param Show Text Icon
* @desc Show Textのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param Transfer Icon
* @desc Transfer Playerのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param Change Gold Icon
* @desc Change Goldのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param Change Items Icon
* @desc Change Itemsのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param Change Weapons Icon
* @desc Change Weaponsのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param Change Armors Icon
* @desc Change Armorsのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param Battle Processing Icon
* @desc Battle Processingのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
*
* @param ---Hover Select---
* @desc マウス移動時のエフェクトを設定するオプションです。(見出しのため変更不要)
* @default
*
* @param Highlight On Hover
* @desc マウスオーバー時にメニューアイテムをハイライトします。
* true => ON       false => OFF
* @default false
*
* @param Hover SE Cooldown
* @desc Highlight On HoverがONになっている状態で、オーディオの音量を下げます。デフォルト値=4
* @default 4
*
* @param ---Customizeable Notetags---
* @desc プレイヤーキャラクターの行動によってではなく、マウスインタラクションによってイベントを発動させるオプションです。
* @default
*
* @param No Auto Cursor Notetag
* @desc イベントもしくはイベントページ上で、オートカーソルスイッチを無効化するnotetagです。
* @default no_auto_cursor!
*
* @param No Auto Icon Notetag
* @desc イベントもしくはイベントページ上で、オートアイコンスイッチを無効化するnotetagです。
* @default no_auto_icon!
*
* @param Click Notetag
* @desc クリック時にイベントを発動させるnotetagです。
* Default: click_activate!
* @default click_activate!
*
* @param Hover Notetag
* @desc マウスオ―バー時にイベントを発動させるnotetagです。
* Default: hover_activate!
* @default hover_activate!
*
* @param Leave Notetag
* @desc マウスが離れた時にイベントを発動させるnotetagです。
* Default: leave_activate!
* @default leave_activate!
*
* @param ---Mouse Icons---
* @desc マウスアイコンにまつわるオプションです。(見出しのため変更不要)
* @default
*
* @param Hide Cursor
* @desc アイコン表示時に、デフォルトのマウスカーソルを隠すオプションです。
* true => ON       false => OFF
* @default false
*
* @param Icon Offset X
* @desc マウスからアイコンの距離を設定します。(X軸)
* Default: 9
* @default 9
*
* @param Icon Offset Y
* @desc マウスからアイコンの距離を設定します。(Y軸)
* Default: 14
* @default 14
*
* @param ---Mouse Icon Tags---
* @desc マウスアイコンにまつわるタグです。(見出しのため変更不要)
* @default
*
* @param Icon Tag 1
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default quest: 191
*
* @param Icon Tag 2
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default chest: 210
*
* @param Icon Tag 3
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default door: 106
*
* @param Icon Tag 4
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default world_map: 190
*
* @param Icon Tag 5
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default potion: 176
*
* @param Icon Tag 6
* @desc Mouse Hover Iconsnotetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default poison: 177
*
* @param Icon Tag 7
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default four_leaf_clover: 182
*
* @param Icon Tag 8
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default notebook: 187
*
* @param Icon Tag 9
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default letter: 192
*
* @param Icon Tag 10
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default key: 195
*
* @param Icon Tag 11
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default key: 195
*
* @param Icon Tag 12
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default key: 195
*
* @param Icon Tag 13
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default key: 195
*
* @param Icon Tag 14
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default key: 195
*
* @param Icon Tag 15
* @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
* @default key: 195
*
* @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
* Information
* =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
* TDDP - MouseSystemは、ゲーム内でのマウスを用いた
* 様々なアクションを可能にするプラグインです。
* マウスカーソル自体のカスタマイズや、イベントマウスオーバー時のアイコン表示、
* マウスでのイベントの発動などを行なうことができます。
*
* アップデートと簡易使用方法については、
* こちらのプラグインのサイトを参照してください。
* http://mvplugins.tordamian.com/?p=26
* このサイトでは、オフラインで使用するためのPDFをダウンロードすることができます。
* またいつでも最新版の確認を行なうことができます。
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Terms & Conditions
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* このプラグインは、商用利用・非商用利用どちらにもフリーで公開されています。
* 使用方法の全文についてはこちらのサイトを確認してください。
* http://mvplugins.tordamian.com/terms-of-use
*
* 最後に、このプラグインのフリーでの商用利用を実現してくれた
* Degicaさんに感謝の意を表します。
*/
//=============================================================================
// All anonymous/helper functions are registered on this object for the convenience of other plugins.
var TDDP_MouseSystemEx = {};
(function ($) {
    "use strict";
    /**
    * Return .png if no file extension present in filename
    */
    $._ext = function (filename) {
        if (String(filename).split(".").length > 1) {
            return filename;
        } else {
            // Default filetype extension
            return filename + ".png";
        }
    }
    //=============================================================================
    // Setting up parameters
    //=============================================================================
    var parameters = $plugins.filter(function (p) { return p.description.contains("id:TDDP_MouseSystemEx") })[0].parameters;
    // Auto change cursors
    $.showTextCursor = String(parameters['Show Text Cursor']) || false;
    $.changeGoldCursor = String(parameters['Change Gold Cursor']) || false;
    $.changeItemCursor = String(parameters['Change Items Cursor']) || false;
    $.changeWeaponCursor = String(parameters['Change Weapons Cursor']) || false;
    $.changeArmorCursor = String(parameters['Change Armors Cursor']) || false;
    $.transferPlayerCursor = String(parameters['Transfer Cursor']) || false;
    $.battleProcessingCursor = String(parameters['Battle Processing Cursor']) || false;
    // Auto change icons
    $.showTextIcon = String(parameters['Show Text Icon']) || false;
    $.changeGoldIcon = String(parameters['Change Gold Icon']) || false;
    $.changeItemIcon = String(parameters['Change Items Icon']) || false;
    $.changeWeaponIcon = String(parameters['Change Weapons Icon']) || false;
    $.changeArmorIcon = String(parameters['Change Armors Icon']) || false;
    $.transferPlayerIcon = String(parameters['Transfer Icon']) || false;
    $.battleProcessingIcon = String(parameters['Battle Processing Icon']) || false;
    // Settings
    $.highlightOnHover = Boolean(parameters['Highlight On Hover'] === 'true' || false);
    $.audioCooldownOnHover = Number(parameters['Hover SE Cooldown'] || 4)
    $.hideCursor = Boolean(parameters['Hide Cursor'] === 'true' || false);
    $.iconOffsetX = Number(parameters['Icon Offset X']) || 0;
    $.iconOffsetY = Number(parameters['Icon Offset Y']) || 0;
    $.noAutoCursorNotetag = String(parameters['No Auto Cursor Notetag']);
    $.noAutoIconNotetag = String(parameters['No Auto Icon Notetag']);
    $.clickToActivateNote = String(parameters['Click Notetag']);
    $.hoverToActivateNote = String(parameters['Hover Notetag']);
    $.leaveToActivateNote = String(parameters['Leave Notetag']);
    $.useCustomCursor = Boolean(parameters['Use Custom Cursor?'] === 'true' || false);
    $.cursorImage = $._ext(String(parameters['Custom Cursor Image']));
    $.defaultCursorImage = $.cursorImage;
    $.customCursorPath = String(parameters['Custom Cursors Folder']);

    $._cursorFilenameInUse = null;   // Helper to compare changes
    $._lastUpdateFrame = 0;      // Last frame cursor got updated
    $._cssClassPrefix = "TDDP_customCursor_";
    $._indexFilename = "_index.json";

    // Add all mouse icon tags
    $.mouseIconTags = {}
    for (var i = 1; i <= 15; ++i) {
        var tag = parameters['Icon Tag ' + i]
        if (!tag) continue;
        tag = tag.split(":");
        var key = tag[0];
        var val = tag[1].replace(' ', '');
        $.mouseIconTags[key] = val;
    }
    /**
    * Load and setup the custom cursor CSS additions
    */
    $._loadAndSetupCustomCursorCSS = function () {
        var xhr = new XMLHttpRequest();
        var url = this.customCursorPath + this._indexFilename;
        xhr.open('GET', url);
        xhr.overrideMimeType('application/json');
        xhr.onload = function () {
            if (xhr.status < 400) {
                var dummyContainerElement = document.createElement('div');
                dummyContainerElement.id = "TDD_MS_CursorDummies";
                document.body.appendChild(dummyContainerElement);
                // Next we iterate the cached cursor list
                var classPrefix = this._cssClassPrefix;
                var cachedCursors = JSON.parse(xhr.responseText);
                for (var i = 0, max = cachedCursors.length; i < max; i++) {
                    var cursor = cachedCursors[i];
                    var cursorName = cursor.split(".")[0];
                    var ox = 0;
                    cursorName = cursorName.replace(/_x(\d*)/g, function (m, p1) {
                        if (p1) ox = p1;
                        return "";
                    });
                    var oy = 0;
                    cursorName = cursorName.replace(/_y(\d*)/, function (m, p1) {
                        if (p1) oy = p1;
                        return "";
                    });
                    var cursorPath = this.customCursorPath + cursor;
                    var sheet = window.document.styleSheets[0];
                    sheet.insertRule('.' + classPrefix + cursorName + ' { cursor: url(../' + cursorPath + ')' + ox + ' ' + oy + ', default; }', sheet.cssRules.length);
                    // To ensure all the cursors get prefetched by browsers, we create dummy divs to hold all the styles...
                    var dummyLoaderElement = document.createElement('div');
                    dummyLoaderElement.id = cursorName + "_dummy";
                    dummyContainerElement.appendChild(dummyLoaderElement);
                    dummyLoaderElement.className = classPrefix + cursorName;
                }
            }
        }.bind(this);
        xhr.onerror = function () {
            //
        };
        xhr.send();
    }
    /**
    * Pre-cache all custom cursors when in test mode
    */
    // Check if playtest; if so, store file. If not, read stored
    $._precacheCustomCursors = function () {
        if (StorageManager.isLocalMode() && Utils.isOptionValid('test')) {
            var fs = require('fs');
            // Find that relative local path, using MV's own methods
            var path = window.location.pathname.replace(/\/[^\/]*$/, '/' + this.customCursorPath);
            if (path.match(/^\/([A-Z]\:)/)) {
                path = path.slice(1);
            }
            path = decodeURIComponent(path);
            // Check if cursors dir exists, make if not
            if (!fs.existsSync(path)) {
                alert('TDDP MouseSystemEx\nThe chosen cursor folder "' + this.customCursorPath + '" has been created for you. Please put any custom cursor image files in this folder.');
                fs.mkdirSync(path);
            }
            // Read dir
            var files = fs.readdirSync(path).filter(function (v) {
                if (v != this._indexFilename && v[1]) return v;
            }.bind(this));
            // Store in json
            fs.writeFile(path + this._indexFilename, JSON.stringify(files), 'utf8', this._loadAndSetupCustomCursorCSS.bind(this));
        } else {
            // Read stored file
            this._loadAndSetupCustomCursorCSS();
        }
    }.apply(TDDP_MouseSystemEx);
    //=============================================================================
    // Game_Interpreter - register plugin commands
    //=============================================================================
    /**
    * Alias and extend pluginCommand
    */
    var Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function (command, args) {
        Game_Interpreter_pluginCommand.call(this, command, args)
        if (command === 'SetCustomCursor') $._setCustomCursor(args[0]);
        if (command === 'ResetCustomCursor') $._resetCustomCursor();
    };
    //=============================================================================
    // Helper functions
    //=============================================================================
    /**
    * Get events at x and y coordinates. Separate function for compatibility
    *
    * @method _eventsXy
    * @param x {Number} Map X coordinate
    * @param y {Number} Map Y coordinate
    * @return {Array} of events at given coordinates
    */
    $._eventsXy = function (x, y) {
        return $gameMap.eventsXy(x, y);
    }
    /**
    * Show custom cursor
    */
    $._showCustomCursor = function (filename) {
        var filename = filename || this.cursorImage;
        document.body.className = this._cssClassPrefix + filename.split(".")[0];
    }
    /**
    * Set new default custom cursor
    */
    $._setCustomCursor = function (filename) {
        this.cursorImage = filename;
        this._showCustomCursor(TouchInput.cursorImage);
    }
    /**
    * Reset custom cursor to parameter setting defaults
    */
    $._resetCustomCursor = function () {
        this._setCustomCursor(this.defaultCursorImage);
    }
    /**
    * Show the mouse cursor
    */
    $._showMouseCursor = function () {
        if (this.useCustomCursor) {
            this._showCustomCursor();
        } else {
            document.body.style.cursor = 'inherit';
        }
    }
    /**
    * Hide the mouse cursor
    */
    $._hideMouseCursor = function () {
        document.body.style.cursor = 'none';
    }
    /**
    * Return Comments from event page. Multiline comments require an additional check (408)
    */
    $._filterComments = function (pageListObject) {
        var comments = (pageListObject.code == 108 || pageListObject.code == 408) ? true : false;
        return comments;
    }
    /**
    * Return Show Text messages from event page
    */
    $._filterMessages = function (pageListObject) {
        return pageListObject.code == 401;
    }
    /**
    * Return Transfer Player events from event page
    */
    $._filterTransferPlayer = function (pageListObject) {
        return pageListObject.code == 201;
    }
    /**
    * Return Battle Processing events from event page
    */
    $._filterBattleProcess = function (pageListObject) {
        return pageListObject.code == 301;
    }
    /**
    * Return Change Gold events from event page
    */
    $._filterChangeGold = function (pageListObject) {
        return pageListObject.code == 125;
    }
    /**
    * Return Change Items events from event page
    */
    $._filterChangeItems = function (pageListObject) {
        return pageListObject.code == 126;
    }
    /**
    * Return Change Weapons events from event page
    */
    $._filterChangeWeapons = function (pageListObject) {
        return pageListObject.code == 127;
    }
    /**
    * Return Change Armors events from event page
    */
    $._filterChangeArmors = function (pageListObject) {
        return pageListObject.code == 128;
    }
    /**
    * Check if current scene is of the type Scene_Map
    */
    $._isSceneMap = function () {
        return (SceneManager._scene instanceof Scene_Map);
    }
    /**
    * Find a given notetag either in a game_event's Note box or Comment box on current active page
    */
    $._findInEventNotetags = function (game_event, notetag, onMatch) {
        if (!game_event.page()) return false;
        var comments = game_event.page().list.filter(this._filterComments);
        var result = null;
        var foundMatch = false;
        var matchInString = function (string) {
            result = string.match(notetag);
            if (result !== null) {
                foundMatch = true;
            }
        }
        // First see if there's a relevant page comment, has higher priority
        if (comments.length > 0) {
            comments.forEach(function (comment) {
                if (foundMatch) return;
                matchInString(comment.parameters[0]);
            })
        }
        // If nothing found in page comment, check Note box
        if (!foundMatch) {
            if (game_event.event().note) {
                matchInString(game_event.event().note);
            }
        }
        if (foundMatch) { onMatch.call(game_event, result); }
    }
    /**
    * Arrays of pairs of cursors/icons and filters to run to check if they should be used
    */
    $.autoCursorFilters = [
        // The order is the priority; the first match stops further lookup
        [$.battleProcessingCursor, $._filterBattleProcess],
        [$.transferPlayerCursor, $._filterTransferPlayer],
        [$.changeGoldCursor, $._filterChangeGold],
        [$.changeItemCursor, $._filterChangeItems],
        [$.changeWeaponCursor, $._filterChangeWeapons],
        [$.changeArmorCursor, $._filterChangeArmors],
        [$.showTextCursor, $._filterMessages],
    ];
    $.autoIconFilters = [
        // The order is the priority; the first match stops further lookup
        [$.battleProcessingIcon, $._filterBattleProcess],
        [$.transferPlayerIcon, $._filterTransferPlayer],
        [$.changeGoldIcon, $._filterChangeGold],
        [$.changeItemIcon, $._filterChangeItems],
        [$.changeWeaponIcon, $._filterChangeWeapons],
        [$.changeArmorIcon, $._filterChangeArmors],
        [$.showTextIcon, $._filterMessages],
    ];
    /**
    * Function to check whether conditions are prime to check for events under the mouse
    */
    $.conditionsValidForMouseHoverCheck = function () {
        return (SceneManager.isCurrentSceneStarted() && this._isSceneMap() &&
            $gameMap !== null &&
            $dataMap !== null &&
            !$gameMap._interpreter.isRunning());
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // START - Highlight On Hover option
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if ($.highlightOnHover) {
        //=========================================================================
        // TouchInput modifications
        //=========================================================================
        /**
        * Removing the check for whether _mousePressed is active to facilitate hover events
        */
        TouchInput._onMouseMove = function (event) {
            var x = Graphics.pageToCanvasX(event.pageX);
            var y = Graphics.pageToCanvasY(event.pageY);
            this._onMove(x, y);
        };
        //=========================================================================
        // Window_Selectable modifications
        //=========================================================================
        /**
        * Aliased update function, adds processMouseMoved() call
        */
        var _Window_Selectable_update = Window_Selectable.prototype.update;
        Window_Selectable.prototype.update = function () {
            this.processMouseMoved();
            _Window_Selectable_update.call(this);
        };
        /**
        * Check if conditions are right for calling onTouch when using mouse movement (for hover activation)
        */
        Window_Selectable.prototype.processMouseMoved = function () {
            if (this.isOpenAndActive() && TouchInput.isMoved() && this.cursorIsWithinWindow()) {
                this.onTouch(false);
            }
        };
        /**
        * Check if cursor is within window
        */
        Window_Selectable.prototype.cursorIsWithinWindow = function () {
            var _x = this.canvasToLocalX(TouchInput.x);
            var _y = this.canvasToLocalY(TouchInput.y);
            if (_x > this.padding && _x <= this.width - this.padding) {
                if (_y > this.padding && _y < this.height - this.padding) {
                    return true;
                }
            }
            return false;
        }

        //=============================================================================
        // SoundManager modifications
        //=============================================================================
        /*
        * Static var to keep track of last played cursor SE frame
        */
        SoundManager._lastPlayCursorFrame = 0;
        /**
        * Aliased function to add check for whether playCursor should play, based on cooldown setting
        */
        var _SoundManager_playCursor = SoundManager.playCursor;
        SoundManager.playCursor = function () {
            var _canPlay = SoundManager._lastPlayCursorFrame > Graphics.frameCount
                || Graphics.frameCount > SoundManager._lastPlayCursorFrame + $.audioCooldownOnHover;

            if (_canPlay) {
                _SoundManager_playCursor.call(this);
                SoundManager._lastPlayCursorFrame = Graphics.frameCount;
            }
        };
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // END - Highlight On Hover option
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //=============================================================================
    // TouchInput modifications
    //=============================================================================
    /**
    * Alias and extend initialize() with _setupCursorIconObject()
    */
    var _TouchInput_initialize = TouchInput.initialize;
    TouchInput.initialize = function () {
        this._setupCursorIconObject();
        _TouchInput_initialize.call(this);
    };
    /**
    * Setup cursorIcon object
    */
    TouchInput._setupCursorIconObject = function () {
        this.cursorIcon = new Sprite();
        this.cursorIcon.drawIcon = Window_Base.prototype.drawIcon;
        this.cursorIcon.bitmap = new Bitmap(Window_Base._iconWidth, Window_Base._iconHeight);
        this.cursorIcon.contents = this.cursorIcon.bitmap;
        this.cursorIcon.iconIndex = null;
    }
    /**
    * Alias and extend _onMouseMove() to use new function _checkCursorStatus()
    */
    var _TouchInput_onMouseMove = TouchInput._onMouseMove;
    TouchInput._onMouseMove = function (event) {
        _TouchInput_onMouseMove.call(this, event);
        this._checkCursorStatus(event.pageX, event.pageY);
    };
    /**
    * Check cursor's status and whether to alter cursor
    * @method _checkCursorStatus
    * @param pageX {Number} Mouse page X coordinate
    * @param pageY {Number} Mouse page Y coordinate
    */
    TouchInput._checkCursorStatus = function (pageX, pageY) {
        // Check for events under mouse and perform actions, and get event in result
        var overEvents = this._checkForEventUnderMouse(pageX, pageY);

        // Update cursor icon position
        if (this.cursorIcon.iconIndex) {
            this.cursorIcon.x = Graphics.pageToCanvasX(pageX) +
                (this.cursorIcon.customOffsetX !== null ? this.cursorIcon.customOffsetX : $.iconOffsetX);
            this.cursorIcon.y = Graphics.pageToCanvasY(pageY) +
                (this.cursorIcon.customOffsetY !== null ? this.cursorIcon.customOffsetY : $.iconOffsetY);
            this.cursorIcon.visible = true;
        }

        // Check if leave activate is to be triggered for a previously active event
        this._activeEvents = this._activeEvents || [];
        while (this._activeEvents.length > 0) {
            var activeEvent = this._activeEvents.shift();
            if (activeEvent.TDDP_MS.leaveActivate) {
                if (!overEvents || overEvents.length == 0 || overEvents.indexOf(activeEvent) == -1) {
                    activeEvent.start();
                }
            }
        }
        // Reset active events if new over events
        this._activeEvents = overEvents || this._activeEvents;
    }
    /**
    * Alias and extend update() to store last event coords for checking if cursor has left an event
    */
    var _TouchInput_update = TouchInput.update;
    TouchInput.update = function () {
        _TouchInput_update.call(this);
        if (this._lastEventPageX == this._curEventPageX && this._lastEventPageY == this._curEventPageY) {
            this._checkCursorStatus(this._lastEventPageX, this._lastEventPageY);
        }
        this._lastEventPageX = this._curEventPageX;
        this._lastEventPageY = this._curEventPageY;
    }
    /**
    * Perform check for event under mouse and perform functions depending on parsed notetag properties
    * @method _checkForEventUnderMouse
    * @param pageX {Number} Mouse page X coordinate
    * @param pageY {Number} Mouse page Y coordinate
    * @return {Array} of found events or {Boolean} false if none.
    */
    TouchInput._checkForEventUnderMouse = function (pageX, pageY) {
        this._curEventPageX = pageX;
        this._curEventPageY = pageY;
        if ($.conditionsValidForMouseHoverCheck()) {
            var x = $gameMap.canvasToMapX(Graphics.pageToCanvasX(pageX));
            var y = $gameMap.canvasToMapY(Graphics.pageToCanvasY(pageY));
            var events = $._eventsXy(x, y);
            events.reverse().forEach(function (game_event) {
                if (game_event.TDDP_MS.hoverIcon) {
                    TouchInput._updateCursorIcon(game_event.TDDP_MS.hoverIcon);
                    if ($.hideCursor) $._hideMouseCursor();
                } else {
                    TouchInput._hideCursorIcon();
                };
                if (game_event.TDDP_MS.hoverActivate && !$gameMessage.isBusy()) {
                    game_event.start();
                };
                if (game_event.TDDP_MS.hideCursor) {
                    $._hideMouseCursor();
                };
                if (game_event.TDDP_MS.customOffsetX && game_event.TDDP_MS.customOffsetY) {
                    TouchInput.cursorIcon.customOffsetX = game_event.TDDP_MS.customOffsetX;
                    TouchInput.cursorIcon.customOffsetY = game_event.TDDP_MS.customOffsetY;
                };
                if ($.useCustomCursor) {
                    if (game_event.TDDP_MS.customCursor) {
                        $._showCustomCursor(game_event.TDDP_MS.customCursor);
                    } else {
                        $._showCustomCursor();
                    }
                };
                if (game_event.TDDP_MS.hoverSwitch) {
                    var key = [$gameMap._mapId, game_event._eventId, game_event.TDDP_MS.hoverSwitch.key]
                    $gameSelfSwitches.setValue(key, game_event.TDDP_MS.hoverSwitch.val === 'true')
                };
            });
            if (events && events.length > 0) return events;
        }
        // If no events found under cursor perform default actions
        TouchInput._hideCursorIcon();
        $._showMouseCursor();
        return false;
    };
    /**
    * Update the cursor icon
    * @method _updateCursorIcon
    * @param iconIndex {Number} The icon index to show next to the cursor
    */
    TouchInput._updateCursorIcon = function (iconIndex) {
        if (this.cursorIcon.iconIndex != iconIndex) {
            this.cursorIcon.iconIndex = iconIndex;
            this.cursorIcon.contents.clear();
            this.cursorIcon.drawIcon(iconIndex, 0, 0);
            this.cursorIcon.visible = false;
        }
    };
    /**
    * Hide the cursor icon
    * @method _hideCursorIcon
    */
    TouchInput._hideCursorIcon = function () {
        this.cursorIcon.iconIndex = null;
        this.cursorIcon.visible = false;
        this.cursorIcon.customOffsetX = null;
        this.cursorIcon.customOffsetY = null;
    }
    /**
    * Alias and extend _onTrigger() to only fire if we're not activating on click
    */
    var _TouchInput_onTrigger = TouchInput._onTrigger;
    TouchInput._onTrigger = function (x, y) {
        if (TouchInput._activateClickEvents(x, y)) {
            $gameTemp.clearDestination(); // Invalidate destination
        } else {
            _TouchInput_onTrigger.call(this, x, y);
        }
    };
    /**
    * Activate click events if valid and return true if so
    * @method _activateClickEvents
    * @param x {Number} Map X coordinate
    * @param y {Number} Map Y coordinate
    */
    TouchInput._activateClickEvents = function (x, y) {
        var found_click_event = false;
        if ($.conditionsValidForMouseHoverCheck()) {
            var x = $gameMap.canvasToMapX(x);
            var y = $gameMap.canvasToMapY(y);
            $._eventsXy(x, y).reverse().forEach(function (game_event) {
                if (game_event.TDDP_MS.clickActivate) {
                    game_event.start();
                    found_click_event = true;
                };
                if (game_event.TDDP_MS.clickSwitch) {
                    var key = [$gameMap._mapId, game_event._eventId, game_event.TDDP_MS.clickSwitch.key]
                    $gameSelfSwitches.setValue(key, game_event.TDDP_MS.clickSwitch.val === 'true');
                    found_click_event = true;
                };
            });
        }
        return found_click_event;
    }
    //=============================================================================
    // Spriteset_Map modifications
    //=============================================================================
    /**
    * Alias and extend createScreenSprites() to also create cursor icon holder sprite
    */
    var _Spriteset_Map_createScreenSprites = Spriteset_Map.prototype.createScreenSprites;
    Spriteset_Map.prototype.createScreenSprites = function () {
        _Spriteset_Map_createScreenSprites.call(this);
        this.createCursorIconSprite();
    };
    /**
    * Create a container sprite for the cursor icon
    */
    Spriteset_Map.prototype.createCursorIconSprite = function () {
        this._cursorIconSprite = new Sprite();
        this._cursorIconSprite.setFrame(0, 0, Graphics.width, Graphics.height);
        this._cursorIconSprite.addChild(TouchInput.cursorIcon);
        this.addChild(this._cursorIconSprite);
    };
    //=============================================================================
    // Game_Event modifications
    //=============================================================================
    /**
    * Alias and extend setupPage() to also setup mouse system properties
    */
    var _Game_Event_setupPage = Game_Event.prototype.setupPage;
    Game_Event.prototype.setupPage = function () {
        _Game_Event_setupPage.call(this);
        this.setupMouseSystemProperties();
    };
    /**
    * Setup mouse system properties on events, for storing notetag parsing on page updates
    */
    Game_Event.prototype.setupMouseSystemProperties = function () {
        this.TDDP_MS = {};
        this.TDDP_MS.hoverIcon = false;
        this.TDDP_MS.allowAutoCursor = true;
        this.TDDP_MS.allowAutoIcon = true;
        this.TDDP_MS.clickActivate = false;
        this.TDDP_MS.hoverActivate = false;
        this.TDDP_MS.leaveActivate = false;
        this.TDDP_MS.hideCursor = false;
        this.TDDP_MS.customOffsetX = false;
        this.TDDP_MS.customOffsetY = false;
        this.TDDP_MS.customCursor = false;
        this.TDDP_MS.clickSwitch = false;
        this.TDDP_MS.hoverSwitch = false;
        $._findInEventNotetags(this, /hover_icon\s(.*?);/i, function (result) {
            if (!result) return;
            result = result[result.length - 1];
            if ($.mouseIconTags[result]) {
                result = $.mouseIconTags[result];
            }
            this.TDDP_MS.hoverIcon = Number(result);
        });
        $._findInEventNotetags(this, $.noAutoCursorNotetag, function () {
            this.TDDP_MS.allowAutoCursor = false;
        });
        $._findInEventNotetags(this, $.noAutoIconNotetag, function () {
            this.TDDP_MS.allowAutoIcon = false;
        });
        $._findInEventNotetags(this, $.clickToActivateNote, function () {
            this.TDDP_MS.clickActivate = true;
        });
        $._findInEventNotetags(this, $.hoverToActivateNote, function () {
            this.TDDP_MS.hoverActivate = true;
        });
        $._findInEventNotetags(this, $.leaveToActivateNote, function () {
            this.TDDP_MS.leaveActivate = true;
        });
        $._findInEventNotetags(this, 'hide_cursor!', function () {
            this.TDDP_MS.hideCursor = true;
        });
        $._findInEventNotetags(this, /icon_offset\s(.*?)\s(.*?);/i, function (result) {
            this.TDDP_MS.customOffsetX = Number(result[1]);
            this.TDDP_MS.customOffsetY = Number(result[2]);
        });
        $._findInEventNotetags(this, /hover_cursor\s(.*?);/i, function (result) {
            this.TDDP_MS.customCursor = result[result.length - 1];
        });
        $._findInEventNotetags(this, /click_switch\s(.*?)\s(.*?);/i, function (result) {
            this.TDDP_MS.clickSwitch = {};
            this.TDDP_MS.clickSwitch.key = String(result[1]);
            this.TDDP_MS.clickSwitch.val = String(result[2]);

        });
        $._findInEventNotetags(this, /hover_switch\s(.*?)\s(.*?);/i, function (result) {
            this.TDDP_MS.hoverSwitch = {};
            this.TDDP_MS.hoverSwitch.key = String(result[1]);
            this.TDDP_MS.hoverSwitch.val = String(result[2]);
        });
        // If no active event page, there's no event commands to go through
        if (!this.page()) return;
        // Auto cursor checks, only if there's a page and allowed
        if (this.TDDP_MS.allowAutoCursor) {
            for (var i = 0, max = $.autoCursorFilters.length; i < max; i++) {
                if (this.TDDP_MS.customCursor) break;
                var entry = $.autoCursorFilters[i];
                var cursor = entry[0];
                var filter = entry[1];
                if (typeof cursor == "string") {
                    var matches = this.page().list.filter(filter);
                    if (matches.length > 0) {
                        this.TDDP_MS.customCursor = cursor;
                    }
                }
            }
        }
        // Auto icon checks
        if (this.TDDP_MS.allowAutoIcon) {
            for (var i = 0, max = $.autoIconFilters.length; i < max; i++) {
                if (this.TDDP_MS.hoverIcon) break;
                var entry = $.autoIconFilters[i];
                var icon = entry[0];
                var filter = entry[1];
                if (typeof icon == "string") {
                    var matches = this.page().list.filter(filter);
                    if (matches.length > 0) {
                        if (isNaN(icon)) {
                            // Icon is a string, so let's look in Icon Tags
                            icon = $.mouseIconTags[icon]
                        }
                        this.TDDP_MS.hoverIcon = Number(icon);
                    }
                }
            }
        }
    }
})(TDDP_MouseSystemEx);


code:
//==============================================================================
// TEM_Formation_Battle_A
// TEM_Formation_Battle_A.js
// Version: 2.1
// 最終更新日: 2016/09/07
//=============================================================================
//■更新履歴
// 2016/04/16 - 公開
// 2016/04/16 - 修正（匿名の方のご協力）
// 2016/09/05 - アクター1人目の「攻撃」「防御」のところに「隊列」をいれたバージョン
// 2016/09/07 - コアスクリプト1.3.1で不具合報告、確認できたので修正対応しました。
//=============================================================================
/*:
 *
 * @plugindesc 戦闘中のアクターコマンドに隊列変更を追加
 * @author みみおとこ
 *
 * @help
 * 戦闘中のアクターコマンド（一人目）に隊列変更を追加します
 * フロントビュー・サイドビュー両対応。
 *
 * 再配布・改造、自由にしてください。クレジットあると嬉しいです。
 *
 */

Scene_Battle.prototype.createActorCommandWindow = function () {
    this._actorCommandWindow = new Window_ActorCommand();
    this._actorCommandWindow.setHandler('attack', this.commandAttack.bind(this));
    this._actorCommandWindow.setHandler('skill', this.commandSkill.bind(this));
    this._actorCommandWindow.setHandler('guard', this.commandGuard.bind(this));
    this._actorCommandWindow.setHandler('formation', this.commandFormation.bind(this));

    this._actorCommandWindow.setHandler('item', this.commandItem.bind(this));
    this._actorCommandWindow.setHandler('cancel', this.selectPreviousCommand.bind(this));
    this.addWindow(this._actorCommandWindow);
};

Scene_Battle.prototype.commandFormation = function () {
    this._fstatusWindow.setFormationMode(true);
    this._fstatusWindow.selectLast();
    this._fstatusWindow.activate();
    this._fstatusWindow.show();

    //    this._statusWindow.refresh();
    this._fstatusWindow.refresh();
    this._fstatusWindow.setHandler('ok', this.onFormationOk.bind(this));
    this._fstatusWindow.setHandler('cancel', this.onFormationCancel.bind(this));
};
Scene_Battle.prototype.onFormationOk = function () {
    var index = this._fstatusWindow.index();
    var actor = $gameParty.allMembers()[index];
    var pendingIndex = this._fstatusWindow.pendingIndex();
    if (pendingIndex >= 0) {
        $gameParty.swapOrder(index, pendingIndex);
        this._fstatusWindow.setPendingIndex(-1);
        this._fstatusWindow.redrawItem(index);
        this._statusWindow.refresh();
    } else {
        this._fstatusWindow.setPendingIndex(index);
    }
    this._fstatusWindow.activate();
};
Scene_Battle.prototype.onFormationCancel = function () {
    if (this._fstatusWindow.pendingIndex() >= 0) {
        this._fstatusWindow.setPendingIndex(-1);
        this._fstatusWindow.activate();
        //this._partyCommandWindow.activate();
    } else {
        this._fstatusWindow.deselect();
        this._fstatusWindow.hide();
        BattleManager.startInput();
    }
};
var F_Scene_Battle_createAllWindows = Scene_Battle.prototype.createAllWindows;
Scene_Battle.prototype.createAllWindows = function () {
    F_Scene_Battle_createAllWindows.call(this);
    this.createFWindow();
};
Scene_Battle.prototype.createFWindow = function () {
    this._fstatusWindow = new Window_FStatus(100, 0, 100, 100);
    this.addWindow(this._fstatusWindow);
    this._fstatusWindow.hide();

};
Scene_Battle.prototype.startActorCommandSelection = function () {
    if (this._fstatusWindow.active) return;
    this._statusWindow.select(BattleManager.actor().index());
    this._partyCommandWindow.close();
    this._actorCommandWindow.setup(BattleManager.actor());
};
Window_ActorCommand.prototype.isFormationEnabled = function () {
    return $gameParty.size() >= 2 && $gameSystem.isFormationEnabled();
};
Window_ActorCommand.prototype.addFormationCommand = function () {
    if (!this.isFormationEnabled()) {
        this.addCommand(TextManager.formation, 'formation', false);
        return;
    }
    this.addCommand(TextManager.formation, 'formation', true);
};
Window_ActorCommand.prototype.makeCommandList = function () {
    if (this._actor) {
        if (this._actor._actorId == $gameParty._actors[0]) {
            this.addAttackCommand();
            this.addSkillCommands();
            this.addGuardCommand();
            this.addFormationCommand();
            this.addItemCommand();
        } else {
            this.addAttackCommand();
            this.addSkillCommands();
            this.addGuardCommand();
            this.addItemCommand();
        }
    }
};
//-----------------------------------------------------------------------------
// Window_FStatus
//
// The window for displaying party member status on the menu screen.

function Window_FStatus() {
    this.initialize.apply(this, arguments);
}
Window_FStatus.prototype = Object.create(Window_MenuStatus.prototype);
Window_FStatus.prototype.constructor = Window_FStatus;

Window_FStatus.prototype.maxItems = function () {
    return $gameParty.allMembers().length;;
};
Window_FStatus.prototype.loadImages = function () {
    $gameParty.allMembers().forEach(function (actor) {
        ImageManager.loadFace(actor.faceName());
    }, this);
};
Window_FStatus.prototype.drawItemImage = function (index) {
    var actor = $gameParty.allMembers()[index];
    var rect = this.itemRect(index);
    this.changePaintOpacity(actor.isBattleMember());
    this.drawActorFace(actor, rect.x + 1, rect.y + 1, Window_Base._faceWidth, Window_Base._faceHeight);
    this.changePaintOpacity(true);

};
Window_FStatus.prototype.drawItemStatus = function (index) {
    var actor = $gameParty.allMembers()[index];
    var rect = this.itemRect(index);
    var x = rect.x + 162;
    var y = rect.y + rect.height / 2 - this.lineHeight() * 1.5;
    var width = rect.width - x - this.textPadding();

    this.drawActorSimpleStatus(actor, x, y, width);
};
Window_FStatus.prototype.processOk = function () {

    this.playOkSound();
    this.updateInputData();
    this.deactivate();
    this.callOkHandler();
    $gameParty.setMenuActor($gameParty.allMembers()[this.index()]);
};

Window_FStatus.prototype.isCurrentItemEnabled = function () {
    if ($gameSystem.isTopFix() && this._formationMode &&
        this.index() === 0) {
        return false;
    } else {
        return true;
    }
};


code:
//========================================
// TF_LayeredMap.js
// Version :0.4.1.0
// For : RPGツクールMV (RPG Maker MV)
// -----------------------------------------------
// Copyright : Tobishima-Factory 2018 - 2019
// Website : http://tonbi.jp
//
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
//========================================
/*:
 * @plugindesc Upper[☆]tile display like billboard.
 * @author Tonbi@Tobishima-Factory
 *
 * @help
 * Change tile behavior by use no effect option at default.
 *
 * 1. Set [counter]option for A3・A4 tile.
 *      [○] Behavior like[☆]
 *      [×] Hide only upper tile.
 *
 * 2. set [☆] to BCDE tile, and set 4 direction setting.
 *      0x0 ↑→←↓ : [☆]  Same as no plugin.
 *      0x1 ↑→←・ : billboard, ↑・←→ pass, ground (for fence)
 *      0x2 ↑→・↓ : billboard, ↑↓　→ pass, ground (left side of fence)┃
 *      0x3 ↑→・・ : billboard, ↑　　→ pass, ground (bottom left)┗
 *      0x4 ↑・←↓ : billboard, ↑↓←　 pass, ground (right)   ┃
 *      0x5 ↑・←・ : billboard, ↑　←　 pass, ground (bottom right)   ┛
 *      0x6 ↑・・↓ : billboard, ↑↓　　 pass, ground (both side)┃┃
 *      0x7 ↑・・・ : billboard, ↑　　　 pass, ground (like bartizan)┗┛
 *      0x8 ・→←↓ : billboard,  all directtion , ground (for bush)
 *      0x9 ・→←・ : billboard,  all directtion , upper
 *      0xA ・→・↓ : undefined
 *      0xB ・→・・ : undefined
 *      0xC ・・←↓ : undefined
 *      0xD ・・←・ : undefined
 *      0xE ・・・↓ : undefined
 *      0xF ・・・・ : undefined
 *
 * Released under the MIT License.
 */
/*:ja
 * @plugindesc 高層[☆]タイルを書き割り風に配置する
 * @author とんび@鳶嶋工房
 *
 * @help
 * デフォルトで未使用の設定で、タイルの重なりが変化します。
 *
 * 1. A3・A4タイルに[カウンター]を設定
 *      [○] 下を通れる(ほぼ[☆]の状態)
 *      [×] 上部タイルのみ後ろに回り込む
 *
 * 2. BCDEタイルに[☆]を指定したあと、通行設定(4方向)
 *      0x0 ↑→←↓ : [☆] 設定、全方向に 通行可(プラグインなしと同じ)
 *      0x1 ↑→←・ : 書き割り、上　左右 通行可、1階 (基本、柵とか)
 *      0x2 ↑→・↓ : 書き割り、上下　右 通行可、1階 (柵の左側とか)┃
 *      0x3 ↑→・・ : 書き割り、上　　右 通行可、1階 (柵の左下とか)┗
 *      0x4 ↑・←↓ : 書き割り、上下左　 通行可、1階 (柵の右側とか)   ┃
 *      0x5 ↑・←・ : 書き割り、上　左　 通行可、1階 (柵の右下とか)   ┛
 *      0x6 ↑・・↓ : 書き割り、上下　　 通行可、1階 (両脇に木とか)┃┃
 *      0x7 ↑・・・ : 書き割り、上　　　 通行可、1階 (張り出し的な)┗┛
 *      0x8 ・→←↓ : 書き割り、全方向に 通行可、1階 (草むらなどに)
 *      0x9 ・→←・ : 書き割り、全方向に 通行可、2階
 *      0xA ・→・↓ : 未設定
 *      0xB ・→・・ : 未設定
 *      0xC ・・←↓ : 未設定
 *      0xD ・・←・ : 未設定
 *      0xE ・・・↓ : 未設定
 *      0xF ・・・・ : 未設定
 *
 * 利用規約 : MITライセンス
 */
(function () {
    'use strict';

    const PLUGIN_NAME = 'TF_LayeredMap';
    const pluginParams = PluginManager.parameters(PLUGIN_NAME);

    /*---- ShaderTilemap ----*/
    /**
     * タイルセットの画像を設定する。
     * マップ開始時に呼ばれる。
     */
    const _ShaderTilemaprefreshTileset = ShaderTilemap.prototype.refreshTileset;
    ShaderTilemap.prototype.refreshTileset = function () {
        _ShaderTilemaprefreshTileset.call(this);

        // BitmapをPIXI.Textureにコンバート
        const bitmaps = this.bitmaps.map(function (x) {
            return x._baseTexture ? new PIXI.Texture(x._baseTexture) : x;
        });

        // 書き割りのタイルセットの画像をアップデート
        for (let curItem of this.TF_billboards) {
            curItem.children[0].setBitmaps(bitmaps);
        }
    }

    /**
     * 書き割りレイヤーの生成と追加
     */
    const _ShaderTilemap_createLayers = ShaderTilemap.prototype._createLayers;
    ShaderTilemap.prototype._createLayers = function () {
        _ShaderTilemap_createLayers.call(this);

        // 書き割り風オブジェクトを生成
        // +2 はスクロールの際にはみ出す部分と2階用
        const th = this._tileHeight;
        const tileRows = Math.ceil(this._height / th) + 2;

        if (!this.hasOwnProperty('TF_billboards')) {
            this.TF_billboards = [];
        }

        for (let i = 0; i < tileRows; i++) {
            const billboard = new PIXI.tilemap.ZLayer(this, 3);
            billboard.spriteId = -Infinity;
            this.addChild(billboard);
            this.TF_billboards.push(billboard);
            const layer = new PIXI.tilemap.CompositeRectTileLayer(0, [], 0);
            billboard.addChild(layer);
        }
    };

    /**
     * 描画前に書き割りの中を空にしておく。
     */
    const _ShaderTilemap_paintAllTiles = ShaderTilemap.prototype._paintAllTiles;
    ShaderTilemap.prototype._paintAllTiles = function (startX, startY) {
        for (let curItem of this.TF_billboards) {
            curItem.clear();
        }

        _ShaderTilemap_paintAllTiles.call(this, startX, startY);
    }

    /**
     * タイルマップと書き割りの描画。
     * 関数をまるっと書き換えているので
     * 他のプラグインとコンフリクトを起こしてしまうので注意。
     * @param {Number} startX 開始 マップ x座標(タイル数)
     * @param {Number} startY 開始 マップ y座標(タイル数)
     * @param {Number} x 画面上の x座標(タイル数)
     * @param {Number} y 画面上の y座標(タイル数)
     */
    //const _ShaderTilemap_paintTiles = ShaderTilemap.prototype._paintTiles;
    ShaderTilemap.prototype._paintTiles = function (startX, startY, x, y) {
        //_ShaderTilemap_paintTiles.call( this, startX, startY, x, y );

        const mx = startX + x; //  描画対象のマップ x座標(タイル数)
        const my = startY + y; //  描画対象のマップ y座標(タイル数)
        const dx = x * this._tileWidth; //  描画位置の x座標(ピクセル)
        const dy = y * this._tileHeight; //  描画位置の y座標(ピクセル)

        const tileId0 = this._readMapData(mx, my, 0); // 低層タイルA
        const tileId1 = this._readMapData(mx, my, 1); // 低層タイルA2右側など
        const tileId2 = this._readMapData(mx, my, 2); // B 〜 E タイル
        const tileId3 = this._readMapData(mx, my, 3); // B 〜 E タイル
        const shadowBits = this._readMapData(mx, my, 4); // 影ペン
        const upperTileId1 = this._readMapData(mx, my - 1, 1); // 上位置の低層タイルA

        const lowerLayer = this.lowerLayer.children[0];     // 低層レイヤ( z: 0 )
        const upperLayer = this.upperLayer.children[0];   // 高層レイヤ( z: 4 )

        /**
         * タイルを描画(upperLayer,lowerLayer,dx,dy は親の変数を使う)
         * @param {Number} tileId タイルID
         */
        const drawTile = (tileId) => {
            if (this._isHigherTile(tileId)) {
                if ((this.flags[tileId] & 0x9) === 0x9) {
                    // 2階設定は、ひとつ下の書き割りに書き込む
                    this._drawTile(this.TF_billboards[y + 1].children[0].children[0], tileId, dx, -this._tileHeight * 2);
                } else if (this.flags[tileId] & 0xF) {
                    // 通行不可設定のどれかがONだと書き割り
                    this._drawTile(this.TF_billboards[y].children[0].children[0], tileId, dx, -this._tileHeight);
                } else {
                    // 全方向通行可の場合は通常の高層[☆]表示
                    this._drawTile(upperLayer, tileId, dx, dy);
                }
            } else {
                this._drawTile(lowerLayer, tileId, dx, dy);
            }
        }

        drawTile(tileId0);
        drawTile(tileId1);

        this._drawShadow(lowerLayer, shadowBits, dx, dy);
        if (this._isTableTile(upperTileId1) && !this._isTableTile(tileId1)) {
            if (!Tilemap.isShadowingTile(tileId0)) {
                this._drawTableEdge(lowerLayer, upperTileId1, dx, dy);
            }
        }

        if (this._isOverpassPosition(mx, my)) {
            this._drawTile(upperLayer, tileId2, dx, dy);
            this._drawTile(upperLayer, tileId3, dx, dy);
        } else {
            drawTile(tileId2);
            drawTile(tileId3);
        }
    };

    /**
     * (スクロールに合わせて)書き割りの表示位置を変更
     * @param {Number} startX
     * @param {Number} startY
     */
    const _ShaderTilemap_updateLayerPositions = ShaderTilemap.prototype._updateLayerPositions;
    ShaderTilemap.prototype._updateLayerPositions = function (startX, startY) {
        _ShaderTilemap_updateLayerPositions.call(this, startX, startY);

        let ox, oy;
        if (this.roundPixels) {
            ox = Math.floor(this.origin.x);
            oy = Math.floor(this.origin.y);
        } else {
            ox = this.origin.x;
            oy = this.origin.y;
        }
        const th = this._tileHeight;
        const tw = this._tileWidth;
        const posX = startX * tw - ox;
        const posY = startY * th - oy
        const l = this.TF_billboards.length;
        for (let i = 0; i < l; i++) {
            const curItem = this.TF_billboards[i];
            curItem.position.x = posX;
            curItem.position.y = posY + (i + 1) * th;
        };
    };

    /*---- DataManager ---*/
    /**
     * 読み込み直後に、タイルセットデータを書き換える
     */
    const _DataManager_onLoad = DataManager.onLoad;
    DataManager.onLoad = function (object) {
        _DataManager_onLoad.call(this, object);

        if (object === $dataTilesets) {
            treatDataTilesets();
        }

        // end: onLoad
        /**
         * カウンター設定しているA3・A4オートタイルを回り込みに設定
         */
        function treatDataTilesets() {
            // 全タイルセットに対して設定
            for (const curTileset of $dataTilesets) {
                if (!curTileset) continue;
                const flags = curTileset.flags;

                // 屋根タイル(A3)を走査
                for (let tileId = Tilemap.TILE_ID_A3; tileId < Tilemap.TILE_ID_A4; tileId += 48) {
                    if (flags[tileId] & 0x80) { // カウンター設定か
                        if (Tilemap.isRoofTile(tileId)) {
                            roof2UpperLayer(flags, tileId);
                        } else {
                            wallSide2UpperLayer(flags, tileId);
                        }
                    }
                }

                // 壁タイル(A4)を走査
                for (let tileId = Tilemap.TILE_ID_A4; tileId < Tilemap.TILE_ID_MAX; tileId += 48) {
                    if (flags[tileId] & 0x80) { // カウンター設定か
                        if (Tilemap.isWallTopTile(tileId)) {
                            wallTop2UpperLayer(flags, tileId);
                        } else {
                            wallSide2UpperLayer(flags, tileId);
                        }
                    }
                }
            }
        }

        //  屋根の通行設定
        function roof2UpperLayer(flags, tileId) {
            if (flags[tileId + 15] & 0xF) {
                // [×] : 上端を高層表示[☆]、適宜通行不可[・]
                for (let i = 0; i < 16; i++) {
                    flags[tileId + i] = flags[tileId + i] & 0xFFE0 | ROOF_PASS_EDGE[i];
                }
            } else {
                // [○] : 全体を高層表示[☆]かつ通行可
                for (let i = 0; i < 16; i++) {
                    flags[tileId + i] = flags[tileId + i] & 0xFFE0 | 0x10;
                }
            }
        }
        //  壁(上面)の通行設定
        function wallTop2UpperLayer(flags, tileId) {
            if (flags[tileId + 46] & 0xF) {
                // [×] : 上端を高層表示[☆]、適宜通行不可[・]
                for (let i = 0; i < 47; i++) {
                    flags[tileId + i] = flags[tileId + i] & 0xFFE0 | WALL_TOP_PASS_EDGE[i];
                }
            } else {
                // [○] : 全体を高層表示[☆]かつ通行可
                for (let i = 0; i < 47; i++) {
                    flags[tileId + i] = flags[tileId + i] & 0xFFE0 | 0x10;
                }
            }
        }
        //  壁(側面)の通行設定
        function wallSide2UpperLayer(flags, tileId) {
            if (flags[tileId + 15] & 0xF) {
                // [×] : 上端を高層表示[☆]、適宜通行不可[・]
                for (let i = 0; i < 16; i++) {
                    flags[tileId + i] = flags[tileId + i] & 0xFFE0 | WALL_SIDE_PASS_EDGE[i];
                }
            } else {
                // [○] : 全体を高層表示[☆]かつ通行可(一番下のみ通行不可)
                for (let i = 0; i < 16; i++) {
                    flags[tileId + i] = flags[tileId + i] & 0xFFE0 | WALL_SIDE_PASS[i];
                }
            }
        }
    }

    /*---- Scene_Map ---*/
    /**
     * シーン表示前に、マップデータを書き換える
     */
    const _Scene_Map_onMapLoaded = Scene_Map.prototype.onMapLoaded;
    Scene_Map.prototype.onMapLoaded = function () {
        treatDataMap();
        _Scene_Map_onMapLoaded.call(this);
        // end: onMapLoaded

        /**
         * カウンター設定のA3,A4オートタイルの箇所に、低層の補完タイルを設定
         */
        function treatDataMap() {
            const flags = $dataTilesets[$dataMap.tilesetId].flags;
            for (let y = 0; y < $dataMap.height; y++) {
                for (let x = 0; x < $dataMap.width; x++) {
                    const tileId = getMapData(x, y, 0);
                    if (tileId < Tilemap.TILE_ID_A3 || !((flags[tileId] & 0x90) === 0x90)) continue;

                    // A3・A4のカウンター設定かつ高層[☆]なら、タイルを補完
                    const upTileId = (y === 0) ? getMapData(x, $dataMap.height - 1, 0) : getMapData(x, y - 1, 0);
                    setMapData(x, y, 1, tileId);
                    setMapData(x, y, 0, upTileId);
                }
            }

            function getMapData(x, y, z) {
                return $dataMap.data[x + (y + z * $dataMap.height) * $dataMap.width];
            }
            function setMapData(x, y, z, tileId) {
                $dataMap.data[x + (y + z * $dataMap.height) * $dataMap.width] = tileId;
            }
        }
    }

    // 屋根用通行設定
    const ROOF_PASS_EDGE = [
        0, 2, 17, 17,
        4, 6, 17, 17,
        0, 2, 17, 17,
        4, 6, 17, 17,
    ];
    // 壁(上面)用通行設定
    const WALL_TOP_PASS_EDGE = [
        0, 2, 4, 6, 0, 2, 4, 6,
        0, 2, 4, 6, 0, 2, 4, 6,
        2, 6, 2, 6, 17, 17, 17, 17,
        4, 4, 6, 6, 0, 2, 4, 6,
        6, 17, 17, 17, 17, 17, 4, 6,
        2, 6, 17, 17, 6, 17, 17,
    ];
    // 壁(側面)用通行設定
    const WALL_SIDE_PASS_EDGE = [
        15, 15, 17, 17,
        15, 15, 17, 17,
        15, 15, 17, 17,
        15, 15, 17, 17,
    ];
    const WALL_SIDE_PASS = [
        25, 25, 25, 25,
        25, 25, 25, 25,
        17, 17, 17, 17,
        17, 17, 17, 17,
    ];

    /*---- Game_Map ----*/
    /**
     * 指定位置の指定フラグビットが通行可か。
     * @param {Number} x タイル数
     * @param {Number} y タイル数
     * @param {Number} bit {@link RPG.Tileset}の flagsチェック用ビット
     * @returns {Boolean} 高層表示[☆]の4方向の通行設定については@helpを参照
     */
    const _Game_Map_checkPassage = Game_Map.prototype.checkPassage;
    Game_Map.prototype.checkPassage = function (x, y, bit) {
        const flags = this.tilesetFlags();
        const tiles = this.allTiles(x, y);
        for (let i = 0; i < tiles.length; i++) {
            const tileId = tiles[i];
            const flag = flags[tileId];

            // ここでは高層[☆]タイルのみ判定するので、外は無視
            if (!(flag & 0x10)) continue;

            // 0x08(上通行不可[・])は特殊設定用のビットに使う
            // そのため通行判定として無視
            if (flag & 0x08) continue;

            // 高層[☆]の通行不可[・]設定は
            // 他の重なったタイルによらず通行不可
            if ((flag & bit) === bit) return false;
        }
        return _Game_Map_checkPassage.call(this, x, y, bit);
    };
})();


code:
//=============================================================================
// TMPlugin - アニメ付き明かり
// バージョン: 2.0.1
// 最終更新日: 2016/12/02
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2016 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc イベントにアニメーション付きの明かりを表示します。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @param range
 * @desc アニメーションの大きさ。
 * 初期値: 0.1 ( 0.1 でプラスマイナス 10% の拡大縮小アニメ)
 * @default 0.1
 *
 * @param defaultZ
 * @desc アニメーションのＺ座標。
 * 初期値: 4
 * @default 4
 *
 * @param frames
 * @desc アニメーションにかけるフレーム数。
 * 初期値: 30
 * @default 30
 *
 * @help
 * 準備:
 *
 *   プラグインと一緒に配布している明かり画像を img/system フォルダに
 *   保存してください。ファイル名は自由に変更可能です。
 *   使用する画像はどんなものでもかまいません、イベントごとに違う画像を
 *   表示することもできます。
 *
 *
 * 使い方:
 *
 *   イベントのメモ欄に <animeLight:ファイル名> というタグを書き込めば、
 *   明かりが表示されるようになります。
 *
 *   明かりの位置もタグを使って調整することができます。
 *
 *   このプラグインは RPGツクールMV Version 1.3.4 で動作確認をしています。
 *
 *
 * メモ欄（イベント）タグ:
 *
 *   <animeLight:TMAnimeLight1 192 24 -44 4>
 *     画像 TMAnimeLight1.png を不透明度 192 で、イベントの足元から右に 24、
 *     上に 44 ドットずらした位置にＺ座標 4 で表示します。
 *     不透明度の最大値は 255 です。
 *
 *   イベントのメモ欄以外に、実行内容の一番上にある注釈コマンド内でも
 *   同様のタグで名前を設定することができます。
 *   メモ欄と注釈の両方にタグがある場合は注釈が優先されます。
 *
 *
 * プラグインコマンド:
 *
 *   animeLight 1 TMAnimeLight1 255 0 -44 4
 *     イベント 1 番に明かりを適用します。
 *     イベント番号、ファイル名、不透明度、Ｘ座標補正、Ｙ座標補正、Ｚ座標
 *     の順に設定してください。
 *     Ｚ座標を省略した場合はプラグインパラメータ animeLightZ の値を
 *     使用します。
 *
 *   animeLight 1
 *     イベント 1 番の明かりを削除します。
 *
 *   イベント番号（ひとつ目の数値）は以下の規則にしたがって対象を指定します。
 *     -1     … プレイヤーを対象にする
 *     0      … コマンドを実行しているイベントを対象にする
 *     1 以上 … その番号のイベントを対象にする
 *
 *
 * おまけ機能:
 *
 *   メモ欄タグ、注釈、プラグインコマンドすべてに共通で、Ｚ座標のあとに
 *   1 という数値を付与することでアニメーションのない画像を表示できます。
 *   例: <animeLight:TMAnimeLight1 192 0 0 4 1>
 *   この場合Ｚ座標を省略することはできません。
 *
 *
 * プラグインパラメータ補足:
 *
 *   defaultZ
 *     明かりの描画順を設定します、これによりイベントよりも下に表示するか
 *     上に表示するかが決まります。
 *     0 … プライオリティ『通常キャラの下』より下
 *     2 … プライオリティ『通常キャラと同じ』より下
 *     4 … プライオリティ『通常キャラと同じ』より上
 *     6 … プライオリティ『通常キャラの上』より上
 */

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

var TMPlugin = TMPlugin || {};
TMPlugin.AnimeLight = {};
TMPlugin.AnimeLight.Parameters = PluginManager.parameters('TMAnimeLight');
TMPlugin.AnimeLight.Range = +(TMPlugin.AnimeLight.Parameters['range'] || 0.1);
TMPlugin.AnimeLight.DefaultZ = +(TMPlugin.AnimeLight.Parameters['defaultZ'] || 4);
TMPlugin.AnimeLight.Frames = +(TMPlugin.AnimeLight.Parameters['frames'] || 30);

if (!TMPlugin.EventBase) {
  TMPlugin.EventBase = true;
  (function () {

    var _Game_Event_setupPage = Game_Event.prototype.setupPage;
    Game_Event.prototype.setupPage = function () {
      _Game_Event_setupPage.call(this);
      if (this._pageIndex >= 0) this.loadCommentParams();
    };

    Game_Event.prototype.loadCommentParams = function () {
      this._commentParams = {};
      var re = /<([^<>:]+)(:?)([^>]*)>/g;
      var list = this.list();
      for (var i = 0; i < list.length; i++) {
        var command = list[i];
        if (command && command.code == 108 || command.code == 408) {
          for (; ;) {
            var match = re.exec(command.parameters[0]);
            if (match) {
              this._commentParams[match[1]] = match[2] === ':' ? match[3] : true;
            } else {
              break;
            }
          }
        } else {
          break;
        }
      }
    };

    Game_Event.prototype.loadTagParam = function (paramName) {
      return this._commentParams[paramName] || this.event().meta[paramName];
    };

  })();
} // TMPlugin.EventBase

if (!TMPlugin.InterpreterBase) {
  TMPlugin.InterpreterBase = true;
  (function () {

    Game_Interpreter.prototype.convertEscapeCharactersTM = function (text) {
      text = text.replace(/\\/g, '\x1b');
      text = text.replace(/\x1b\x1b/g, '\\');
      text = text.replace(/\x1bV\[(\d+)\]/gi, function () {
        return $gameVariables.value(parseInt(arguments[1]));
      }.bind(this));
      text = text.replace(/\x1bV\[(\d+)\]/gi, function () {
        return $gameVariables.value(parseInt(arguments[1]));
      }.bind(this));
      text = text.replace(/\x1bN\[(\d+)\]/gi, function () {
        return this.actorNameTM(parseInt(arguments[1]));
      }.bind(this));
      text = text.replace(/\x1bP\[(\d+)\]/gi, function () {
        return this.partyMemberNameTM(parseInt(arguments[1]));
      }.bind(this));
      text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
      return text;
    };

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

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

  })();
} // TMPlugin.InterpreterBase

(function () {

  //-----------------------------------------------------------------------------
  // Game_Temp
  //

  var _Game_Temp_initialize = Game_Temp.prototype.initialize;
  Game_Temp.prototype.initialize = function () {
    _Game_Temp_initialize.call(this);
    this.createAnimeLightSinTable();
  };

  Game_Temp.prototype.createAnimeLightSinTable = function () {
    this._animeLightSinTable = [];
    for (var i = 0; i < TMPlugin.AnimeLight.Frames; i++) {
      this._animeLightSinTable[i] = Math.sin(Math.PI * i / (TMPlugin.AnimeLight.Frames / 2)) *
        TMPlugin.AnimeLight.Range + 1;
    }
  };

  Game_Temp.prototype.animeLightSin = function (index) {
    return this._animeLightSinTable[index];
  };

  //-----------------------------------------------------------------------------
  // Game_CharacterBase
  //

  Game_CharacterBase.prototype.requestAnimeLight = function () {
    this._requestAnimeLight = true;
  };

  Game_CharacterBase.prototype.onChangeAnimeLight = function () {
    this._requestAnimeLight = false;
  };

  Game_CharacterBase.prototype.isAnimeLightRequested = function () {
    return this._requestAnimeLight;
  };

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

  var _Game_Event_setupPage = Game_Event.prototype.setupPage;
  Game_Event.prototype.setupPage = function () {
    _Game_Event_setupPage.call(this);
    if (this._pageIndex >= 0) {
      var animeLight = this.loadTagParam('animeLight');
      if (animeLight) {
        var arr = animeLight.split(' ');
        this._animeLight = arr[0];
        this._animeLightOpacity = arr[1] || 255;
        this._animeLightShiftX = arr[2] || 0;
        this._animeLightShiftY = arr[3] || 0;
        this._animeLightZ = arr[4] || TMPlugin.AnimeLight.DefaultZ;
        this._animeLightNone = arr[5] === '1';
      }
    } else {
      this._animeLight = '';
      this._animeLightOpacity = 255;
      this._animeLightShiftX = 0;
      this._animeLightShiftY = 0;
      this._animeLightZ = TMPlugin.AnimeLight.DefaultZ;
      this._animeLightNone = false;
    }
    this.requestAnimeLight();
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter
  //

  var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === 'animeLight') {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var character = this.character(+arr[0]);
      if (character) {
        character._animeLight = arr[1];
        character._animeLightOpacity = arr[2] || 255;
        character._animeLightShiftX = arr[3] || 0;
        character._animeLightShiftY = arr[4] || 0;
        character._animeLightZ = arr[5] || TMPlugin.AnimeLight.DefaultZ;
        character._animeLightNone = arr[6] === '1';
        character.requestAnimeLight();
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Sprite_Character
  //

  var _Sprite_Character_update = Sprite_Character.prototype.update;
  Sprite_Character.prototype.update = function () {
    _Sprite_Character_update.call(this);
    this.updateAnimeLight();
  };

  Sprite_Character.prototype.updateAnimeLight = function () {
    if (this._character.isAnimeLightRequested() ||
      this._animeLight !== this._character._animeLight) {
      this._character.onChangeAnimeLight();
      this._animeLight = this._character._animeLight;
      if (this._animeLight) {
        if (!this._animeLightSprite) {
          this._animeLightSprite = new Sprite_AnimeLight(this);
          this.parent.addChild(this._animeLightSprite);
        }
        this._animeLightSprite.refresh(this._animeLight);
      } else {
        this.parent.removeChild(this._animeLightSprite);
        this._animeLightSprite = null;
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Sprite_AnimeLight
  //

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

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

  Sprite_AnimeLight.prototype.initialize = function (characterSprite) {
    Sprite.prototype.initialize.call(this);
    this._characterSprite = characterSprite;
    this.anchor.x = 0.5;
    this.anchor.y = 0.5;
    this.blendMode = 1;
    this._animeCount = 0;
  };

  Sprite_AnimeLight.prototype.update = function () {
    Sprite.prototype.update.call(this);
    this.x = this._characterSprite.x + this._shiftX;
    this.y = this._characterSprite.y + this._shiftY;
    if (!this._characterSprite._character._animeLightNone) {
      this._animeCount++;
      if (this._animeCount === TMPlugin.AnimeLight.Frames) this._animeCount = 0;
      var n = $gameTemp.animeLightSin(this._animeCount);
      this.scale.set(n, n);
    }
  };

  Sprite_AnimeLight.prototype.refresh = function (fileName) {
    this.bitmap = ImageManager.loadSystem(fileName);
    this.opacity = +this._characterSprite._character._animeLightOpacity;
    this._shiftX = +this._characterSprite._character._animeLightShiftX;
    this._shiftY = +this._characterSprite._character._animeLightShiftY;
    this.x = this._characterSprite.x + this._shiftX;
    this.y = this._characterSprite.y + this._shiftY;
    this.z = +this._characterSprite._character._animeLightZ;
  };

})();


code:
//=============================================================================
// TMVplugin - バトラー表示拡張
// 作者: tomoaky (http://hikimoki.sakura.ne.jp/)
// Version: 1.0
// 最終更新日: 2015/11/24
//=============================================================================

/*:
 * @plugindesc エネミーに遠近感や息づかいの表現を追加します。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @param baseY
 * @desc 拡大率が 1 になる Y 座標。
 * 初期値: 400
 * @default 400
 *
 * @param breathH
 * @desc 息づかいの大きさ。
 * 初期値: 0.05
 * @default 0.05
 *
 * @param mirrorRate
 * @desc 左右反転の確率。
 * 初期値: 0.4（ 0 ～ 1 ）
 * @default 0.4
 *
 * @help サイドビューでは左右反転が無効になります。
 *
 * メモ欄（敵キャラ）タグ:
 *   <scale:1>       # 拡大率の個別設定
 *   <breathH:0.05>  # 息づかいの大きさを個別設定
 *   <noMirror>      # 左右反転を禁止
 *
 * 拡大率の個別設定がある敵キャラには遠近感の表現が適用されません。
 *
 * プラグインコマンドはありません。
 *
 */

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

(function () {

  var parameters = PluginManager.parameters('TMBattlerEx');
  var baseY = Number(parameters['baseY']);
  var breathH = Number(parameters['breathH']);
  var mirrorRate = Number(parameters['mirrorRate']);

  //-----------------------------------------------------------------------------
  // Sprite_Enemy
  //

  var _Sprite_Enemy_initialize = Sprite_Enemy.prototype.initialize;
  Sprite_Enemy.prototype.initialize = function (battler) {
    _Sprite_Enemy_initialize.call(this, battler);
    var r = battler.enemy().meta['scale'];
    r = r ? Number(scale) : this.y / (baseY * 2) + 0.5;
    this._baseScale = new Point(r, r);
    if (!$gameSystem.isSideView() && Math.random() < mirrorRate &&
      !battler.enemy().meta['noMirror']) {
      this._baseScale.x = -r;
    }
    this._breathMax = Math.randomInt(90) + 90;
    this._breathCount = Math.randomInt(this._breathMax);
  };

  var _Sprite_Enemy_update = Sprite_Enemy.prototype.update;
  Sprite_Enemy.prototype.update = function () {
    _Sprite_Enemy_update.call(this);
    this.updateScaleEx();
  };

  Sprite_Enemy.prototype.updateScaleEx = function () {
    this._breathCount++;
    if (this._breathCount >= this._breathMax) {
      this._breathMax = Math.randomInt(90) + 90;
      this._breathCount = 0;
    }
    var scaleX = this._baseScale.x;
    var scaleY = this._baseScale.y;
    var bh = this._enemy.enemy().meta['breathH'];
    bh = bh ? Number(bh) : breathH;
    scaleY += Math.sin(Math.PI * this._breathCount / (this._breathMax / 2)) * bh;
    this.scale.set(scaleX, scaleY);
  };

})();


code:
//=============================================================================
// TMPlugin - さよならコマンド
// バージョン: 1.0.0
// 最終更新日: 2017/01/12
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2017 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc メニューコマンドに仲間と別れる機能を追加します。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @param byeCommand
 * @desc さよならコマンドのコマンド名。
 * 初期値: 別れる
 * @default 別れる
 *
 * @param byeSe
 * @desc さよならコマンド実行時に鳴らす効果音のファイル名
 * 初期値: Decision1
 * @default Decision1
 * @require 1
 * @dir audio/se/
 * @type file
 *
 * @param byeSeParam
 * @desc さよならコマンド効果音のパラメータ
 * 初期値: {"volume":90, "pitch":100, "pan":0}
 * @default {"volume":90, "pitch":100, "pan":0}
 *
 * @help
 * TMPlugin - さよならコマンド ver1.0.0
 *
 * 使い方:
 *
 *   このプラグインを導入するとメニューコマンドに『別れる』が追加されます。
 *   パーティメンバーが 1 名以下の場合、コマンドを実行することはできません。
 *
 *   このプラグインは RPGツクールMV Version 1.3.4 で動作確認をしています。
 *
 *
 * プラグインコマンド:
 *
 *   disableBye
 *     さよならコマンドをメニューコマンドから除外します。
 *
 *   enableBye
 *     除外したさよならコマンドを元に戻します。
 *
 *
 * メモ欄タグ（アクター）:
 *
 *   <disableBye>
 *     メモ欄にこのタグがついているアクターは別れることができません。
 */

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

var TMPlugin = TMPlugin || {};
TMPlugin.ByeCommand = {};
TMPlugin.ByeCommand.Parameters = PluginManager.parameters('TMByeCommand');
TMPlugin.ByeCommand.ByeCommand = TMPlugin.ByeCommand.Parameters['byeCommand'] || '別れる';
TMPlugin.ByeCommand.ByeSe = JSON.parse(TMPlugin.ByeCommand.Parameters['byeSeParam'] || '{}');
TMPlugin.ByeCommand.ByeSe.name = TMPlugin.ByeCommand.Parameters['byeSe'] || '';
(function () {

  //-----------------------------------------------------------------------------
  // Game_System
  //

  Game_System.prototype.isByeEnabled = function () {
    if (this._byeEnabled == null) this._byeEnabled = true;
    return this._byeEnabled;
  };

  Game_System.prototype.disableBye = function () {
    this._byeEnabled = false;
  };

  Game_System.prototype.enableBye = function () {
    this._byeEnabled = true;
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter
  //

  var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === 'disableBye') {
      $gameSystem.disableBye();
    } else if (command === 'enableBye') {
      $gameSystem.enableBye();
    }
  };

  //-----------------------------------------------------------------------------
  // Window_MenuCommand
  //

  var _Window_MenuCommand_addOriginalCommands = Window_MenuCommand.prototype.addOriginalCommands;
  Window_MenuCommand.prototype.addOriginalCommands = function () {
    var enabled = this.isByeEnabled();
    this.addCommand(TMPlugin.ByeCommand.ByeCommand, 'bye', enabled);
    _Window_MenuCommand_addOriginalCommands.call(this);
  };

  Window_MenuCommand.prototype.isByeEnabled = function () {
    return $gameParty.size() >= 2 && $gameSystem.isByeEnabled();
  };

  //-----------------------------------------------------------------------------
  // Window_MenuStatus
  //

  Window_MenuStatus.prototype.setByeMode = function (byeMode) {
    this._byeMode = byeMode;
  };

  var _Window_MenuStatus_processOk = Window_MenuStatus.prototype.processOk;
  Window_MenuStatus.prototype.processOk = function () {
    if (this._byeMode) {
      Window_Selectable.prototype.processOk.call(this);
    } else {
      _Window_MenuStatus_processOk.call(this);
    }
  };

  var _Window_MenuStatus_isCurrentItemEnabled = Window_MenuStatus.prototype.isCurrentItemEnabled;
  Window_MenuStatus.prototype.isCurrentItemEnabled = function () {
    if (this._byeMode) {
      var actor = $gameParty.members()[this.index()];
      return actor && !actor.actor().meta.disableBye;
    } else {
      return _Window_MenuStatus_isCurrentItemEnabled.call(this);
    }
  };

  var _Window_MenuStatus_playOkSound = Window_Selectable.prototype.playOkSound;
  Window_Selectable.prototype.playOkSound = function () {
    if (this._byeMode) {
      AudioManager.playSe(TMPlugin.ByeCommand.ByeSe);
    } else {
      _Window_MenuStatus_playOkSound.call(this);
    }
  };

  //-----------------------------------------------------------------------------
  // Scene_Menu
  //

  var _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
  Scene_Menu.prototype.createCommandWindow = function () {
    _Scene_Menu_createCommandWindow.call(this);
    this._commandWindow.setHandler('bye', this.commandBye.bind(this));
  };

  Scene_Menu.prototype.commandBye = function () {
    this._statusWindow.setByeMode(true);
    this._statusWindow.selectLast();
    this._statusWindow.activate();
    this._statusWindow.setHandler('ok', this.onByeOk.bind(this));
    this._statusWindow.setHandler('cancel', this.onByeCancel.bind(this));
  };

  Scene_Menu.prototype.onByeOk = function () {
    var index = this._statusWindow.index();
    var actor = $gameParty.members()[index];
    $gameParty.removeActor(actor.actorId());
    this._statusWindow.refresh();
    var n = $gameParty.size();
    if (n === 1) {
      this._commandWindow.refresh();
      this.onByeCancel();
    } else {
      if (this._statusWindow.index() >= n) {
        this._statusWindow.select(n - 1);
      }
      this._statusWindow.activate();
    }
  };

  Scene_Menu.prototype.onByeCancel = function () {
    this._statusWindow.deselect();
    this._statusWindow.setByeMode(false);
    this._commandWindow.activate();
  };

})();