code:
//=============================================================================
// NRP_EventCollisionEX.js
//=============================================================================
/*:
 * @target MV MZ
 * @plugindesc v1.03 Extends the collision detection for events.
 * @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
 * @url http://newrpg.seesaa.net/article/481944599.html
 *
 * @help Extends the collision detection for events.
 *
 * This is useful for large objects and huge monsters.
 * It also extends the range of event execution by triggers.
 *
 * Note that only squares can be extended.
 * It does not support flexible changes such as circles and crosses.
 *
 * ■Usage
 * There are three ways to extend the event collision detection.
 * Please use the method that is easiest for you.
 *
 * ◆SettingList
 * You can register the target file and collision detection
 * in the plugin parameter SettingList.
 * This is convenient because you do not need to register each event.
 *
 * ◆Note Field
 * Please enter the following in the Note field of the event.
 *
 * <CollisionEX:?,?,?,?>
 *
 * Please set a numerical value in the ?.
 * The collision detection will be extended
 * in the following order: down, left, right, up.
 *
 * ◆Annotations
 * You can also enter the same information
 * in the annotation at the top of the event page.
 * You can switch the status of this annotation for each current page.
 *
 * In addition, the order of priority is "Annotations > Notes > SettingList".
 * Please note that if the event itself has a collision detection specification,
 * the contents registered in the SettingList will be ignored.
 *
 * ■Notice
 * This plugin has a relatively large impact.
 * In order to avoid conflicts,
 * it is recommended to place it as high up as possible.
 *
 * If normal movement of large events is not necessary,
 * turning off "ConsiderEventMove" may stabilize the situation.
 *
 * Also, the behavior near the boundary of a looping map is
 * I gave up on implementing it
 * because it was too complicated. Sorry.......
 * So, there is no collision detection for the part of the loop
 * that extends beyond the loop.
 *
 * [Terms]
 * There are no restrictions.
 * Modification, redistribution freedom, commercial availability,
 * and rights indication are also optional.
 * The author is not responsible,
 * but will deal with defects to the extent possible.
 *
 * @param ConsiderEventMove
 * @type boolean
 * @default true
 * @desc The collision detection is also calculated when a large event moves. Turning it off will reduce the processing.
 *
 * @param SettingList
 * @type struct<Setting>[]
 * @default []
 * @desc List of settings related to collision detection.
 */
/*~struct~Setting:
 * @param File
 * @type file
 * @dir img/characters
 * @desc A file of character images to extend the collision detection.
 *
 * @param Index
 * @type number
 * @desc The index value of the image to use (0~7).
 * If blank, all will be used.
 *
 * @param CollisionDown
 * @type number
 * @desc This is an additional value for downward collision detection.
 *
 * @param CollisionLeft
 * @type number
 * @desc This is an additional value for leftward collision detection.
 *
 * @param CollisionRight
 * @type number
 * @desc This is an additional value for rightward collision detection.
 *
 * @param CollisionUp
 * @type number
 * @desc This is an additional value for upward collision detection.
 */

/*:ja
 * @target MV MZ
 * @plugindesc v1.03 イベントの当たり判定を拡張する。
 * @author 砂川赳（http://newrpg.seesaa.net/）
 * @url http://newrpg.seesaa.net/article/481944599.html
 *
 * @help イベントの当たり判定を拡張します。
 *
 * 大型のオブジェクトや巨大モンスターなどに便利です。
 * トリガーによるイベントの実行範囲も拡張されます。
 *
 * なお、拡張できる範囲は四角だけです。
 * 円や十字などの柔軟な変更には対応していません。
 *
 * ■使用方法
 * 三通りの方法によって、イベントの当たり判定を拡張できます。
 * 使いやすい方法をご利用ください。
 *
 * ◆設定リスト
 * プラグインパラメータの設定リストに、
 * 対象のファイルと当たり判定を登録できます。
 * いちいちイベント毎に登録する必要がないので便利です。
 *
 * ◆メモ欄
 * イベントのメモ欄に以下を記入してください。
 *
 * <CollisionEX:?,?,?,?>
 *
 * ?には数値を設定してください。
 * 下、左、右、上の順番に当たり判定が拡張されます。
 *
 * ◆注釈
 * また、イベントページ先頭の注釈に同様の記入しても有効となります。
 * こちらは現在のページ毎に状態を切り替えられます。
 *
 * なお、優先度は『注釈＞メモ欄＞設定リスト』の順番になっています。
 * イベント自体に指定がある場合、設定リストに登録した内容は
 * 無視されますのでご注意ください。
 *
 * ■注意点
 * 比較的、影響の大きいプラグインです。
 * 競合を避けるため、なるべく上方への配置を推奨します。
 *
 * 大型イベントの通常移動が不要な場合は、
 * 『大型イベントの移動を考慮』をオフにしておくと安定するかもしれません。
 *
 * また、ループするマップの境界付近での挙動については、
 * ややこしくて実装を断念しました。すまぬ……。
 * なので、ループの向こうへはみ出している部分には、
 * 当たり判定がありません。
 *
 * ■利用規約
 * 特に制約はありません。
 * 改変、再配布自由、商用可、権利表示も任意です。
 * 作者は責任を負いませんが、不具合については可能な範囲で対応します。
 *
 * @param ConsiderEventMove
 * @text 大型イベントの移動を考慮
 * @type boolean
 * @default true
 * @desc 大型イベントが移動した際も当たり判定を計算します。
 * オフにすると処理が軽減されます。
 *
 * @param SettingList
 * @text 設定リスト
 * @type struct<Setting>[]
 * @default []
 * @desc 当たり判定の設定の一覧です。
 */
/*~struct~Setting:ja
 * @param File
 * @text 画像ファイル
 * @type file
 * @dir img/characters
 * @desc 当たり判定を拡張するキャラクター画像のファイルです。
 *
 * @param Index
 * @text 画像インデックス
 * @type number
 * @desc 使用する画像のインデックス値（0~7）です。
 * 空欄なら全てを対象とします。
 *
 * @param CollisionDown
 * @text 当たり判定（下）
 * @type number
 * @desc 下方向への当たり判定の加算値です。
 *
 * @param CollisionLeft
 * @text 当たり判定（左）
 * @type number
 * @desc 左方向への当たり判定の加算値です。
 *
 * @param CollisionRight
 * @text 当たり判定（右）
 * @type number
 * @desc 右方向への当たり判定の加算値です。
 *
 * @param CollisionUp
 * @text 当たり判定（上）
 * @type number
 * @desc 上方向への当たり判定の加算値です。
 */

(function () {
    "use strict";

    /**
     * ●構造体（二重配列）をJSで扱えるように変換
     */
    function parseStruct2(arg) {
        var ret = [];

        JSON.parse(arg).forEach(function (str) {
            ret.push(JSON.parse(str));
        });

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

    const PLUGIN_NAME = "NRP_EventCollisionEX";
    const parameters = PluginManager.parameters(PLUGIN_NAME);
    const pConsiderMove = toBoolean(parameters["ConsiderEventMove"], true);
    const pSettingList = parseStruct2(parameters["SettingList"]);

    /**
     * ●効率化のため事前変換
     */
    for (const setting of pSettingList) {
        setting.file = setting.File;
        setting.index = toNumber(setting.Index);
        setting.collisionDown = toNumber(setting.CollisionDown, 0);
        setting.collisionLeft = toNumber(setting.CollisionLeft, 0);
        setting.collisionRight = toNumber(setting.CollisionRight, 0);
        setting.collisionUp = toNumber(setting.CollisionUp, 0);
    }

    //--------------------------------------------------------------
    // 基本処理
    //--------------------------------------------------------------

    /**
     * ●変数初期化
     */
    const _Game_CharacterBase_initMembers = Game_CharacterBase.prototype.initMembers;
    Game_CharacterBase.prototype.initMembers = function () {
        _Game_CharacterBase_initMembers.apply(this, arguments);

        // 当たり判定初期化
        this._collisionDown = 0;
        this._collisionLeft = 0;
        this._collisionRight = 0;
        this._collisionUp = 0;
    }

    /*
     * Game_Event.prototype.setImageが未定義の場合は事前に定義
     * ※これをしておかないと以後のGame_CharacterBase側への追記が反映されない。
     */
    if (Game_Event.prototype.setImage == Game_CharacterBase.prototype.setImage) {
        Game_Event.prototype.setImage = function (
            characterName,
            characterIndex
        ) {
            Game_CharacterBase.prototype.setImage.apply(this, arguments);
        }
    }

    /**
     * 【独自】画像を設定する。
     * ※Game_CharacterBaseの関数をオーバーライド
     */
    const _Game_Event_setImage = Game_Event.prototype.setImage;
    Game_Event.prototype.setImage = function (
        characterName,
        characterIndex
    ) {
        _Game_Event_setImage.apply(this, arguments);

        // 当たり判定初期化
        this._collisionDown = 0;
        this._collisionLeft = 0;
        this._collisionRight = 0;
        this._collisionUp = 0;

        // ページを取得できない場合は処理終了
        if (!this.page()) {
            return;
        }

        //-------------------------------------------
        // 当たり判定をイベントに設定する。
        // 優先度は『注釈＞メモ欄＞画像ファイル名』の順番
        //-------------------------------------------
        let collisionEX = undefined;

        // 注釈欄から読込を行う。
        const list = this.list();
        // 処理が存在する場合
        if (list && list.length > 0) {
            for (const line of list) {
                // 108:注釈開始, 408:注釈続き
                if (line.code == 108 || line.code == 408) {
                    // 注釈から<CollisionEX:*>を取得
                    collisionEX = getMetaValue(line.parameters[0]);
                    // 取得できればイベントに設定
                    if (collisionEX != undefined) {
                        setCollision(this, collisionEX);
                        return;
                    }

                    // それ以外はループ終了
                } else {
                    break;
                }
            }
        }

        // メモ欄に、当たり判定の設定があれば反映
        collisionEX = this.event().meta.CollisionEX;
        if (collisionEX != undefined) {
            setCollision(this, collisionEX);
            return;
        }

        // 設定されている画像名から判定
        for (const setting of pSettingList) {
            // 一致する画像名が存在した場合
            if (setting.file == this.characterName()) {
                // インデックスの指定がない場合は常に有効
                if (setting.index == undefined) {
                    setCollisionFromSetting(this, setting);
                    return;

                    // インデックスの指定がある場合
                } else if (setting.index == this.characterIndex()) {
                    setCollisionFromSetting(this, setting);
                    return;
                }
            }
        }
    };

    /**
     * ●<CollisionEX>の指定があれば取得
     */
    function getMetaValue(note) {
        // 注釈から<CollisionEX:*>を取得
        const strArr = note.match("<CollisionEX:(.+)>");
        // 取得できれば返す
        if (strArr) {
            return strArr[1];
        }
    }

    /**
     * ●各方向の当たり判定をイベントに設定する。
     */
    function setCollision(event, collisionEX) {
        // 下、左、右、上の順番
        const collisionArray = collisionEX.split(",");
        event._collisionDown = toNumber(collisionArray[0]);
        if (collisionArray.length >= 2) {
            event._collisionLeft = toNumber(collisionArray[1]);
        }
        if (collisionArray.length >= 3) {
            event._collisionRight = toNumber(collisionArray[2]);
        }
        if (collisionArray.length >= 4) {
            event._collisionUp = toNumber(collisionArray[3]);
        }
    }

    /**
     * ●各方向の当たり判定をイベントに設定する。
     * こちらは設定リストから読み込む場合です。
     */
    function setCollisionFromSetting(event, setting) {
        // 下、左、右、上の順番
        event._collisionDown = setting.collisionDown;
        event._collisionLeft = setting.collisionLeft;
        event._collisionRight = setting.collisionRight;
        event._collisionUp = setting.collisionUp;
    }

    /**
     * 【独自】衝突計算用の中央Ｘ座標
     */
    Game_CharacterBase.prototype.collisionCenterX = function (x) {
        return x + (this._collisionRight - this._collisionLeft) / 2;
    };

    /**
     * 【独自】衝突計算用の中央Ｙ座標
     */
    Game_CharacterBase.prototype.collisionCenterY = function (y) {
        return y + (this._collisionDown - this._collisionUp) / 2;
    };

    /**
     * 【独自】衝突計算用の横幅
     */
    Game_CharacterBase.prototype.collisionWidth = function () {
        return 1 + this._collisionRight + this._collisionLeft;
    };

    /**
     * 【独自】衝突計算用の縦幅
     */
    Game_CharacterBase.prototype.collisionHeight = function () {
        return 1 + this._collisionUp + this._collisionDown;
    };

    /**
     * 【独自】拡張を行っているかどうか？
     */
    Game_CharacterBase.prototype.isCollisionEX = function () {
        return this._collisionUp || this._collisionDown || this._collisionLeft || this._collisionRight;
    };

    //--------------------------------------------------------------
    // プレイヤーからイベントへの当たり判定
    // ※プレイヤーは拡張なしとして計算
    //--------------------------------------------------------------

    /**
     * 【上書】指定の座標に当たり判定のあるイベントを求める。
     */
    Game_Map.prototype.eventsXyNt = function (x, y) {
        return this.events().filter(event => event.posNtCollisionEX(x, y));
    };

    /**
     * 【独自】該当の座標にすり抜けではないイベントが存在するかどうか？
     * ※当たり判定の拡張を考慮
     */
    Game_CharacterBase.prototype.posNtCollisionEX = function (x, y) {
        return !this.isThrough() && this.posCollisionEX(x, y);
    };

    /**
     * 【独自】該当の座標に一致するかどうか？
     * ※当たり判定の拡張を考慮
     */
    Game_CharacterBase.prototype.posCollisionEX = function (x, y) {
        return this._x + this._collisionRight >= x && this.x - this._collisionLeft <= x
            && this._y + this._collisionDown >= y && this._y - this._collisionUp <= y;
    };

    //--------------------------------------------------------------
    // 飛行船の着陸判定
    //--------------------------------------------------------------

    /**
     * ●乗降判定
     */
    const _Game_Vehicle_isLandOk = Game_Vehicle.prototype.isLandOk;
    Game_Vehicle.prototype.isLandOk = function (x, y, d) {
        // 飛行船の場合
        if (this.isAirship()) {
            // イベントが存在する場合は着陸禁止
            if ($gameMap.eventsXyCollisionEX(x, y).length > 0) {
                return false;
            }
        }

        return _Game_Vehicle_isLandOk.apply(this, arguments);
    };

    //--------------------------------------------------------------
    // イベントからイベントへの当たり判定
    //--------------------------------------------------------------

    /**
     * 【上書】指定の座標に当たり判定のあるイベントが存在するか？
     */
    Game_Event.prototype.isCollidedWithEvents = function (x, y) {
        const events = this.eventsXyNt(x, y);
        return events.length > 0;
    };

    /**
     * 【独自】指定の座標に当たり判定のあるイベントを求める。
     */
    Game_Event.prototype.eventsXyNt = function (x, y) {
        // Game_Mapと異なり、自分自身は判定から除外する。
        // さもないと、自分の当たり判定で動けなくなる。
        return $gameMap.events().filter(event => event != this && event.posNtCollisionEXEvent(x, y, this));
    };

    /**
     * 【独自】該当の座標にすり抜けではないイベントが存在するかどうか？
     * ※当たり判定の拡張を考慮
     */
    Game_Event.prototype.posNtCollisionEXEvent = function (x, y, event) {
        return !this.isThrough() && this.posCollisionEXEvent(x, y, event);
    };

    /**
     * 【独自】該当の座標に一致するかどうか？
     * ※当たり判定の拡張を考慮
     */
    Game_CharacterBase.prototype.posCollisionEXEvent = function (x, y, event) {
        // 大型イベントの移動を考慮しない場合
        if (!pConsiderMove) {
            return this.posCollisionEX(x, y);
        }

        //-----------------------------------
        // 引数のイベントとの当たり判定を計算
        //-----------------------------------

        // 中央座標を求める
        const aCenterX = this.collisionCenterX(this._x);
        const aCenterY = this.collisionCenterY(this._y);
        const bCenterX = event.collisionCenterX(x);
        const bCenterY = event.collisionCenterY(y);

        // 横幅・縦幅を計算
        const aWidth = this.collisionWidth();
        const aHeight = this.collisionHeight();
        const bWidth = event.collisionWidth();
        const bHeight = event.collisionHeight();

        // 中心同士の距離を計算
        const distanceCenterX = Math.abs(aCenterX - bCenterX);
        const distanceCenterY = Math.abs(aCenterY - bCenterY);

        // 横幅・縦幅を考慮した距離
        const distanceX = distanceCenterX - (aWidth + bWidth) / 2;
        const distanceY = distanceCenterY - (aHeight + bHeight) / 2;

        // 両方がマイナスなら重なっている
        if (distanceX < 0 && distanceY < 0) {
            return true;
        }

        return false;
    };

    //--------------------------------------------------------------
    // イベントからプレイヤー＆フォロワーへの当たり判定
    //--------------------------------------------------------------

    /**
     * イベントが移動しない想定なら不要
     */
    if (pConsiderMove) {
        /**
         * ●プレイヤー＆フォロワーとの衝突判定
         */
        Game_Event.prototype.isCollidedWithPlayerCharacters = function (x, y) {
            // イベントが通常キャラと同じ以外なら処理しない。
            if (!this.isNormalPriority()) {
                return false;
            }

            // プレイヤーがすり抜けなら処理しない。
            if ($gamePlayer.isThrough()) {
                return false;
            }

            // プレイヤーとフォロワーに衝突するかどうか？
            return $gamePlayer.posCollisionEXEvent(x, y, this)
                || $gamePlayer._followers.isSomeoneCollidedExEvent(x, y, this);
        };

        /**
         * 【独自】イベントとフォロワーとの衝突判定
         */
        Game_Followers.prototype.isSomeoneCollidedExEvent = function (x, y, event) {
            return this.visibleFollowers().some(follower => follower.posCollisionEXEvent(x, y, event));
        };
    }

    //--------------------------------------------------------------
    // イベントからマップへの当たり判定
    //--------------------------------------------------------------

    /**
     * イベントが移動しない想定なら不要
     */
    if (pConsiderMove) {
        /*
        * Game_Event.prototype.canPassが未定義の場合は事前に定義
        * ※これをしておかないと以後のGame_CharacterBase側への追記が反映されない。
        */
        if (Game_Event.prototype.canPass == Game_CharacterBase.prototype.canPass) {
            Game_Event.prototype.canPass = function (x, y, d) {
                return Game_CharacterBase.prototype.canPass.apply(this, arguments);
            }
        }

        /**
         * 【独自】イベントからマップへの当たり判定
         * ※Game_CharacterBaseの関数をオーバーライド
         */
        const _Game_Event_canPass = Game_Event.prototype.canPass;
        Game_Event.prototype.canPass = function (x, y, d) {
            const x2 = $gameMap.roundXWithDirection(x, d);
            const y2 = $gameMap.roundYWithDirection(y, d);
            if (!this.isMapValid(x2, y2)) {
                return false;
            }

            return _Game_Event_canPass.apply(this, arguments);
        };

        /**
         * 【独自】イベントの当たり判定を考慮して、マップの有効無効を確認
         */
        Game_Event.prototype.isMapValid = function (x, y) {
            let horizontalOk = false;
            let verticalOk = false;

            // 横ループのマップなら、横チェックは行わない。
            if ($gameMap.isLoopHorizontal()) {
                horizontalOk = true;

                // 横範囲に収まっているか？
            } else if (x - this._collisionLeft >= 0 && x + this._collisionRight < $gameMap.width()) {
                horizontalOk = true;
            }

            // 縦ループのマップなら、縦チェックは行わない。
            if ($gameMap.isLoopVertical()) {
                verticalOk = true;

                // 縦範囲に収まっているか？
            } else if (y - this._collisionUp >= 0 && y + this._collisionDown < $gameMap.height()) {
                verticalOk = true;
            }

            return horizontalOk && verticalOk;
        };

        /**
         * ●イベントからマップへの当たり判定
         * ※イベント限定の機能なのでGame_Eventにしたかったけど、
         * 　『OverpassTile.js』辺りと併用できなくなるのでここに実装。
         */
        const _Game_CharacterBase_isMapPassable = Game_CharacterBase.prototype.isMapPassable;
        Game_CharacterBase.prototype.isMapPassable = function (x, y, d) {
            // イベント以外は元の処理を使用
            if (!this.event) {
                return _Game_CharacterBase_isMapPassable.apply(this, arguments);
            }

            // 先端座標を取得
            const tipX = this.collisionTipX(x, d);
            const tipY = this.collisionTipY(y, d);

            // 先端の移動先座標を取得
            const tipX2 = $gameMap.roundXWithDirection(tipX, d);
            const tipY2 = $gameMap.roundYWithDirection(tipY, d);
            const d2 = this.reverseDir(d);

            return this.isPassableWide(tipX, tipY, d) && this.isPassableWide(tipX2, tipY2, d2);
        };

        /**
         * 【独自】イベントがタイルを通過できるか？
         * ※イベントの進路に対する水平サイズを考慮
         */
        Game_CharacterBase.prototype.isPassableWide = function (x, y, d) {
            // 上下
            if (d === 2 || d === 8) {
                const startX = x - this._collisionLeft;
                const endX = x + this._collisionRight;

                for (let tmpX = startX; tmpX <= endX; tmpX++) {
                    // 通行禁止に該当があれば処理終了
                    if (!$gameMap.checkPassage(tmpX, y, (1 << (d / 2 - 1)) & 0x0f)) {
                        return false;
                    }
                }

                // 通行可能
                return true;

                // 左右
            } else if (d === 4 | d === 6) {
                const startY = y - this._collisionUp;
                const endY = y + this._collisionDown;

                for (let tmpY = startY; tmpY <= endY; tmpY++) {
                    // 通行禁止に該当があれば処理終了
                    if (!$gameMap.checkPassage(x, tmpY, (1 << (d / 2 - 1)) & 0x0f)) {
                        return false;
                    }
                }

                // 通行可能
                return true;
            }

            // とりあえずそのまま
            return $gameMap.checkPassage(x, y, (1 << (d / 2 - 1)) & 0x0f);
        };
    }

    /**
     * 【独自】衝突時の先端となるＸ座標
     */
    Game_CharacterBase.prototype.collisionTipX = function (x, d) {
        // 左
        if (d === 4) {
            x -= this._collisionLeft;

            // 右
        } else if (d === 6) {
            x += this._collisionRight;
        }
        return x;
    };

    /**
     * 【独自】衝突時の先端となるＹ座標
     */
    Game_CharacterBase.prototype.collisionTipY = function (y, d) {
        // 下
        if (d === 2) {
            y += this._collisionDown;

            // 上
        } else if (d === 8) {
            y -= this._collisionUp;
        }
        return y;
    };

    //--------------------------------------------------------------
    // イベント起動
    //--------------------------------------------------------------

    /**
     * 【上書】マップイベントの起動
     */
    Game_Player.prototype.startMapEvent = function (x, y, triggers, normal) {
        if (!$gameMap.isEventRunning()) {
            for (const event of $gameMap.eventsXyCollisionEX(x, y)) {
                if (
                    event.isTriggerIn(triggers) &&
                    event.isNormalPriority() === normal
                ) {
                    event.start();
                }
            }
        }
    };

    /**
     * 【独自】指定の座標に存在するイベントを求める。
     */
    Game_Map.prototype.eventsXyCollisionEX = function (x, y) {
        return this.events().filter(event => event.posCollisionEX(x, y));
    };

    /**
     * イベントから接触の場合
     * ※イベントが移動しない想定なら不要
     */
    if (pConsiderMove) {
        /*
        * Game_Event.prototype.checkEventTriggerTouchFrontが未定義の場合は事前に定義
        * ※これをしておかないと以後のGame_CharacterBase側への追記が反映されない。
        */
        if (Game_Event.prototype.checkEventTriggerTouchFront == Game_CharacterBase.prototype.checkEventTriggerTouchFront) {
            Game_Event.prototype.checkEventTriggerTouchFront = function (d) {
                Game_CharacterBase.prototype.checkEventTriggerTouchFront.apply(this, arguments);
            }
        }

        // 一時的に保持する向き
        let mTmpD = 0;

        /**
         * 【独自】イベントから接触による起動判定１
         * ※Game_CharacterBaseの関数をオーバーライド
         */
        const _Game_Event_checkEventTriggerTouchFront = Game_Event.prototype.checkEventTriggerTouchFront;
        Game_Event.prototype.checkEventTriggerTouchFront = function (d) {
            mTmpD = d;
            _Game_Event_checkEventTriggerTouchFront.apply(this, arguments);
        };

        /**
         * ●イベントから接触による起動判定１
         */
        const _Game_Event_checkEventTriggerTouch = Game_Event.prototype.checkEventTriggerTouch;
        Game_Event.prototype.checkEventTriggerTouch = function (x, y) {
            // 拡張対象外の場合は元の処理
            if (!this.isCollisionEX()) {
                _Game_Event_checkEventTriggerTouch.apply(this, arguments);
                return;
            }

            // 本来引数に存在しないdを取得
            const d = mTmpD;

            // 先端座標を取得
            const tipX = this.collisionTipX(this._x, d);
            const tipY = this.collisionTipY(this._y, d);

            // 先端の向いている座標を取得
            const x2 = $gameMap.roundXWithDirection(tipX, d);
            const y2 = $gameMap.roundYWithDirection(tipY, d);

            // イベント確認＆起動
            this.checkEventTriggerTouchCollisionEX(x2, y2, d);
        };

        /**
         * 【独自】イベントから接触による起動判定２
         */
        Game_Event.prototype.checkEventTriggerTouchCollisionEX = function (x, y, d) {
            if (!$gameMap.isEventRunning()) {
                if (this._trigger === 2 && $gamePlayer.posTriggerTouchCollisionEX(x, y, d, this)) {
                    if (!this.isJumping() && this.isNormalPriority()) {
                        this.start();
                    }
                }
            }
        };

        /**
         * 【独自】イベントから接触の対象座標に一致するかどうか？
         * ※当たり判定の拡張を考慮
         */
        Game_Player.prototype.posTriggerTouchCollisionEX = function (x, y, d, event) {
            // 進路が上下
            if (d === 2 || d === 8) {
                if (this.y == y) {
                    const startX = x - event._collisionLeft;
                    const endX = x + event._collisionRight;

                    // 該当範囲のＸ座標を確認
                    for (let tmpX = startX; tmpX <= endX; tmpX++) {
                        // 該当があればtrue
                        if (this.x == tmpX) {
                            return true;
                        }
                    }
                }

                // 進路が左右
            } else if (d === 4 | d === 6) {
                if (this.x == x) {
                    const startY = y - this._collisionUp;
                    const endY = y + this._collisionDown;

                    // 該当範囲のＹ座標を確認
                    for (let tmpY = startY; tmpY <= endY; tmpY++) {
                        // 該当があればtrue
                        if (this.y == tmpY) {
                            return true;
                        }
                    }
                }
            }

            // それ以外は通常の座標一致
            return this.pos(x, y);
        };
    }

})();


code:
//=============================================================================
// NRP_VehiclePassage.js
//=============================================================================
/*:
 * @target MV MZ
 * @plugindesc v1.02 Extends the passage & get on/off decision for vehicles.
 * @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
 * @url http://newrpg.seesaa.net/article/482385836.html
 *
 * @help Extends the passage & get on/off decision for vehicles.
 *
 * You can also fine-tune the settings by using TerrainTags,
 * RegionIDs, TileIDs and AutoTileTypes as conditions.
 *
 * If you add a "SettingId" to the settings you have created,
 * you can call up the settings for each tileset.
 *
 * Depending on the plugin parameters,
 * getting on and off can be prohibited in principle.
 * This is useful if you want to be able to get on and off only in certain terrains.
 * For example, a ship that can only arrive and depart at a pier,
 * or a black bird that can only land in a forest, can be realized.
 *
 * In addition, the altitude of the airship can be set.
 * This can be used to create low-flying vehicles
 * that cannot pass through mountainous areas.
 *
 * [Usage]
 * Set the passage & get on/off decision
 * in each SettingList of plugin parameters.
 * It is possible to switch between enabling it for all tilesets
 * and calling it for each tileset by using the parameters in the list.
 *
 * [Tilesets Notes]
 * If you want to set it for each tile set,
 * specify the following in the Note field.
 * <VehiclePassage:?>
 *
 * ? is the SettingId registered in the SettingList.
 * It is also possible to specify multiple settings by separating them with commas.
 * <VehiclePassage:A,B,C>
 *
 * [Terms]
 * There are no restrictions.
 * Modification, redistribution freedom, commercial availability,
 * and rights indication are also optional.
 * The author is not responsible,
 * but will deal with defects to the extent possible.
 *
 * @param BoatSettingList
 * @type struct<Setting>[]
 * @desc This is a list of Boat's passage & get on/off settings.
 *
 * @param ShipSettingList
 * @type struct<Setting>[]
 * @desc This is a list of Ship's passage & get on/off settings.
 *
 * @param AirshipSettingList
 * @type struct<Setting>[]
 * @desc This is a list of Airship's passage & get on/off settings.
 *
 * @param BoatNoGetOff
 * @type boolean
 * @default false
 * @desc In principle, getting on and off the Boat is prohibited.
 * Please define exceptions in the SettingList.
 *
 * @param ShipNoGetOff
 * @type boolean
 * @default false
 * @desc In principle, getting on and off the Ship is prohibited.
 * Please define exceptions in the SettingList.
 *
 * @param AirshipNoGetOff
 * @type boolean
 * @default false
 * In principle, getting on and off the Airship is prohibited.
 * Please define exceptions in the SettingList.
 *
 * @param AirshipAltitude
 * @type number
 * @min 0 @max 999
 * @desc The altitude of the airship.
 * Default is 48.
 */
/*~struct~Setting:
 * @param SettingId
 * @type string
 * @desc Identifier used to call from the note field of a tileset. This is not required if "ValidAllTilesets" is on.
 *
 * @param Memo
 * @type string
 * @desc This is a memo for identification.
 * Please give it an easy-to-understand name.
 *
 * @param ValidAllTilesets
 * @type boolean
 * @default false
 * @desc Enables the setting for all tilesets. If turned off, the setting can be applied to individual tilesets.
 *
 * @param <Condition>
 *
 * @param TerrainTag
 * @parent <Condition>
 * @type string
 * @desc Specify the Terrain Tag (1~7) to be targeted.
 * Multiple tags can be specified. (Example: 1,3~5)
 *
 * @param RegionId
 * @parent <Condition>
 * @type string
 * @desc Specify the Region Id (1~255) to be targeted.
 * Multiple ids can be specified. (Example: 1,3~5)
 *
 * @param AutotileType
 * @parent <Condition>
 * @type string
 * @desc Specify the Autotile Type to be targeted.
 * Multiple types can be specified. (Example: 1,3~5)
 *
 * @param TileId
 * @parent <Condition>
 * @type string
 * @desc Specify the Tile Id to be targeted.
 * Multiple ids can be specified. (Example: 1,3~5)
 *
 * @param <PassageSetting>
 *
 * @param CanPass
 * @parent <PassageSetting>
 * @type boolean
 * @desc Is it passable?
 *
 * @param CanGetOn
 * @parent <PassageSetting>
 * @type boolean
 * @desc Is it possible to get in and out?
 */

/*:ja
 * @target MV MZ
 * @plugindesc v1.02 乗物の通行＆乗降判定を拡張します。
 * @author 砂川赳（http://newrpg.seesaa.net/）
 * @url http://newrpg.seesaa.net/article/482385836.html
 *
 * @help 乗物の通行＆乗降判定を拡張します。
 *
 * 地形タグやリージョンＩＤ、タイルＩＤやオートタイルタイプを
 * 条件にして細かく設定できます。
 * 作成した設定に『設定ＩＤ』を付加すれば、
 * タイルセット毎に設定を呼び出すことも可能です。
 *
 * プラグインパラメータによって、乗降を原則禁止にすることもできます。
 * 桟橋でのみ発着できる船や、森のみ着陸できる黒い馬鳥など、
 * 特定の地形でのみ乗降できるようにしたい場合は便利です。
 *
 * ついでに飛行船の高度も設定可能です。
 * 山岳地帯を通れない低空飛行の乗物などが実現できます。
 *
 * ■使用方法
 * プラグインパラメータの各設定リストに、通行＆乗降判定を設定してください。
 * 全タイルセットで有効とするか、タイルセット毎に呼び出すかを、
 * リスト内のパラメータによって切り替え可能です。
 *
 * ■タイルセットのメモ欄
 * タイルセット毎に設定する場合はメモ欄に以下を指定してください。
 * <VehiclePassage:?>
 *
 * ?の部分が設定リストに登録した『設定ＩＤ』となります。
 * また、カンマ区切りによって複数指定も可能です。
 * <VehiclePassage:A,B,C>
 *
 * ■利用規約
 * 特に制約はありません。
 * 改変、再配布自由、商用可、権利表示も任意です。
 * 作者は責任を負いませんが、不具合については可能な範囲で対応します。
 *
 * @param BoatSettingList
 * @text 小型船の設定リスト
 * @type struct<Setting>[]
 * @desc 小型船の通行＆乗降設定の一覧です。
 *
 * @param ShipSettingList
 * @text 大型船の設定リスト
 * @type struct<Setting>[]
 * @desc 大型船の通行＆乗降設定の一覧です。
 *
 * @param AirshipSettingList
 * @text 飛行船の設定リスト
 * @type struct<Setting>[]
 * @desc 飛行船の通行＆乗降設定の一覧です。
 *
 * @param BoatNoGetOff
 * @text 小型船の原則乗降禁止
 * @type boolean
 * @default false
 * @desc 小型船の乗降を原則禁止します。
 * 設定リストに定義した地形のみ乗降できます。
 *
 * @param ShipNoGetOff
 * @text 大型船の原則乗降禁止
 * @type boolean
 * @default false
 * @desc 大型船の乗降を原則禁止します。
 * 設定リストに定義した地形のみ乗降できます。
 *
 * @param AirshipNoGetOff
 * @text 飛行船の原則乗降禁止
 * @type boolean
 * @default false
 * @desc 飛行船の乗降を原則禁止します。
 * 設定リストに定義した地形のみ乗降できます。
 *
 * @param AirshipAltitude
 * @text 飛行船の高度
 * @type number
 * @min 0 @max 999
 * @desc 飛行船の高度です。
 * デフォルトは48となります。
 *
 * @param AirshipSameAsCharacters
 * @text 飛行船を通常キャラと同じに
 * @type boolean
 * @default false
 * @desc 飛行船のプライオリティタイプを『通常キャラと同じ』に変更します。
 */
/*~struct~Setting:ja
 * @param SettingId
 * @text 設定ＩＤ
 * @type string
 * @desc タイルセットのメモ欄からの呼び出しに使う識別子です。
 * 『全タイルセットで有効』がオンの場合は不要です。
 *
 * @param Memo
 * @text メモ
 * @type string
 * @desc 判別用のメモです。
 * 分かりやすい名前を付けてください。
 *
 * @param ValidAllTilesets
 * @text 全タイルセットで有効
 * @type boolean
 * @default false
 * @desc 設定を全てのタイルセットで有効にします。
 * オフにした場合は、個別のタイルセットに設定できます。
 *
 * @param <Condition>
 * @text ＜条件＞
 *
 * @param TerrainTag
 * @text 地形タグ
 * @parent <Condition>
 * @type string
 * @desc 対象とする地形タグ（1~7）を指定します。
 * 複数指定も可能です。（例：1,3~5）
 *
 * @param RegionId
 * @text リージョンＩＤ
 * @parent <Condition>
 * @type string
 * @desc 対象とするリージョン（1~255）を指定します。
 * 複数指定も可能です。（例：1,3~5）
 *
 * @param AutotileType
 * @text オートタイルタイプ
 * @parent <Condition>
 * @type string
 * @desc 対象とするオートタイルタイプを指定します。
 * 複数指定も可能です。（例：1,3~5）
 *
 * @param TileId
 * @text タイルＩＤ
 * @parent <Condition>
 * @type string
 * @desc 対象とするタイルＩＤを指定します。
 * 複数指定も可能です。（例：1,3~5）
 *
 * @param <PassageSetting>
 * @text ＜通行設定＞
 *
 * @param CanPass
 * @text 通行可能
 * @parent <PassageSetting>
 * @type boolean
 * @desc 通行可能かどうか？
 *
 * @param CanGetOn
 * @text 乗降可能
 * @parent <PassageSetting>
 * @type boolean
 * @desc 乗降可能かどうか？
 */
(function () {
    "use strict";

    function toBoolean(val, def) {
        // 空白なら初期値を返す
        if (val === "" || val === undefined) {
            return def;

            // 既にboolean型なら、そのまま返す
        } else if (typeof val === "boolean") {
            return val;
        }
        // 文字列ならboolean型に変換して返す
        return val.toLowerCase() == "true";
    }
    function toNumber(str, def) {
        if (str == undefined || str == "") {
            return def;
        }
        return isNaN(str) ? def : +(str || def);
    }

    /**
     * ●構造体（二重配列）をJSで扱えるように変換
     */
    function parseStruct2(arg) {
        var ret = [];

        if (arg) {
            JSON.parse(arg).forEach(function (str) {
                ret.push(JSON.parse(str));
            });
        }

        return ret;
    }

    /**
     * ●引数を元に配列を取得する。
     */
    function makeArray(values) {
        const results = [];
        if (!values) {
            return undefined;
        }

        // カンマ区切りでループ
        for (let value of values.split(",")) {
            // 空白除去
            value = value.trim();
            // 1~5というように範囲指定の場合
            // ※~が存在する。
            if (value.indexOf("~") >= 0) {
                const range = value.split("~");
                const rangeStart = eval(range[0]);
                const rangeEnd = eval(range[1]);

                // 指定範囲で実行
                // 開始のほうが終了より大きい場合は反対に実行
                if (rangeEnd < rangeStart) {
                    for (let i = rangeStart; i >= rangeEnd; i--) {
                        results.push(eval(i));
                    }
                } else {
                    for (let i = rangeStart; i <= rangeEnd; i++) {
                        results.push(eval(i));
                    }
                }

                // 通常時
            } else {
                // 数値変換するためeval
                results.push(eval(value));
            }
        }
        return results;
    }

    const PLUGIN_NAME = "NRP_VehiclePassage";
    const parameters = PluginManager.parameters(PLUGIN_NAME);
    const pBoatSettingList = parseStruct2(parameters["BoatSettingList"]);
    const pShipSettingList = parseStruct2(parameters["ShipSettingList"]);
    const pAirshipSettingList = parseStruct2(parameters["AirshipSettingList"]);
    const pBoatNoGetOff = toBoolean(parameters["BoatNoGetOff"], false);
    const pShipNoGetOff = toBoolean(parameters["ShipNoGetOff"], false);
    const pAirshipNoGetOff = toBoolean(parameters["AirshipNoGetOff"], false);
    const pAirshipAltitude = toNumber(parameters["AirshipAltitude"]);
    const pAirshipSameAsCharacters = toBoolean(parameters["AirshipSameAsCharacters"], false);

    /**
     * ●通行リストを使用できる形式に設定
     */
    function setSettingList(settingList, type) {
        for (const setting of settingList) {
            setting.settingId = setting.SettingId;
            setting.vehicleType = type;
            setting.validAllTilesets = toBoolean(setting.ValidAllTilesets, false);
            setting.terrainTags = makeArray(setting.TerrainTag);
            setting.regionIds = makeArray(setting.RegionId);
            setting.autotileTypes = makeArray(setting.AutotileType);
            setting.tileIds = makeArray(setting.TileId);
            setting.canPass = toBoolean(setting.CanPass);
            setting.canGetOn = toBoolean(setting.CanGetOn);
        }
    }

    setSettingList(pBoatSettingList, "boat");
    setSettingList(pShipSettingList, "ship");
    setSettingList(pAirshipSettingList, "airship");

    // リストを全連結
    const pSettingList = pBoatSettingList.concat(pShipSettingList).concat(pAirshipSettingList);

    //----------------------------------------
    // 通行判定
    //----------------------------------------

    /**
     * ●小型船の通行判定
     */
    const _Game_Map_isBoatPassable = Game_Map.prototype.isBoatPassable;
    Game_Map.prototype.isBoatPassable = function (x, y) {
        // 条件設定が一つでも存在する場合
        if (existSetting()) {
            const setting = getMatchSetting(x, y);
            // 条件設定が取得できた場合、通行判定を適用
            if (setting && setting.canPass !== undefined) {
                return setting.canPass;
            }
        }

        return _Game_Map_isBoatPassable.apply(this, arguments);
    };

    /**
     * ●大型船の通行判定
     */
    const _Game_Map_isShipPassable = Game_Map.prototype.isShipPassable;
    Game_Map.prototype.isShipPassable = function (x, y) {
        // 条件設定が一つでも存在する場合
        if (existSetting()) {
            const setting = getMatchSetting(x, y);
            // 条件設定が取得できた場合、通行判定を適用
            if (setting && setting.canPass !== undefined) {
                return setting.canPass;
            }
        }

        return _Game_Map_isShipPassable.apply(this, arguments);
    };

    /**
     * ●通行判定
     * ※Game_CharacterBase.prototype.canPassのオーバーライド
     * ※飛行船はすり抜け属性をデフォルトで持っているため、
     * 　Game_Vehicle.prototype.isMapPassableを通過しない。
     * 　そのためここで実装する。
     */
    const _Game_Player_canPass = Game_Player.prototype.canPass;
    Game_Player.prototype.canPass = function (x, y, d) {
        // プレイヤーが飛行船に乗っている場合
        if (this.isInAirship()) {
            const x2 = $gameMap.roundXWithDirection(x, d);
            const y2 = $gameMap.roundYWithDirection(y, d);
            return isAirShipPassable(x2, y2);
        }

        return _Game_Player_canPass.apply(this, arguments);
    };

    /**
     * ●飛行船の通行判定
     */
    function isAirShipPassable(x, y) {
        // 条件設定が一つでも存在する場合
        if (existSetting()) {
            const setting = getMatchSetting(x, y);
            // 条件設定が取得できた場合、通行判定を適用
            if (setting && setting.canPass !== undefined) {
                return setting.canPass;
            }
        }

        return true;
    }

    //----------------------------------------
    // 乗降判定
    //----------------------------------------

    const _Game_Vehicle_isLandOk = Game_Vehicle.prototype.isLandOk;
    Game_Vehicle.prototype.isLandOk = function (x, y, d) {
        // 通過判定、イベントとの衝突判定などをここで参照
        const ret = _Game_Vehicle_isLandOk.apply(this, arguments);

        // 飛行船ではない
        if (ret && !this.isAirship()) {
            // 条件設定が一つでも存在する場合
            if (existSetting()) {
                const x2 = $gameMap.roundXWithDirection(x, d);
                const y2 = $gameMap.roundYWithDirection(y, d);

                const setting = getMatchSetting(x2, y2);
                // 条件設定が取得できた場合、乗降判定を適用
                if (setting && setting.canGetOn !== undefined) {
                    return setting.canGetOn;
                }
            }

            // 原則禁止の場合はfalse固定
            if (this.isBoat() && pBoatNoGetOff) {
                return false;
            } else if (this.isShip() && pShipNoGetOff) {
                return false;
            }
        }

        return ret;
    };

    /**
     * ●飛行船の乗降判定
     */
    const _Game_Map_isAirshipLandOk = Game_Map.prototype.isAirshipLandOk;
    Game_Map.prototype.isAirshipLandOk = function (x, y) {
        // 条件設定が一つでも存在する場合
        if (existSetting()) {
            const setting = getMatchSetting(x, y);
            // 条件設定が取得できた場合、乗降判定を適用
            if (setting && setting.canGetOn !== undefined) {
                return setting.canGetOn;
            }
        }

        // 原則禁止の場合はfalse固定
        if (pAirshipNoGetOff) {
            return false;
        }

        return _Game_Map_isAirshipLandOk.apply(this, arguments);
    };

    //----------------------------------------
    // マップ切替時
    //----------------------------------------

    /**
     * ●マップ情報の設定
     */
    const _Game_Map_setup = Game_Map.prototype.setup;
    Game_Map.prototype.setup = function (mapId) {
        _Game_Map_setup.apply(this, arguments);

        setTilesetInfo();
    };

    /**
     * ●タイルセットの変更
     */
    const _Game_Map_changeTileset = Game_Map.prototype.changeTileset;
    Game_Map.prototype.changeTileset = function (tilesetId) {
        _Game_Map_changeTileset.apply(this, arguments);

        setTilesetInfo();
    };

    /**
     * ●タイルセットに情報を設定
     * ※常駐処理は避けて、極力処理はこちらでやっておく。
     */
    function setTilesetInfo() {
        const tileset = $gameMap.tileset();
        if (!tileset) {
            return;
        }

        // 設定リスト
        const vehiclePassageSettingList = [];

        // 条件に一致する設定を抽出する。
        for (const setting of pSettingList) {
            // どのタイルセットでも常に有効の場合
            if (setting.validAllTilesets) {
                // 追加して次へ
                vehiclePassageSettingList.push(setting);
                continue;
            }

            // 有効な設定ＩＤかどうかを確認
            if (isValidSetting(setting.settingId, tileset)) {
                // 追加して次へ
                vehiclePassageSettingList.push(setting);
            }
        }

        // タイルセットに設定
        tileset.vehiclePassageSettingList = vehiclePassageSettingList;
    }

    /**
     * ●通行設定が指定のタイルセットで有効か？
     */
    function isValidSetting(settingId, tileset) {
        if (settingId === undefined) {
            return false;
        }

        const setting = tileset.meta.VehiclePassage;
        if (setting) {
            // カンマ区切りで分解
            const settingArray = setting.split(",");
            // 含まれていればtrue
            return settingArray.includes(settingId);
        }
        return false;
    }

    //----------------------------------------
    // 飛行船の最大高度
    //----------------------------------------

    if (pAirshipAltitude !== undefined) {
        /**
         * 【上書】飛行船の最大高度
         */
        Game_Vehicle.prototype.maxAltitude = function () {
            return pAirshipAltitude;
        };

        /**
         * ●飛行船の更新
         */
        const _Game_Vehicle_updateAirship = Game_Vehicle.prototype.updateAirship;
        Game_Vehicle.prototype.updateAirship = function () {
            _Game_Vehicle_updateAirship.apply(this, arguments);

            // 最大高度が0以下の場合、プライオリティタイプを下げないように調整
            if (this.maxAltitude() <= 0) {
                if (this._driving) {
                    this.setPriorityType(2);
                    this.setStepAnime(true);
                } else {
                    this.setPriorityType(0);
                    this.setStepAnime(false);
                }
            }
        };
    }

    //----------------------------------------
    // 飛行船のプライオリティタイプ
    //----------------------------------------

    if (pAirshipSameAsCharacters) {
        const _Game_Vehicle_refresh = Game_Vehicle.prototype.refresh;
        Game_Vehicle.prototype.refresh = function () {
            _Game_Vehicle_refresh.apply(this, arguments);

            if (this.isAirship() && !this._driving) {
                // 飛行中でない場合は通常キャラと同じに
                this.setPriorityType(1);
            }
        };

        const _Game_Vehicle_updateAirship = Game_Vehicle.prototype.updateAirship;
        Game_Vehicle.prototype.updateAirship = function () {
            _Game_Vehicle_updateAirship.apply(this, arguments);

            if (this.isLowest()) {
                // 飛行中でない場合は通常キャラと同じに
                this.setPriorityType(1);
            }
        };
    }

    //----------------------------------------
    // ゲームロード時
    //----------------------------------------

    // ロード時判定フラグ
    let mIsGameLoad = false;

    /**
     * ●ロード時のデータ展開
     */
    const _DataManager_extractSaveContents = DataManager.extractSaveContents;
    DataManager.extractSaveContents = function (contents) {
        _DataManager_extractSaveContents.apply(this, arguments);
        // ロード時判定フラグ
        mIsGameLoad = true;
    };

    /**
     * ●マップデータのロード完了時に通行情報を反映
     */
    const _DataManager_onLoad = DataManager.onLoad;
    DataManager.onLoad = function (object) {
        _DataManager_onLoad.apply(this, arguments);

        // ゲームロード時
        if (object === $dataMap && $gameMap && mIsGameLoad) {
            // 通行情報を反映
            setTilesetInfo();
            // 用済みなのでフラグ初期化
            mIsGameLoad = false;
        }
    };

    //----------------------------------------
    // その他共通関数
    //----------------------------------------

    /**
     * ●現在位置に一致する通行設定を取得する。
     */
    function getMatchSetting(x, y) {
        const tileset = $gameMap.tileset();

        // 設定がなければundefined
        if (!tileset.vehiclePassageSettingList) {
            return undefined;
        }

        // なるべく負荷をかけないよう値を一度だけ取得する。
        let terrainTag;
        let regionId;
        let autotileType;
        let tileId;

        // 設定を１つずつ確認
        for (const setting of tileset.vehiclePassageSettingList) {
            let noMatch = false;

            // 該当の乗物以外は無視
            if ($gamePlayer.vehicle()._type != setting.vehicleType) {
                continue;
            }

            // 地形タグの一致を確認
            if (setting.terrainTags && setting.terrainTags.length > 0) {
                // 未取得なら地形タグを取得
                if (terrainTag === undefined) {
                    terrainTag = $gameMap.terrainTag(x, y);
                }

                noMatch = setting.terrainTags.every(function (tag) {
                    return terrainTag != tag;
                });
                if (noMatch) {
                    continue;
                }
            }

            // リージョンの一致を確認
            if (setting.regionIds && setting.regionIds.length > 0) {
                // 未取得ならリージョンＩＤを取得
                if (regionId === undefined) {
                    regionId = $gameMap.regionId(x, y);
                }

                noMatch = setting.regionIds.every(function (id) {
                    return regionId != id;
                });
                if (noMatch) {
                    continue;
                }
            }

            // オートタイルタイプの一致を確認
            if (setting.autotileTypes && setting.autotileTypes.length > 0) {
                // 未取得ならオートタイルタイプを取得
                if (autotileType === undefined) {
                    const layerNo = getStepLayer(x, y);
                    autotileType = $gameMap.autotileType(x, y, layerNo);
                }

                noMatch = setting.autotileTypes.every(function (type) {
                    return autotileType != type;
                });
                if (noMatch) {
                    continue;
                }
            }

            // タイルＩＤの一致を確認
            if (setting.tileIds && setting.tileIds.length > 0) {
                // 未取得ならタイルＩＤを取得
                if (tileId === undefined) {
                    const layerNo = getStepLayer(x, y);
                    tileId = $gameMap.tileId(x, y, layerNo);
                }

                noMatch = setting.tileIds.every(function (id) {
                    return tileId != id;
                });
                if (noMatch) {
                    continue;
                }
            }

            // 条件を満たす設定があった。
            return setting;
        }

        // なければundefined
        return undefined;
    }

    /**
     * ●☆を除いた有効な最大レイヤー番号
     * ※要するに足を踏みしめるレイヤー
     */
    function getStepLayer(x, y) {
        // 各タイルが保有するフラグ情報
        const flags = $gameMap.tilesetFlags();
        // 上のレイヤーから順番にループ
        const tiles = $gameMap.layeredTiles(x, y);
        for (let i = 0; i < 4; i++) {
            const tileId = tiles[i];
            const layerNo = 3 - i;
            const flag = flags[tileId];

            // 通行判定☆（0x10）を除く最初のタイルが対象
            if ((flag & 0x10) === 0) {
                return layerNo;
            }
        }
        // 無効の場合は-1
        return -1;
    }

    /**
     * ●条件設定が存在するかどうか？
     */
    function existSetting() {
        return pSettingList.length > 0;
    }

})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// NearEventSensor.js
// ----------------------------------------------------------------------------
// (C) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 3.1.1 2020/07/05 3.1.0の修正をイベント開始時にも適用できるよう変更
// 3.1.0 2020/07/05 イベントから離れたらエフェクトを即時消去できる設定を追加
// 3.0.0 2020/05/26 センサーエフェクトをイベントではなくプレイヤーに適用できる機能を追加。パラメータの再設定が必要です。
// 2.2.0 2018/11/05 フキダシの表示完了までウェイトするかどうかの設定を追加
// 2.1.1 2018/11/05 マップ移動時にすでに検知範囲内に入っていたイベントについて、一度範囲外に出ないと反応しない問題を修正
// 2.1.0 2017/10/23 特定のスイッチもしくはセルフスイッチが有効なときのみ感知エフェクトを出す機能を追加
//                  パラメータの型指定機能に対応
// 2.0.0 2016/08/27 フラッシュの代わりにフキダシアイコンを利用できる機能を追加
//                  パラメータ名等に一部破壊的な変更が加わっています。
// 1.1.0 2016/07/14 各種パラメータとメモ欄で感知可否の設定を追加
// 1.0.1 2015/11/01 既存コードの再定義方法を修正（内容に変化なし）
// 1.0.0 2015/10/31 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc 周辺イベント感知プラグイン
 * @author トリアコンタン
 *
 * @param DefaultFlash
 * @text デフォルトフラッシュ
 * @desc 感知時にイベントを指定色でフラッシュさせます。(ON/OFF)
 * @default true
 * @type boolean
 *
 * @param DefaultBalloon
 * @text デフォルトフキダシ
 * @desc 感知時にイベントに自動でフキダシアイコンを出します。
 * (1:びっくり 2:はてな 3:音符 4:ハート 5:怒り....)
 * @default 0
 * @type select
 * @option なし
 * @value 0
 * @option びっくり
 * @value 1
 * @option はてな
 * @value 2
 * @option 音符
 * @value 3
 * @option ハート
 * @value 4
 * @option 怒り
 * @value 5
 * @option 汗
 * @value 6
 * @option くしゃくしゃ
 * @value 7
 * @option 沈黙
 * @value 8
 * @option 電球
 * @value 9
 * @option Zzz
 * @value 10
 * @option ユーザ定義1
 * @value 11
 * @option ユーザ定義2
 * @value 12
 * @option ユーザ定義3
 * @value 13
 * @option ユーザ定義4
 * @value 14
 * @option ユーザ定義5
 * @value 15
 *
 * @param DisableEmpty
 * @text 空イベントは無効
 * @desc イベント内容が空の場合、感知しなくなります。(ON/OFF)
 * @default true
 * @type boolean
 *
 * @param SensorDistance
 * @text 感知距離
 * @desc イベントを関知する距離です。
 * @default 2
 * @type number
 *
 * @param FlashColor
 * @text フラッシュカラー
 * @desc 感知時のフラッシュ色です。R(赤),G(緑),B(青),A(強さ)の順番で指定してください。
 * @default {"Red":"255","Green":"255","Blue":"255","Alpha":"255"}
 * @type struct<Color>
 *
 * @param FlashDuration
 * @text フラッシュ時間
 * @desc フラッシュさせるフレーム数です。
 * @default 60
 * @type number
 *
 * @param BalloonInterval
 * @text フキダシ間隔
 * @desc フキダシを表示する間隔のフレーム数です。
 * @default 15
 * @type number
 *
 * @param WaitForBalloon
 * @text フキダシ完了までウェイト
 * @desc 範囲内に居続けた場合の連続フキダシ表示で、フキダシの表示が終わるのを待ってから次のフキダシの表示します。
 * @default true
 * @type boolean
 *
 * @param ConsiderationDir
 * @text 向きを考慮
 * @desc プレイヤーがイベントの方を向いている場合のみエフェクトを有効にします。(ON/OFF)
 * @default false
 * @type boolean
 *
 * @param ApplyPlayer
 * @text プレイヤーに適用
 * @desc 感知時のエフェクトを対象イベントではなくプレイヤーに対して適用します。
 * @default false
 * @type boolean
 *
 * @param EraseWhenAway
 * @text 離れたら消去
 * @desc イベントから離れたらエフェクトを消去します。
 * @default false
 * @type boolean
 *
 * @help 周囲に存在するイベントを感知してイベントにエフェクトを発生させます。
 * 実行可能なイベントをプレイヤーに伝えてユーザビリティを向上させます。
 * 使用できるエフェクトはフラッシュとフキダシアイコン（およびその両方）です。
 *
 * 各エフェクトの有効可否は、プラグインパラメータによる一括設定と
 * イベントのメモ欄による個別設定があり、個別設定が優先されます。
 *
 * 感知時のエフェクトをフラッシュにしたい場合は、
 * メモ欄を以下の通り指定してください。
 * <NESフラッシュ対象:ON>  # 対象イベントのフラッシュを有効にします。
 * <NESフラッシュ対象:OFF> # 対象イベントのフラッシュを無効にします。
 *
 * 感知時のエフェクトをフキダシアイコンにしたい場合は、
 * メモ欄を以下の通り指定してください。
 * <NESフキダシ対象:1> # 対象イベントのフキダシを(1:びっくり)にします。
 * <NESフキダシ対象:0> # 対象イベントのフキダシを無効にします。
 *
 * 特定のスイッチもしくはセルフスイッチがONのときのみ感知エフェクトを
 * 表示したい場合は、メモ欄を以下の通り指定してください。
 * <NESスイッチ:1>       # スイッチ[1]がONのときのみエフェクトを出します。
 * <NESSwitch:1>         # 同上
 * <NESセルフスイッチ:A> # セルフスイッチ[A]がONのときのみエフェクトを出します。
 * <NESSelfSwitch:1>     # 同上
 *
 * 注意！
 * モバイル端末では、フラッシュを使用すると動作が
 * 少し重くなるようです。ご利用の際はご注意ください。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~Color:
 * @param Red
 * @desc 赤色の情報です。(0-255)
 * @type number
 * @min 0
 * @max 255
 * @default 255
 *
 * @param Green
 * @desc 緑色の情報です。(0-255)
 * @type number
 * @min 0
 * @max 255
 * @default 255
 *
 * @param Blue
 * @desc 青色の情報です。(0-255)
 * @type number
 * @min 0
 * @max 255
 * @default 255
 *
 * @param Alpha
 * @desc 強さの情報です。(0-255)
 * @type number
 * @min 0
 * @max 255
 * @default 255
 */

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

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

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

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

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

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

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var createPluginParameter = function (pluginName) {
        var paramReplacer = function (key, value) {
            if (value === 'null') {
                return value;
            }
            if (value[0] === '"' && value[value.length - 1] === '"') {
                return value;
            }
            try {
                return JSON.parse(value);
            } catch (e) {
                return value;
            }
        };
        var parameter = JSON.parse(JSON.stringify(PluginManager.parameters(pluginName), paramReplacer));
        PluginManager.setParameters(pluginName, parameter);
        return parameter;
    };
    var param = createPluginParameter('NearEventSensor');
    param.FlashColorArray = [param.FlashColor.Red, param.FlashColor.Green, param.FlashColor.Blue, param.FlashColor.Alpha];

    //=============================================================================
    // Sprite_Character
    //  キャラクターのフラッシュ機能を追加定義します。
    //=============================================================================
    var _Sprite_CharacterUpdate = Sprite_Character.prototype.update;
    Sprite_Character.prototype.update = function () {
        _Sprite_CharacterUpdate.call(this);
        this.updateFlash();
    };

    Sprite_Character.prototype.updateFlash = function () {
        if (this._character.isFlash()) {
            this.setBlendColor(this._character._flashColor);
        }
    };

    var _Sprite_Character_updateBalloon = Sprite_Character.prototype.updateBalloon;
    Sprite_Character.prototype.updateBalloon = function () {
        if (this._character.isBalloonCancel()) {
            this.endBalloon();
        }
        _Sprite_Character_updateBalloon.apply(this, arguments);
    };

    //=============================================================================
    // Game_CharacterBase
    //  キャラクターのフラッシュ機能を追加定義します。
    //=============================================================================
    var _Game_CharacterBaseInitMembers = Game_CharacterBase.prototype.initMembers;
    Game_CharacterBase.prototype.initMembers = function () {
        _Game_CharacterBaseInitMembers.call(this);
        this._flashColor = null;
        this._flashDuration = 0;
    };

    var _Game_CharacterBaseUpdate = Game_CharacterBase.prototype.update;
    Game_CharacterBase.prototype.update = function () {
        _Game_CharacterBaseUpdate.call(this);
        this.updateFlash();
    };

    Game_CharacterBase.prototype.startFlash = function (flashColor, flashDuration) {
        this._flashColor = flashColor;
        this._flashDuration = flashDuration;
    };

    Game_CharacterBase.prototype.clearFlash = function () {
        this._flashColor = [0, 0, 0, 0];
    };

    Game_CharacterBase.prototype.isFlash = function () {
        return this._flashDuration > 0;
    };

    Game_CharacterBase.prototype.updateFlash = function () {
        if (this.isFlash()) {
            this._flashColor[3] = this._flashColor[3] * (this._flashDuration - 1) / this._flashDuration;
            this._flashDuration--;
        }
    };

    Game_CharacterBase.prototype.applySensorEffect = function (targetEvent) {
        if (!this.isFlash() && targetEvent.isFlashEvent()) {
            this.startFlash(param.FlashColorArray.clone(), param.FlashDuration);
        }
        var balloonId = targetEvent.getSensorBalloonId();
        if (balloonId && (!param.WaitForBalloon || !this.isBalloonPlaying())) {
            if (this._balloonInterval <= 0 || isNaN(this._balloonInterval)) {
                this.requestBalloon(balloonId);
                this._balloonInterval = param.BalloonInterval;
            } else {
                this._balloonInterval--;
            }
        }
        this._sensorApply = true;
    };

    Game_CharacterBase.prototype.eraseSensorEffect = function () {
        if (!this._sensorApply || !param.EraseWhenAway) {
            return;
        }
        this.clearFlash();
        this._balloonCancel = true;
        this._sensorApply = false;
    };

    Game_CharacterBase.prototype.isBalloonCancel = function () {
        var cancel = this._balloonCancel;
        this._balloonCancel = false;
        return cancel;
    };

    //=============================================================================
    // Game_Event
    //  プレイヤーとの距離を測り、必要な場合にエフェクトさせる機能を追加定義します。
    //=============================================================================
    var _Game_Event_initialize = Game_Event.prototype.initialize;
    Game_Event.prototype.initialize = function (mapId, eventId) {
        _Game_Event_initialize.apply(this, arguments);
        this._balloonInterval = 0;
    };

    var _Game_EventUpdate = Game_Event.prototype.update;
    Game_Event.prototype.update = function () {
        _Game_EventUpdate.apply(this, arguments);
        if (this.page()) {
            this.updateSensorEffect();
        }
    };

    var _Game_Event_start = Game_Event.prototype.start;
    Game_Event.prototype.start = function () {
        _Game_Event_start.apply(this, arguments);
        this.eraseSensorEffect();
    };

    Game_Event.prototype.updateSensorEffect = function () {
        var subject = this.findNearEffectSubject();
        if (this.isSensorOn()) {
            subject.applySensorEffect(this);
        } else {
            subject.eraseSensorEffect(this);
            this._balloonInterval = 0;
        }
    };

    Game_Event.prototype.isSensorOn = function () {
        return this.isEmptyValidate() && this.isVeryNearThePlayer() &&
            !$gameMap.isEventRunning() && this.isValidSensor();
    };

    Game_Event.prototype.findNearEffectSubject = function () {
        return param.ApplyPlayer ? $gamePlayer : this;
    };

    Game_Event.prototype.isEmptyValidate = function () {
        var list = this.list();
        return (list && list.length > 1) || !param.DisableEmpty;
    };

    Game_Event.prototype.isFlashEvent = function () {
        var useFlash = getMetaValues(this.event(), ['フラッシュ対象', 'FlashEvent']);
        return useFlash ? getArgBoolean(useFlash) : param.DefaultFlash;
    };

    Game_Event.prototype.isValidSensor = function () {
        return this.isValidSensorSwitch() && this.isValidSensorSelfSwitch();
    };

    Game_Event.prototype.isValidSensorSwitch = function () {
        var switchId = getMetaValues(this.event(), ['スイッチ', 'Switch']);
        return switchId ? $gameSwitches.value(getArgNumber(switchId, 1)) : true;
    };

    Game_Event.prototype.isValidSensorSelfSwitch = function () {
        var selfSwitchType = getMetaValues(this.event(), ['セルフスイッチ', 'SelfSwitch']);
        return selfSwitchType ? $gameSelfSwitches.value([this._mapId, this._eventId, selfSwitchType.toUpperCase()]) : true;
    };

    Game_Event.prototype.getSensorBalloonId = function () {
        var balloonId = getMetaValues(this.event(), ['フキダシ対象', 'BalloonEvent']);
        return balloonId ? getArgNumber(balloonId, 0) : param.DefaultBalloon;
    };

    Game_Event.prototype.isVeryNearThePlayer = function () {
        var sx = this.deltaXFrom($gamePlayer.x);
        var sy = this.deltaYFrom($gamePlayer.y);
        var ax = Math.abs(sx);
        var ay = Math.abs(sy);
        var result = (ax + ay <= param.SensorDistance);
        if (result && param.ConsiderationDir) {
            if (ax > ay) {
                return $gamePlayer.direction() === (sx > 0 ? 6 : 4);
            } else if (sy !== 0) {
                return $gamePlayer.direction() === (sy > 0 ? 2 : 8);
            } else {
                return true;
            }
        }
        return result;
    };
})();


code:
//=============================================================================
// NoGameover.js
//=============================================================================

/*:
 * @plugindesc NoGameover
 * @author yuwaka
 *
 * @param Switch ID
 * @desc The ID of the switch to be turned ON when AllDead.
 * @default 0
 *
 * @param Switch ID2
 * @desc The ID of the switch to be turned ON when AllDead.
 * @default 0
 *
 * @help This plugin does not provide plugin commands.
 *I role model Tachi's plug-ins.
 *Thank you very much.
 */

/*:ja
 * @plugindesc ゲームオーバーにならないよ。
 * @author ゆわか
 *
 * @param Switch ID
 * @desc 戦闘中でもマップでも全滅したときにONにするスイッチのIDです。
 * @default 0
 *
 * @param Switch ID2
 * @desc 戦闘中全滅したときだけONにするスイッチのIDです。
 * @default 0
 *
 * @help このプラグインには、プラグインコマンドはありません。
 *
 *　自動的にフェードアウトするようにしています。
 *　フェードインはスイッチで呼び出すコモンイベントへ入れて
 *　好きなタイミングで行ってください。
 *　（フェードアウトしたくなければ、コメントアウトしてね）
 *
 *　このプラグインはもうあなたのものです。
 *　お好きなように使ってください。
 *
 *　ＲＰＧツクールＭＶサンプルゲーム「シーピラート」のプラグインを
 *　参考にさせて頂きました。
 *　ありがとうございます。
 */

(function () {

    var parameters = PluginManager.parameters('NoGameover2');
    var switchId = Number(parameters['Switch ID'] || 0);
    var switchId2 = Number(parameters['Switch ID2'] || 0);

    //rpg_managers.jsより（戦闘で全滅した場合）
    BattleManager.updateBattleEnd = function () {
        if (this.isBattleTest()) {
            AudioManager.stopBgm();
            SceneManager.exit();
        } else if ($gameParty.isAllDead()) {
            if (this._canLose) {
                $gameParty.reviveBattleMembers();
                SceneManager.pop();
            } else {
                //SceneManager.goto(Scene_Gameover);//ゲームオーバーを表示するぜ
                $gameScreen.startFadeOut(10); //フェードアウトするぜ
                $gameSwitches.setValue(switchId, true); //全滅したぜ
                $gameSwitches.setValue(switchId2, true); //戦闘中に全滅したぜ
                $gameParty.reviveBattleMembers(); //みんな生き返るぜ
                SceneManager.pop(); //マップ画面へ移動するぜ
            }
        } else {
            SceneManager.pop();
        }
        this._phase = null;
    };

    //rpg_scenes.jsより（フィールドで全滅した場合）
    Scene_Base.prototype.checkGameover = function () {
        if ($gameParty.isAllDead()) {
            //        SceneManager.goto(Scene_Gameover);
            $gameScreen.startFadeOut(30); //フェードアウトするぜ
            $gameSwitches.setValue(switchId, true); //全滅したぜ
            $gameParty.reviveBattleMembers(); //みんな生き返るぜ
        }
    };

})();


code:
//=============================================================================
// NpcFollower.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.2.0 2022/09/17 アクターIDを指定してNPCを削除できるコマンドを追加
// 1.1.2 2022/05/10 パラメータの説明文を修正
// 1.1.1 2019/11/02 1.1.0の修正でメンバーの入れ替えを実施すると表示が不正になる場合がある問題を修正
// 1.1.0 2019/01/27 通常のフォロワーを表示せず、NPCフォロワーのみを表示できる機能を追加
// 1.0.3 2018/08/06 コアスクリプトが1.6.0より古い場合にエラーになる記述を修正
// 1.0.2 2017/01/17 プラグインコマンドが小文字でも動作するよう修正（byこまちゃん先輩）
// 1.0.1 2016/07/17 セーブデータをロードした際のエラーになる現象の修正
// 1.0.0 2016/07/14 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc NPC Follower plugin
 * @author triacontane
 *
 * @param MaxNpcNumber
 * @desc 同時に隊列に存在できるNPCの最大数です。
 * @default 1
 *
 * @param HideNormalFollower
 * @desc 通常のフォロワーを一切表示せず、NPCフォロワーのみを表示します。データベースの隊列歩行は有効にしてください。
 * @default false
 * @type boolean
 *
 * @help マップ上の隊列の好きな位置にパーティメンバー以外のNPCを追加します。
 * NPCはデータベース上はアクターで定義してプラグインコマンドから追加、削除します。
 * 戦闘員ではないので、メニュー画面や戦闘画面には影響を与えません。
 * また、隊列表示していない場合は何も表示されません。
 *
 * 同一IDのアクターを複数追加することもできます。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * NF_NPC追加 4 1 # アクターID[4]をNPCとしてパーティの[1]番目の後ろに追加
 * NF_ADD_NPC 5 3 # アクターID[5]をNPCとしてパーティの[3]番目の後ろに追加
 * NF_NPC削除 1   # [1]番目に追加したNPCを全て削除
 * NF_REM_NPC 3   # [3]番目に追加したNPCを全て削除
 *
 * インデックスの指定は追加したNPCとは関係なく、
 * パーティの並び順(1...バトルメンバー数)を指定してください。
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc NPCフォロワープラグイン
 * @author トリアコンタン
 *
 * @param 最大同時NPC数
 * @desc 同時に隊列に存在できるNPCの最大数です。
 * @default 1
 * @type number
 * @min 1
 *
 * @param 通常フォロワーを表示しない
 * @desc 通常のフォロワーを一切表示せず、NPCフォロワーのみを表示します。データベースの隊列歩行は有効にしてください。
 * @default false
 * @type boolean
 *
 * @help マップ上の隊列の好きな位置にパーティメンバー以外のNPCを追加します。
 * NPCはデータベース上はアクターで定義してプラグインコマンドから追加、削除します。
 * 戦闘員ではないので、メニュー画面や戦闘画面には影響を与えません。
 * また、隊列表示していない場合は何も表示されません。
 *
 * 同一IDのアクターを複数追加することもできます。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * NF_NPC追加 4 1 # アクターID[4]をNPCとしてパーティの[1]番目の後ろに追加
 * NF_ADD_NPC 5 3 # アクターID[5]をNPCとしてパーティの[3]番目の後ろに追加
 * NF_NPC削除 1   # [1]番目に追加したNPCを全て削除
 * NF_REM_NPC 3   # [3]番目に追加したNPCを全て削除
 *
 * インデックスの指定は追加したNPCとは関係なく、
 * パーティの並び順(1...バトルメンバー数)を指定してください。
 *
 * 並び順ではなくIDを指定したNPCを削除したい場合、以下のコマンドです。
 * NF_NPC_ID削除 4 # アクターID[4]のNPCを削除
 * NF_REM_NPC_ID 4 # 同上
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
    'use strict';
    var pluginName = 'NpcFollower';
    var metaTagPrefix = 'NF';

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

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

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

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

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

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

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var paramMaxNpcNumber = getParamNumber(['MaxNpcNumber', '最大同時NPC数']);
    var paramHideNormalFollower = getParamBoolean(['HideNormalFollower', '通常フォロワーを表示しない']);

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

    Game_Interpreter.prototype.pluginCommandNpcFollower = function (command, args) {
        switch (getCommandName(command)) {
            case '_NPC追加':
            case '_ADD_NPC':
                var actorId = getArgNumberWithEval(args[0]);
                $gameParty.addNpc(actorId, getArgNumberWithEval(args[1], 1));
                break;
            case '_NPC削除':
            case '_REM_NPC':
                $gameParty.removeNpc(getArgNumberWithEval(args[0], 1));
                break;
            case '_NPC_ID削除':
            case '_REM_NPC_ID':
                var removeActorId = getArgNumberWithEval(args[0]);
                $gameParty.removeNpcById(removeActorId);
        }
    };

    //=============================================================================
    // Game_Party
    //  NPCの追加と削除を追加定義します。
    //=============================================================================
    var _Game_Party_initialize = Game_Party.prototype.initialize;
    Game_Party.prototype.initialize = function () {
        _Game_Party_initialize.apply(this, arguments);
        this.initNpc();
    };

    Game_Party.prototype.initNpc = function () {
        this._npcs = [];
        this._npcIndexes = [];
    };

    Game_Party.prototype.isNpcInvalid = function () {
        return !this._npcs;
    };

    Game_Party.prototype.initNpcIfNeed = function () {
        if (this.isNpcInvalid()) {
            this.initNpc();
            $gamePlayer.followers().initNpc();
        }
    };

    Game_Party.prototype.addNpc = function (actorId, index) {
        if (this._npcs.length < paramMaxNpcNumber) {
            this._npcs.push(actorId);
            this._npcIndexes.push(index);
            $gamePlayer.refresh();
            $gameMap.requestRefresh();
        } else {
            throw new Error('登録可能な最大数を超えています。');
        }
    };

    Game_Party.prototype.removeNpc = function (index) {
        for (var i = 0, n = this._npcs.length; i < n; i++) {
            if (this._npcIndexes[i] === index) {
                this._npcs.splice(i, 1);
                this._npcIndexes.splice(i, 1);
                i--;
            }
        }
        $gamePlayer.refresh();
        $gameMap.requestRefresh();
    };

    Game_Party.prototype.removeNpcById = function (id) {
        for (var i = 0, n = this._npcs.length; i < n; i++) {
            if (this._npcs[i] === id) {
                this._npcs.splice(i, 1);
                this._npcIndexes.splice(i, 1);
                i--;
            }
        }
        $gamePlayer.refresh();
        $gameMap.requestRefresh();
    };

    Game_Party.prototype.npcMembers = function () {
        return this._npcs.map(function (id) {
            return $gameActors.actor(id);
        });
    };

    Game_Party.prototype.visibleMembers = function () {
        return this._visibleMembers;
    };

    Game_Party.prototype.makeVisibleMembers = function () {
        var battleMembers = this.battleMembers();
        var npcMembers = this.npcMembers();
        var visibleMembers = [];
        for (var i = 0, n = this.maxBattleMembers() + 1; i < n; i++) {
            for (var j = 0, m = npcMembers.length; j < m; j++) {
                if (this._npcIndexes[j] === i) {
                    visibleMembers.push(npcMembers[j]);
                }
            }
            if (battleMembers.length > i && !paramHideNormalFollower) {
                visibleMembers.push(battleMembers[i]);
            }
        }
        this._visibleMembers = visibleMembers;
    };

    //=============================================================================
    // Game_Followers
    //  NPCの最大数ぶんだけ余分にGame_Followerを作成します。
    //=============================================================================
    var _Game_Followers_initialize = Game_Followers.prototype.initialize;
    Game_Followers.prototype.initialize = function () {
        _Game_Followers_initialize.apply(this, arguments);
        if (paramHideNormalFollower) {
            this._data = [];
        }
        this.initNpc();
    };

    Game_Followers.prototype.initNpc = function () {
        var memberLength = this._data.length > 0 ? this._data.length + 1 : 0;
        for (var i = 0; i < paramMaxNpcNumber; i++) {
            this._data.push(new Game_Follower(memberLength + i));
        }
    };

    //=============================================================================
    // Game_Follower
    //  NPC判定を追加定義します。
    //=============================================================================
    var _Game_Follower_actor = Game_Follower.prototype.actor;
    Game_Follower.prototype.actor = function () {
        _Game_Follower_actor.apply(this, arguments);
        return $gameParty.visibleMembers()[this._memberIndex];
    };

    //=============================================================================
    // Game_Player
    //  リフレッシュまえに表示メンバーを更新します。
    //=============================================================================
    var _Game_Player_refresh = Game_Player.prototype.refresh;
    Game_Player.prototype.refresh = function () {
        $gameParty.makeVisibleMembers();
        _Game_Player_refresh.apply(this, arguments);
    };

    //=============================================================================
    // DataManager
    //  プラグイン未適用のデータをロードした場合に必要なデータを初期化します。
    //=============================================================================
    var _DataManager_loadGame = DataManager.loadGame;
    DataManager.loadGame = function (saveFileId) {
        var result = _DataManager_loadGame.apply(this, arguments);
        $gameParty.initNpcIfNeed();
        return result;
    };
})();


code:
//=============================================================================
// - OmitTarget
// OmitTarget.js
//=============================================================================

//=============================================================================
/*:
* @plugindesc 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
* @author 名無し蛙 (著作権は放棄。クレジット表記は不要です)
*
* @help
* 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
*
* ↓以下、merusaiaが追記
*
* ■更新履歴
* 20160704: Version 0.:  名無し蛙さんの初版。
* 20160704: Version 1.0: merusaiaがコメントと説明文のみ追加。
*
* 【使い方】
* プラグインをONにすると、戦闘画面でターゲット選択時、対象が一つの場合は省略します。
* ドラ◯エのように、敵が一人の時、わざわざターゲットを選ぶムダな処理がなくなるので、ムダな操作を削減できます。
* 対象が味方一人の場合も省略しています。
*
* ボタンやキー押しっぱなし操作ができるキーボードやゲームパッド操作ではそこまで体感はないかもしれませんが、
* 特にタップ／クリック数をかなり削減できて、スマホユーザにも優しい設計に出来ます。
* スマホユーザ向けのRPGには、必須のプラグインかもです。
*
* 【プラグインコマンド】
* このプラグインは、プラグインコマンドを含みません。
*
* 【競合について】
*   以下のメソッドを追記（一度元のメソッドを別の名前にして、call(this)で呼び出し、その後に上書き）しています。
*    → 上記メソッドを丸ごと上書きしているプラグインとの競合に注意してください。
*　　　 競合をチェックするには、以下を「js」フォルダ内検索をして、丸ごと上書きしているメソッドがないか調べられます。
*　　　・Scene_Battle.prototype.selectActorSelection = function()
*　　　・Scene_Battle.prototype.selectEnemySelection = function()
*
* 【著作権フリーについて】
* このプラグインは「地球の共有物（パブリックドメイン）」です。
* 　　・無償・有償問わず、あらゆる作品に使用でき、また自由に改変・改良・二次配布できます。
* 　　・著作表示のわずらわしさを回避するため、著作権は放棄します。事後報告、クレジット記載も不要です。
* 　　・もちろんクローズドに使っていただいてもOKです。是非、自分好みに改造してお使いください。
*
*/
//=============================================================================

(function () {
    var _Scene_Battle_selectActorSelection = Scene_Battle.prototype.selectActorSelection;
    Scene_Battle.prototype.selectActorSelection = function () {
        _Scene_Battle_selectActorSelection.call(this);
        if (this._actorWindow.maxItems() === 1) { // 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
            this._actorWindow.deactivate();
            this.onActorOk();
        }
    };

    var _Scene_Battle_selectEnemySelection = Scene_Battle.prototype.selectEnemySelection;
    Scene_Battle.prototype.selectEnemySelection = function () {
        _Scene_Battle_selectEnemySelection.call(this);
        if (this._enemyWindow.maxItems() === 1) { // 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
            this._enemyWindow.deactivate();
            this.onEnemyOk();
        }
    };
}());

//=============================================================================
// End of File
//=============================================================================


code:
/*=============================================================================
 * Orange - Custom Event
 * By Hudell - www.hudell.com
 * OrangeCustomEvents.js
 * Version: 1.6.1
 * Free for commercial and non commercial use.
 *=============================================================================*/
/*:
* @plugindesc This plugin Will let you add or copy events to the current map
*
* @author Hudell
* @help
* ============================================================================
* Latest Version
* ============================================================================
*
* Get the latest version of this script on
* http://download.hudell.com/OrangeCustomEvents.js
*
*=============================================================================*/

var Imported = Imported || {};

if (Imported.MVCommons === undefined) {
  var MVCommons = {};

  (function ($) {
    $.ajaxLoadFileAsync = function (filePath, mimeType, onLoad, onError) { mimeType = mimeType || "application/json"; var xhr = new XMLHttpRequest(); var name = '$' + filePath.replace(/^.*(\\|\/|\:)/, '').replace(/\..*/, ''); xhr.open('GET', filePath); if (mimeType && xhr.overrideMimeType) { xhr.overrideMimeType(mimeType); } if (onLoad === undefined) { onLoad = function (xhr, filePath, name) { if (xhr.status < 400) { window[name] = JSON.parse(xhr.responseText); DataManager.onLoad(window[name]); } }; } if (onError === undefined) { onError = function () { DataManager._errorUrl = DataManager._errorUrl || filePath; }; } xhr.onload = function () { onLoad.call(this, xhr, filePath, name); }; xhr.onerror = onError; window[name] = null; xhr.send(); };
  })(MVCommons);

  if (Utils.isOptionValid('test')) {
    console.log('MVC not found, OrangeCustomEvents will be using essentials (copied from MVC 1.4.0).');
  }
}

var OrangeCustomEvents = OrangeCustomEvents || {};

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

(function ($) {
  "use strict";

  //----------------------------------------------.
  //----------------------------------------------|
  // PROTECTED METHODS                            |
  //----------------------------------------------|
  //----------------------------------------------|

  $.getAnotherMapData = function (mapId, callback) {
    var variableName = '$Map%1'.format(mapId.padZero(3));
    var filename = 'data/Map%1.json'.format(mapId.padZero(3));

    var onLoad = function (xhr, filePath, name) {
      if (xhr.status < 400) {
        window[name] = JSON.parse(xhr.responseText);
        DataManager.onLoad(window[name]);

        callback();
      }
    };

    if (window[variableName] === undefined || window[variableName] === null) {
      MVCommons.ajaxLoadFileAsync(filename, undefined, onLoad);
    } else {
      callback();
    }
  };

  //----------------------------------------------.
  //----------------------------------------------|
  // PUBLIC METHODS                               |
  //----------------------------------------------|
  //----------------------------------------------|

  //----------------------------------------------
  // Game_Custom_Event
  //----------------------------------------------
  Game_Custom_Event.prototype.initialize = function (mapId, eventId, eventData) {
    this._eventData = eventData;
    Game_Event.prototype.initialize.call(this, mapId, eventId);
  };

  Game_Custom_Event.prototype.event = function () {
    return this._eventData;
  };

  Game_Custom_Event.prototype.revive = function (data) {
    return new Game_Custom_Event(data.mapId, data.id, data.eventData);
  };

  //----------------------------------------------
  // Game_System
  //----------------------------------------------
  Game_System.prototype.clearSelfSwitches = function (mapId, eventId) {
    var switches = ["A", "B", "C", "D"];

    switches.forEach(function (switchId) {
      var key = [mapId, eventId, switchId];
      $gameSelfSwitches.setValue(key, false);
    });
  };

  Game_System.prototype.initCustomEvents = function (mapId) {
    if (this._customEvents === undefined) {
      this._customEvents = {};
    }

    if (this._customEvents[mapId] === undefined) {
      this._customEvents[mapId] = {};
    }
  };

  Game_System.prototype.addCustomEvent = function (mapId, event) {
    this.initCustomEvents(mapId);
    this.clearSelfSwitches(mapId, event.id);
    this._customEvents[mapId][event.id] = event;

    return event;
  };

  Game_System.prototype.removeCustomEvent = function (mapId, eventId) {
    this.initCustomEvents(mapId);
    this.clearSelfSwitches(mapId, eventId);
    delete this._customEvents[mapId][eventId];
  };

  Game_System.prototype.clearCustomEvents = function (mapId) {
    this.initCustomEvents();
    this._customEvents[mapId] = {};
  };

  Game_System.prototype.getCustomEvents = function (mapId) {
    this.initCustomEvents();
    return this._customEvents[mapId];
  };

  //----------------------------------------------
  // Game_Map
  //----------------------------------------------
  Game_Map.prototype.getIndexForNewEvent = function () {
    var index = 1;
    while (index < this._events.length && !!this._events[index]) {
      index++;
    }

    return index;
  };

  Game_Map.prototype.addEvent = function (eventData, temporary, index) {
    if (temporary === undefined) {
      temporary = false;
    }

    if (index === undefined) {
      index = this.getIndexForNewEvent();
    }

    eventData.id = index;
    var gameEvent = new Game_Custom_Event(this._mapId, index, eventData);
    $gameSystem.clearSelfSwitches(this._mapId, index);

    this._events[index] = gameEvent;

    if (SceneManager._scene instanceof Scene_Map) {
      var sprite = new Sprite_Character(gameEvent);
      SceneManager._scene._spriteset._characterSprites.push(sprite);
      SceneManager._scene._spriteset._tilemap.addChild(sprite);
    }

    if (temporary === false) {
      $gameSystem.addCustomEvent(this._mapId, eventData);
    }

    return gameEvent;
  };

  var oldGameMap_setupEvents = Game_Map.prototype.setupEvents;
  Game_Map.prototype.setupEvents = function () {
    oldGameMap_setupEvents.call(this);

    var customEvents = $gameSystem.getCustomEvents(this._mapId);
    for (var eventId in customEvents) {
      if (customEvents[eventId] === undefined) continue;
      var newEventId = this.getIndexForNewEvent();

      customEvents[eventId].eventId = newEventId;
      this._events[newEventId] = new Game_Custom_Event(this._mapId, newEventId, customEvents[eventId]);
    }
  };

  Game_Map.prototype.addEventAt = function (eventData, x, y, temporary, index) {
    eventData.x = x;
    eventData.y = y;
    return this.addEvent(eventData, temporary, index);
  };

  Game_Map.prototype.spawnEvent = function (eventData, tileList, temporary) {
    for (var i = 0; i < tileList.length; i++) {
      var newEventData = JsonEx.makeDeepCopy(eventData);
      newEventData.x = tileList[i].x;
      newEventData.y = tileList[i].y;
      this.addEvent(newEventData, temporary);
    }
  };

  Game_Map.prototype.getEventData = function (eventIdOrigin) {
    var event = $dataMap.events[eventIdOrigin];
    if (event === undefined) return undefined;

    return JsonEx.makeDeepCopy(event);
  };

  Game_Map.prototype.getEventDataFrom = function (mapIdOrigin, eventIdOrigin, callback) {
    $.getAnotherMapData(mapIdOrigin, function () {
      var variableName = '$Map%1'.format(mapIdOrigin.padZero(3));

      if (window[variableName] === undefined || window[variableName] === null) return;

      var event = window[variableName].events[eventIdOrigin];
      if (event === undefined) return;

      var eventData = JsonEx.makeDeepCopy(event);
      callback.call(this, eventData);
    });
  };

  Game_Map.prototype.copyEvent = function (eventIdOrigin, x, y, temporary, newIndex) {
    var eventData = this.getEventData(eventIdOrigin);
    if (eventData) {
      $gameMap.addEventAt(eventData, x, y, temporary, newIndex);
    }
  };

  Game_Map.prototype.getRegionTileList = function (regionId) {
    var tileList = [];

    for (var x = 0; x < $gameMap.width(); x++) {
      for (var y = 0; y < $gameMap.height(); y++) {
        if ($gameMap.eventsXy(x, y).length === 0) {
          if ($gameMap.regionId(x, y) == regionId) {
            tileList.push({ x: x, y: y });
          }
        }
      }
    }

    return tileList;
  };

  Game_Map.prototype.getRandomRegionTile = function (regionId) {
    var tileList = this.getRegionTileList(regionId);

    if (tileList.length > 0) {
      var index = Math.randomInt(tileList.length);
      return tileList[index];
    }

    return undefined;
  };

  Game_Map.prototype.copyEventToRegion = function (eventIdOrigin, regionId, temporary, newIndex) {
    var tile = this.getRandomRegionTile(regionId);
    if (tile !== undefined) {
      this.copyEvent(eventIdOrigin, tile.x, tile.y, temporary, newIndex);
    }
  };

  Game_Map.prototype.copyEventFrom = function (mapIdOrigin, eventIdOrigin, x, y, temporary, newIndex) {
    this.getEventDataFrom(mapIdOrigin, eventIdOrigin, function (eventData) {
      $gameMap.addEventAt(eventData, x, y, temporary, newIndex);
    });
  };

  Game_Map.prototype.copyEventFromMapToRegion = function (mapIdOrigin, eventIdOrigin, regionId, temporary, newIndex) {
    var tile = this.getRandomRegionTile(regionId);
    if (tile !== undefined) {
      this.copyEventFrom(mapIdOrigin, eventIdOrigin, tile.x, tile.y, temporary, newIndex);
    }
  };

  Game_Map.prototype.spawnMapEvent = function (eventIdOrigin, regionId, temporary) {
    var eventData = this.getEventData(eventIdOrigin);
    var tileList = this.getRegionTileList(regionId);

    if (eventData && tileList) {
      this.spawnEvent(eventData, tileList, temporary);
    }
  };

  Game_Map.prototype.spawnMapEventFrom = function (mapIdOrigin, eventIdOrigin, regionId, temporary) {
    var tileList = this.getRegionTileList(regionId);

    if (tileList.length > 0) {
      this.getEventDataFrom(mapIdOrigin, eventIdOrigin, function (eventData) {
        $gameMap.spawnEvent(eventData, tileList, temporary);
      });
    }
  };

  Game_Interpreter.prototype.checkCopyCommands = function (command, args) {
    if (args.length < 2) return;

    if (command.toUpperCase() !== 'COPY' && command.toUpperCase() !== 'SPAWN') return;
    if (args[0].toUpperCase() !== "EVENT") return;

    var eventIdOrigin = parseInt(args[1], 10);
    var mapIdOrigin = $gameMap.mapId();
    var isPosition = true;
    var x = 0;
    var y = 0;
    var regionId = 0;
    var temporary = true;
    var hasPosition = false;
    var userIndex;

    if (eventIdOrigin <= 0) return;

    var nextIndex = 2;

    if (args.length >= nextIndex + 3) {
      if (args[nextIndex].toUpperCase() == 'FROM' && args[nextIndex + 1].toUpperCase() == 'MAP') {
        mapIdOrigin = parseInt(args[nextIndex + 2], 10);
        nextIndex += 3;
      }
    }

    if (args.length > nextIndex && args[nextIndex].toUpperCase() == 'HERE') {
      isPosition = true;
      hasPosition = true;
      x = this.character(0).x;
      y = this.character(0).y;
      nextIndex++;

    } else if (args.length > nextIndex) {
      if (args[nextIndex].toUpperCase() !== 'TO' && args[nextIndex].toUpperCase() !== 'ON') {
        console.error('OrangeCustomEvents', 'Invalid destination', command, args);
        return;
      }

      nextIndex++;

      if (args.length > nextIndex && args[nextIndex].toUpperCase() == 'REGION') {
        isPosition = false;
        nextIndex++;
      } else if (args.length > nextIndex && args[nextIndex].toUpperCase() == 'POSITION') {
        isPosition = true;
        nextIndex++;
      }
    }
    else {
      console.error('OrangeCustomEvents', 'Incomplete command', command, args);
      return;
    }

    if (isPosition) {
      if (!hasPosition) {
        if (args.length > nextIndex && args[nextIndex].toUpperCase() == 'PLAYER') {
          x = $gamePlayer.x;
          y = $gamePlayer.y;
          nextIndex++;
        } else if (args.length >= nextIndex + 2) {
          x = parseInt(args[nextIndex], 10);
          y = parseInt(args[nextIndex + 1], 10);

          nextIndex += 2;
        }
        else {
          console.error('OrangeCustomEvents', 'What position?', command, args);
        }
      }
    }
    else {
      if (args.length > nextIndex) {
        regionId = parseInt(args[nextIndex], 10);
        nextIndex++;
      }
      else {
        console.error('OrangeCustomEvents', 'What region?', command, args);
      }
    }

    if (args.length > nextIndex) {
      if (args[nextIndex].toUpperCase().startsWith('TEMP')) {
        temporary = true;
        nextIndex++;
      } else if (args[nextIndex].toUpperCase() == 'SAVE') {
        temporary = false;
        nextIndex++;
      }
    }

    if (args.length > nextIndex + 2) {
      if (args[nextIndex].toUpperCase().startsWith('WITH') && args[nextIndex + 1].toUpperCase().startsWith('ID')) {
        userIndex = parseInt(args[nextIndex + 2], 10);
      }
    }

    if (isPosition) {
      if (mapIdOrigin == $gameMap.mapId()) {
        $gameMap.copyEvent(eventIdOrigin, x, y, temporary, userIndex);
      } else {
        $gameMap.copyEventFrom(mapIdOrigin, eventIdOrigin, x, y, temporary, userIndex);
      }
    }
    else {
      if (command.toUpperCase() === 'COPY') {
        if (mapIdOrigin == $gameMap.mapId()) {
          $gameMap.copyEventToRegion(eventIdOrigin, regionId, temporary, userIndex);
        } else {
          $gameMap.copyEventFromMapToRegion(mapIdOrigin, eventIdOrigin, regionId, temporary, userIndex);
        }
      } else if (command.toUpperCase() === 'SPAWN') {
        if (mapIdOrigin == $gameMap.mapId()) {
          $gameMap.spawnMapEvent(eventIdOrigin, regionId, temporary);
        } else {
          $gameMap.spawnMapEventFrom(mapIdOrigin, eventIdOrigin, regionId, temporary);
        }
      }
    }
  };

  Game_Interpreter.prototype.checkDeleteCommand = function (command, args) {
    if (args.length != 2) return;

    if (command.toUpperCase() !== 'DELETE') return;
    if (args[0].toUpperCase() !== "THIS") return;
    if (args[1].toUpperCase() !== "EVENT") return;

    $gameSystem.removeCustomEvent(this._mapId, this._eventId);
    this.command214();
  };

  var oldGameInterpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    oldGameInterpreter_pluginCommand.call(this, command, args);

    this.checkCopyCommands(command, args);
    this.checkDeleteCommand(command, args);
  };
})(OrangeCustomEvents);

Imported.OrangeCustomEvents = 1.6;