code:
//=============================================================================
// MPP_ChoiceEX.js
//=============================================================================
// Copyright (c) 2015-2019 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc 【ver.3.11】選択肢の機能拡張
 * @author 木星ペンギン
 *
 * @help ※[]内は未設定でも動作します。
 * プラグインコマンド:
 *   ChoicePos x y[ row]    # 選択肢の位置(x,y)と行数(row)指定
 *   ChoiceVariableId n     # 選択肢のデフォルト位置を変数n番にする
 *   ChoiceRect x y width height
 *                          # 選択肢の座標とサイズを指定
 *   ChoiceUnderMessage     # 選択肢をメッセージの下に表示
 *
 * ※ プラグインコマンドにて指定する値には変数が使用できます。
 *    v[n] と記述することでn番の変数の値を参照します。
 *
 * 注釈:
 *   選択肢ヘルプ             # 各項目の下に設定することでヘルプを表示させる
 *
 * 選択肢テキスト:
 *   if(条件)                # 条件が偽になると項目が表示されなくなる
 *   en(条件)                # 条件が偽になると項目が選択不可
 *
 * ================================================================
 * ▼ 使い方
 * --------------------------------
 *  〇 選択肢を増やす
 *   イベントコマンド『選択肢の表示』を続けて配置すると
 *   一つの選択肢にまとめられます。
 *   まとめたくない場合は、間に注釈などを入れることで
 *   通常通り分けることができます。
 *
 *   『デフォルト』の処理は、なし以外を設定したものが適用されます。
 *   『デフォルト』の処理が複数ある場合、
 *   後に設定された選択肢のものが適用されます。
 *
 *   『キャンセル』の処理は、禁止以外を設定したものが適用されます。
 *   『キャンセル』の処理が複数ある場合、
 *   後に設定された選択肢のものが適用されます。
 *
 *  『背景』と『ウィンドウ位置』は後の選択肢のものが適用されます。
 *
 *
 * ================================================================
 * ▼ プラグインコマンド 詳細
 * --------------------------------
 *  〇 ChoicePos x y[ row]
 *      x   : 選択肢ウィンドウのX座標
 *      y   : 選択肢ウィンドウのY座標
 *      row : 選択肢ウィンドウの行数。未設定の場合はすべて表示
 *
 *   次に表示する選択肢の位置(x,y)と行数(row)指定します。
 *
 * --------------------------------
 *  〇 ChoiceVariableId n
 *      n : 変数番号
 *
 *   次に表示する選択肢のデフォルト位置を変数の値にします。
 *   さらに現在のカーソル位置を変数に入れます。
 *
 *   カーソル位置は最初の選択肢が上から0～5、次の選択肢は10～15と、
 *   選択肢毎に+10されます。
 *
 *   変数に入った値の項目が表示されない場合、なしと同じ処理をします。
 *
 * --------------------------------
 *  〇 ChoiceRect x y width height
 *      x      : X座標
 *      y      : Y座標
 *      width  : 幅
 *      height : 高さ
 *
 *   次に表示する選択肢の座標とサイズを指定します。
 *
 *   各項目、未設定もしくは-1を指定した場合、通常の値が適用されます。
 *
 * --------------------------------
 *  〇 ChoiceUnderMessage
 *
 *   次に表示する選択肢をメッセージウィンドウ内に表示させます。
 *
 *   この機能は[文章の表示]と併用しなければ機能しません。
 *   [文章の表示]の前に実行してください。
 *
 *   選択肢ウィンドウの[背景]は設定したものが適用されます。
 *
 *
 * ================================================================
 * ▼ 選択肢テキスト 詳細
 * --------------------------------
 *  〇 項目が表示される条件の設定
 *   選択肢の文章中に
 *     if(条件)
 *   と入れ、その条件が偽になると項目が表示されなくなります。
 *
 *   『デフォルト』の項目が表示されない場合の動作は、
 *   プラグインパラメータの[Disabled Index]にて設定できます。
 *
 *   『キャンセル』の項目が表示されない場合、禁止と同じ処理をします。
 *
 *   条件内では s でスイッチ、v で変数を参照できます。
 *
 *     例：if(s[1]) とした場合
 *          => スイッチ１番がONで表示、OFFで非表示。
 *        if(!s[2]) とした場合
 *          => スイッチ２番がOFFで表示、ONで非表示。
 *        if(v[5]>0) とした場合
 *          => 変数５番が0より大きければ表示、0以下で非表示。
 *
 *     変数で使える不等号
 *       === : 等しい
 *       !== : 等しくない
 *       <   : より小さい
 *       <=  : より小さいまたは等しい
 *       >   : より大きい
 *       >=  : より大きいまたは等しい
 *
 *     条件式はeval関数で処理されているため、他演算子も使用できます。
 *
 * --------------------------------
 *  〇 項目を半透明で表示する条件の設定
 *   選択肢の文章中に
 *     en(条件)
 *   と入れ、その条件が偽になると項目が半透明で表示されます。
 *   半透明となった項目は選択できなくなります。
 *
 *   条件は上の『項目が表示される条件の設定』と同じです。
 *
 *   『キャンセル』の項目が半透明の場合、ブザーが鳴ります。
 *
 *
 * ================================================================
 * ▼ プラグインパラメータ 詳細
 * --------------------------------
 *  〇 Disabled Index
 *
 *   [デフォルト]となる項目がif(条件)により非表示となった場合、
 *   デフォルト位置をどこにするかを設定します。
 *
 *     none : [なし]と同じ
 *     top  : 先頭の項目
 *
 * --------------------------------
 *  〇 Plugin Commands / Event Comment
 *
 *   プラグインコマンドや注釈で使用するコマンドは、
 *   プラグインパラメータから変更できます。
 *
 *   コマンドを短くしたり日本語にしたりなどして、
 *   自分が使いやすいようにしてください。
 *
 *   プラグインコマンドのみ、変更後もデフォルトのコマンドでも動作します。
 *
 *
 * ================================================================
 * ▼ その他
 * --------------------------------
 *  〇 プラグインコマンドの実行タイミング
 *   プラグインコマンドを使用する場合、[選択肢の表示]の前に実行するのが
 *   好ましいです。
 *   ただし、メッセージウィンドウを表示したまま選択肢の処理を実行したい場合、
 *   [文章の表示]より前にプラグインコマンドを実行してください。
 *
 * --------------------------------
 *  〇 ヘルプメッセージの表示
 *   各選択肢項目の下に注釈で以下の文字列を入れると、
 *   続きの文章をヘルプメッセージとしてカーソルを合わせたときに
 *   標示させることができます。
 *
 *     選択肢ヘルプ
 *
 *   ※注意点
 *    ヘルプメッセージは[文章の表示]と同じ機能を使っているため、
 *    制御文字が使用できます。
 *    ただし、\!と\^は使用できません。
 *
 * ================================
 * 制作 : 木星ペンギン
 * URL : http://woodpenguin.blog.fc2.com/
 *
 * @param maxPageRow
 * @type number
 * @desc 1ページに表示される行数
 * @default 6
 *
 * @param Disabled Index
 * @type select
 * @option none
 * @option top
 * @desc [デフォルト]となる選択肢が表示されない場合のデフォルト位置
 * @default none
 *
 *
 * @param === Command ===
 *
 * @param Plugin Commands
 * @type struct<Plugin>
 * @desc プラグインコマンド名
 * @default {"ChoicePos":"ChoicePos","ChoiceVariableId":"ChoiceVariableId","ChoiceRect":"ChoiceRect","ChoiceUnderMessage":"ChoiceUnderMessage"}
 * @parent === Command ===
 *
 * @param Event Comment
 * @type struct<EventComment>
 * @desc イベントの注釈で使うコマンド名
 * @default {"ChoiceHelp":"選択肢ヘルプ"}
 * @parent === Command ===
 *
 */

/*~struct~Plugin:
 * @param ChoicePos
 * @desc 選択肢の位置(x,y)と行数(row)指定
 * @default ChoicePos
 *
 * @param ChoiceVariableId
 * @desc 選択肢のデフォルト位置を変数n番にする
 * @default ChoiceVariableId
 *
 * @param ChoiceRect
 * @desc 選択肢の座標とサイズ(x,y,width,height)指定
 * @default ChoiceRect
 *
 * @param ChoiceUnderMessage
 * @desc 選択肢をメッセージの下に表示
 * @default ChoiceUnderMessage
 *
 */

/*~struct~EventComment:
 * @param ChoiceHelp
 * @desc 各項目の下に設定することでヘルプを表示させる
 * @default 選択肢ヘルプ
 */

(function() {

const MPPlugin = {};

{

    let parameters = PluginManager.parameters('MPP_ChoiceEX');

    MPPlugin.maxPageRow = Number(parameters['maxPageRow']);
    MPPlugin.DisabledIndex = parameters['Disabled Index'];

    MPPlugin.PluginCommands = JSON.parse(parameters['Plugin Commands']);
    MPPlugin.EventComment = JSON.parse(parameters['Event Comment']);

}

const Alias = {};

//-----------------------------------------------------------------------------
// Game_Message

//15
Alias.GaMe_clear = Game_Message.prototype.clear;
Game_Message.prototype.clear = function() {
    Alias.GaMe_clear.apply(this, arguments);
    this._choiceEnables = [];
    this._choiceResults = [];
    this._helpTexts = [];
    this._choiceX = -1;
    this._choiceY = -1;
    this._choiceWidth = -1;
    this._choiceHeight = -1;
    this._choiceMaxRow = MPPlugin.maxPageRow;
    this._choiceVariableId = 0;
    this.choiceUnderMes = false;
};

Game_Message.prototype.setChoiceEnables = function(enables) {
    this._choiceEnables = enables;
};

Game_Message.prototype.choiceEnables = function() {
    return this._choiceEnables;
};

Game_Message.prototype.setChoiceResults = function(results) {
    this._choiceResults = results;
};

Game_Message.prototype.setChoiceHelpTexts = function(texts) {
    this._helpTexts = texts;
};

Game_Message.prototype.isHelp = function() {
    return this._helpTexts.length > 0;
};

Game_Message.prototype.setChoicePos = function(x, y, row) {
    this._choiceX = x;
    this._choiceY = y;
    this._choiceWidth = -1;
    this._choiceHeight = -1;
    this._choiceMaxRow = row;
};

Game_Message.prototype.setChoiceRect = function(x, y, width, height) {
    this._choiceX = x;
    this._choiceY = y;
    this._choiceWidth = width;
    this._choiceHeight = height;
};

Game_Message.prototype.setChoiceVariableId = function(id) {
    this._choiceVariableId = id;
};

Game_Message.prototype.shiftLine = function(height) {
    this._choiceY += height;
    this._choiceHeight -= height;
};

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

//336
Game_Interpreter.prototype.setupChoices = function(params) {
    var data = {
        choices: [],
        enables: [],
        results: [],
        helpTexts: [],
        cancelType: -1,
        defaultType: -1,
        positionType: 0,
        background: 0
    };
    data = this.addChoices(params, this._index, data, 0);
    if (data.choices.length > 0) {
        var helpTexts = [];
        if (data.helpTexts.length > 0) {
            helpTexts = data.results.map( i => data.helpTexts[i] );
        }
        var cancelType = -1;
        if (data.cancelType.mod(10) === 8 || data.results.contains(data.cancelType)) {
            data.results.push(data.cancelType);
            cancelType = data.choices.length;
        }
        var index = data.defaultType;
        if ($gameMessage._choiceVariableId > 0) {
            index = $gameVariables.value($gameMessage._choiceVariableId);
        }
        var defaultType = data.results.indexOf(index);
        if (index >= 0 && defaultType < 0 && MPPlugin.DisabledIndex === "top")  {
            defaultType = 0;
        }
        $gameMessage.setChoices(data.choices, defaultType, cancelType);
        $gameMessage.setChoiceEnables(data.enables);
        $gameMessage.setChoiceResults(data.results);
        $gameMessage.setChoiceHelpTexts(helpTexts);
        $gameMessage.setChoiceBackground(data.background);
        $gameMessage.setChoicePositionType(data.positionType);
        $gameMessage.setChoiceCallback( n => this._branch[this._indent] = data.results[n] );
    } else {
        this._branch[this._indent] = -1;
    }
};

Game_Interpreter.prototype.addChoices = function(params, i, data, d) {
    var regIf = /\s*if\((.+?)\)/;
    var regEn = /\s*en\((.+?)\)/;
    for (var n = 0; n < params[0].length; n++) {
        var str = params[0][n];
        if (regIf.test(str)) {
            str = str.replace(regIf, '');
            if (RegExp.$1 && !this.evalChoice(RegExp.$1)) continue;
        }
        var enable = true;
        if (regEn.test(str)) {
            str = str.replace(regEn, '');
            enable = this.evalChoice(RegExp.$1);
        }
        data.choices.push(str);
        data.enables.push(enable);
        data.results.push(n + d);
    }
    var cancelType = params[1];
    if (cancelType !== -1) {
        data.cancelType = cancelType + d;
    }
    var defaultType = params.length > 2 ? params[2] : 0;
    if (defaultType >= 0) {
        data.defaultType = defaultType + d;
    }
    data.positionType = params.length > 3 ? params[3] : 2;
    data.background = params.length > 4 ? params[4] : 0;
    var command;
    for (;;) {
        i++;
        command = this._list[i];
        if (!command) break;
        if (command.indent === this._indent) {
            if (command.code === 402) {
                this.getHelpText(command.parameters[0] + d, i + 1, data);
            } else if (command.code === 404) {
                break;
            }
        }
    }
    command = this._list[i + 1];
    if (command && command.code === 102) {
        this.addChoices(command.parameters, i + 1, data, d + 10);
    }
    return data;
};

Game_Interpreter.prototype.getHelpText = function(c, i, data) {
    var command = MPPlugin.EventComment.ChoiceHelp || '選択肢ヘルプ';
    if (this._list[i].code === 108 && this._list[i].parameters[0] === command) {
        var texts = [];
        while (this._list[i + 1].code === 408) {
            i++;
            texts.push(this._list[i].parameters[0]);
        }
        data.helpTexts[c] = texts;
    }
};

Game_Interpreter.prototype.evalChoice = function(formula) {
    try {
        var s = $gameSwitches._data;
        var formula2 = formula.replace(/v\[(\d+)\]/g,
            (match, p1) => $gameVariables.value(parseInt(p1)) );
        return !!eval(formula2);
    } catch (e) {
        alert("条件エラー \n\n " + formula);
        return true;
    }
};

//362
Game_Interpreter.prototype.command403 = function() {
    if (this._branch[this._indent] !== -2) {
        this.skipBranch();
    }
    return true;
};

Game_Interpreter.prototype.command404 = function() {
    if (this.nextEventCode() === 102) {
        this._branch[this._indent] -= 10;
        this._index++;
    }
    return true;
};

//1739
Alias.GaIn_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    Alias.GaIn_pluginCommand.apply(this, arguments);
    var args2 = this.mppPluginCommandArgs(args);
    switch (command) {
        case MPPlugin.PluginCommands.ChoicePos:
        case 'ChoicePos':
            var x = args2[0];
            var y = args2[1];
            var row = args2[2] || 99;
            $gameMessage.setChoicePos(x, y, row);
            break;
        case MPPlugin.PluginCommands.ChoiceVariableId:
        case 'ChoiceVariableId':
            $gameMessage.setChoiceVariableId(args2[0]);
            break;
        case MPPlugin.PluginCommands.ChoiceRect:
        case 'ChoiceRect':
            var x = (args2[0] === undefined ? -1 : args2[0]);
            var y = (args2[1] === undefined ? -1 : args2[1]);
            var width = (args2[2] === undefined ? -1 : args2[2]);
            var height = (args2[3] === undefined ? -1 : args2[3]);
            $gameMessage.setChoiceRect(x, y, width, height);
            break;
        case MPPlugin.PluginCommands.ChoiceUnderMessage:
        case 'ChoiceUnderMessage':
            $gameMessage.choiceUnderMes = true;
            break;
    }
    return true;
};

Game_Interpreter.prototype.mppPluginCommandArgs = function(args) {
    var v = $gameVariables._data;
    return args.map(function(arg) {
        try {
            return eval(arg) || 0;
        } catch (e) {
            return arg;
        }
    });
};

//-----------------------------------------------------------------------------
// Window

Window.prototype.isClearWindowRect = function() {
    return true;
};

//-----------------------------------------------------------------------------
// WindowLayer

//7100
Alias.WiLa__canvasClearWindowRect = WindowLayer.prototype._canvasClearWindowRect;
WindowLayer.prototype._canvasClearWindowRect = function(renderSession, window) {
    if (window.isClearWindowRect())
        Alias.WiLa__canvasClearWindowRect.apply(this, arguments);
};

//7162
Alias.WiLa__maskWindow = WindowLayer.prototype._maskWindow;
WindowLayer.prototype._maskWindow = function(window, shift) {
    Alias.WiLa__maskWindow.apply(this, arguments);
    if (!window.isClearWindowRect()) {
        var rect = this._windowRect;
        rect.x = 0;
        rect.y = 0;
        rect.width = 0;
        rect.height = 0;
    }
};

//-----------------------------------------------------------------------------
// Window_ChoiceList

Window_ChoiceList.prototype.isClearWindowRect = function() {
    return !this._underMessage;
};

if (Window_ChoiceList.prototype.hasOwnProperty('close')) {
    Alias.WiChLi_close = Window_ChoiceList.prototype.close
}
Window_ChoiceList.prototype.close = function() {
    if ($gameMessage.isHelp()) this._messageWindow.onShowFast();
    var _super = Alias.WiChLi_close || Window_Command.prototype.close;
    _super.apply(this, arguments);
};

if (Window_ChoiceList.prototype.hasOwnProperty('select')) {
    Alias.WiChli_select = Window_ChoiceList.prototype.select;
}
Window_ChoiceList.prototype.select = function(index) {
    var variableId = $gameMessage._choiceVariableId;
    if (index !== this.index() && variableId > 0) {
        var results = $gameMessage._choiceResults;
        $gameVariables.setValue(variableId, results[index]);
    }
    var _super = Alias.WiChli_select = Window_Command.prototype.select
    _super.apply(this, arguments);
};

//34
Alias.WiChLi_updatePlacement = Window_ChoiceList.prototype.updatePlacement;
Window_ChoiceList.prototype.updatePlacement = function() {
    Alias.WiChLi_updatePlacement.apply(this, arguments);
    if ($gameMessage._choiceWidth >= 0) {
        this.width = Math.min($gameMessage._choiceWidth, Graphics.boxWidth);
    }
    if ($gameMessage._choiceHeight >= 0) {
        this.height = Math.min($gameMessage._choiceHeight, Graphics.boxHeight);
    }
    if ($gameMessage._choiceX >= 0) {
        this.x = Math.min($gameMessage._choiceX, Graphics.boxWidth - this.width);
    }
    if ($gameMessage._choiceY >= 0) {
        this.y = Math.min($gameMessage._choiceY, Graphics.boxHeight - this.height);
    }
    this._underMessage = $gameMessage.choiceUnderMes;
};

//67
Window_ChoiceList.prototype.numVisibleRows = function() {
    return Math.min($gameMessage.choices().length, $gameMessage._choiceMaxRow);
};

//103
Window_ChoiceList.prototype.makeCommandList = function() {
    var choices = $gameMessage.choices();
    var enables = $gameMessage._choiceEnables;
    for (var i = 0; i < choices.length; i++) {
        this.addCommand(choices[i], 'choice', enables[i]);
    }
};

//110
Alias.WiChLi_drawItem = Window_ChoiceList.prototype.drawItem;
Window_ChoiceList.prototype.drawItem = function(index) {
    this.changePaintOpacity(this.isCommandEnabled(index));
    Alias.WiChLi_drawItem.apply(this, arguments);
};

//123
Alias.WiChLi_callOkHandler = Window_ChoiceList.prototype.callOkHandler;
Window_ChoiceList.prototype.callOkHandler = function() {
    Alias.WiChLi_callOkHandler.apply(this, arguments);
    this._messageWindow.forceClear();
};

//129
Alias.WiChLi_callCancelHandler = Window_ChoiceList.prototype.callCancelHandler;
Window_ChoiceList.prototype.callCancelHandler = function() {
    Alias.WiChLi_callCancelHandler.apply(this, arguments);
    this._messageWindow.forceClear();
};

if (Window_ChoiceList.prototype.hasOwnProperty('processCancel')) {
    Alias.WiChLi_processCancel = Window_ChoiceList.prototype.processCancel
}
Window_ChoiceList.prototype.processCancel = function() {
    var type = $gameMessage.choiceCancelType();
    var results = $gameMessage._choiceResults;
    var index = results.indexOf(results[type]);
    if (this.isCancelEnabled() && index !== type && !this.isCommandEnabled(index)) {
        this.playBuzzerSound();
    } else {
        var _super = Alias.WiChLi_processCancel || Window_Command.prototype.processCancel;
        _super.apply(this, arguments);
    }
};

Window_ChoiceList.prototype.callUpdateHelp = function() {
    if (this.active && this._messageWindow && $gameMessage.isHelp())
        this.updateHelp();
};

Window_ChoiceList.prototype.updateHelp = function() {
    this._messageWindow.forceClear();
    var texts = $gameMessage._helpTexts[this.index()];
    $gameMessage._texts = texts ? texts.clone() : [''];
    this._messageWindow.startMessage();
};

//-----------------------------------------------------------------------------
// Window_Message

//109
Alias.WiMe_updatePlacement = Window_Message.prototype.updatePlacement;
Window_Message.prototype.updatePlacement = function() {
    Alias.WiMe_updatePlacement.apply(this, arguments);
    this.clearUnderChoice();
};

Window_Message.prototype.clearUnderChoice = function() {
    if ($gameMessage.choiceUnderMes) {
        var x = this.x + this.standardPadding();
        x += this._textState.left || 0;
        var y = this.y + 4;
        var height = this.windowHeight();
        $gameMessage.setChoiceRect(x, y, -1, height);
    }
};

if (Window_Message.prototype.hasOwnProperty('processNewLine')) {
    Alias.WiMe_processNewLine = Window_Message.prototype.processNewLine;
}
Window_Message.prototype.processNewLine = function(textState) {
    if ($gameMessage.choiceUnderMes) $gameMessage.shiftLine(textState.height);
    var _super = Alias.WiMe_processNewLine || Window_Base.prototype.processNewLine;
    _super.apply(this, arguments);
};

//149
Alias.WiMe_updateInput = Window_Message.prototype.updateInput;
Window_Message.prototype.updateInput = function() {
    if ($gameMessage.isHelp() && this._textState) return false;
    return Alias.WiMe_updateInput.apply(this, arguments);
};

//196
Alias.WiMe_onEndOfText = Window_Message.prototype.onEndOfText;
Window_Message.prototype.onEndOfText = function() {
    if ($gameMessage.isHelp() && !this._choiceWindow.active) {
        this.startInput();
    } else {
        Alias.WiMe_onEndOfText.apply(this, arguments);
    }
};

//207
Alias.WiMe_startInput = Window_Message.prototype.startInput;
Window_Message.prototype.startInput = function() {
    if (this._choiceWindow.active) return true;
    if ($gameMessage.isChoice() && $gameMessage.choiceUnderMes &&
            this._textState.x !== this._textState.left) {
        $gameMessage.shiftLine(this._textState.height);
    }
    return Alias.WiMe_startInput.apply(this, arguments);
};

Window_Message.prototype.forceClear = function() {
    this._textState = null;
    this.close();
    this._goldWindow.close();
};

Window_Message.prototype.onShowFast = function() {
    this._showFast = true;
};

//243
Alias.WiMe_newPage = Window_Message.prototype.newPage;
Window_Message.prototype.newPage = function(textState) {
    Alias.WiMe_newPage.apply(this, arguments);
    this.clearUnderChoice();
};

})();


code:
//=============================================================================
// MPP_DeleteSelfSwitch.js
//=============================================================================
// Copyright (c) 2021 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @target MV MZ
 * @plugindesc When you move to another place, turn off the specified self-switch.
 * @author Mokusei Penguin
 * @url
 *
 * @help [version 2.0.0]
 * This plugin is for RPG Maker MV and MZ.
 *
 * ▼ Plugin command details
 *  - In MV, the variable N is referred to by writing v [N] in the item for
 *    inputting a numerical value.
 *  - In MZ, in the item to enter a numerical value, select the text and
 *    write v [N] to refer to the variable N.
 *
 *  〇 MV / MZ
 *
 *  〇 DeleteSelfSwitch mapIds sw  / delete
 *      mapIds : Range can be specified
 *      sw     : Self switch to turn off
 *   - Turns off all self-switches on the specified map.
 *   - When specifying the range, do not put a space between them. (MV only)
 *   - Do not put a space between the self-switch specifications.
 *       Example： DeleteSelfSwitch 1 A
 *                   => Change self-switch A of map ID 1 to OFF
 *                 DeleteSelfSwitch v[13] BCD
 *                   => Change the self-switch B, C, D of the map ID of
 *                      variable 13 to OFF
 *                 DeleteSelfSwitch 1-5,8 BC
 *                   => Change the self-switches B and C of map IDs 1 to 5 and
 *                      8 to OFF
 *
 * ▼ About range specification
 *  - When setting numbers in an array, you can specify numbers from n to m by
 *    writing n-m.
 *      Example: 1-4,8,10-12
 *
 * ================================
 * Mail : wood_penguin＠yahoo.co.jp (＠ is half-width)
 * Blog : http://woodpenguin.blog.fc2.com/
 * License : MIT license
 *
 * @command delete
 * @desc
 *
 * @arg mapIds
 * @desc Range can be specified
 * @default 0
 *
 * @arg switchs
 * @desc
 * @default ABCD
 *
 * @--------------------------------
 *
 * @param Map IDs
 * @desc Map ID that turns off the self-switch when moving to another location
 * (All maps if empty / Range can be specified)
 * @default
 *
 * @param Self Switches
 * @desc Self switch to turn off
 * @default ABCD
 *
 * @param Self Variables
 * @desc Self variable to be 0
 * (Only when MPP_SelfVariable is installed / Range can be specified)
 * @default
 *
 */

/*:ja
 * @target MV MZ
 * @plugindesc 場所移動した際に、指定したセルフスイッチをOFFにします。
 * @author 木星ペンギン
 * @url
 *
 * @help [version 2.0.0]
 * このプラグインはRPGツクールMVおよびMZ用です。
 *
 * ▼ プラグインコマンド
 *  - MVでは数値を入力する項目で v[N] と記述することで変数N番を参照します。
 *  - MZでは数値を入力する項目で、テキストを選択して v[N] と記述することで
 *    変数N番を参照します。
 *
 *  〇 MV / MZ
 *
 *  〇 DeleteSelfSwitch mapIds sw  / セルフスイッチ削除
 *      mapIds : マップID (範囲指定可)
 *      sw     : OFFにするセルフスイッチ
 *   - 指定したマップのセルフスイッチを全てOFFにします。
 *   - 範囲指定する場合は間にスペースを入れないでください。(MVのみ)
 *   - セルフスイッチの指定は間にスペースを入れないでください。
 *       例： DeleteSelfSwitch 1 A
 *             => マップID 1 番のセルフスイッチ A をOFFに変更
 *           DeleteSelfSwitch v[13] BCD
 *             => 変数13番のマップIDのセルフスイッチ B,C,D をOFFに変更
 *           DeleteSelfSwitch 1-5,8 BC
 *             => マップID 1～5と8 のセルフスイッチ B,C をOFFに変更
 *
 * ▼ 範囲指定について
 *  - 数値を配列で設定する際、n-m と表記することでnからmまでの数値を指定できます。
 *      例: 1-4,8,10-12
 *
 * ================================
 * Mail : wood_penguin＠yahoo.co.jp (＠は半角)
 * Blog : http://woodpenguin.blog.fc2.com/
 * License : MIT license
 *
 * @command delete
 * @text 削除
 * @desc
 *
 * @arg mapIds
 * @text マップID
 * @desc 範囲指定可
 * @default 0
 *
 * @arg switchs
 * @text スイッチ
 * @desc
 * @default ABCD
 *
 * @--------------------------------
 *
 * @param Map IDs
 * @text マップID
 * @desc 場所移動でセルフスイッチをOFFにするマップIDの配列
 * (空の場合はすべてのマップ / 範囲指定可)
 * @default
 *
 * @param Self Switches
 * @text セルフスイッチ
 * @desc OFFにするセルフスイッチ
 * @default ABCD
 *
 * @param Self Variables
 * @text セルフ変数
 * @desc 0にするセルフ変数
 * (MPP_SelfVariable導入時のみ / 範囲指定可)
 * @default
 *
 */

(() => {
    'use strict';

    const pluginName = 'MPP_DeleteSelfSwitch';

    // Plugin Parameters
    const parameters = PluginManager.parameters(pluginName);
    const convertToArray = (param) => {
        return param.split(',').reduce((r, item) => {
            const match = /(\d+)-(\d+)/.exec(item);
            if (match) {
                const start = Number(match[1]);
                const end = Number(match[2]);
                return r.concat([...Array(end + 1).keys()].slice(start));
            } else {
                return item ? r.concat(Number(item)) : r;
            }
        }, []);
    };
    const params_MapIDs = convertToArray(parameters['Map IDs']);
    const params_SelfSwitches = parameters['Self Switches'];
    const params_SelfVariables = convertToArray(parameters['Self Variables']);

    // Dealing with other plugins
    const _importedPlugin = (...names) => {
        return names.some(name => PluginManager._scripts.includes(name));
    };

    //-------------------------------------------------------------------------
    // Game_SelfSwitches

    Game_SelfSwitches.prototype.delete = function(mapId, switchs) {
        const re = new RegExp('%1,\\d+,[%2]'.format(mapId, switchs));
        for (const key in this._data) {
            if (re.test(key)) {
                delete this._data[key];
            }
        }
        this.onChange();
    };

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

    const _Game_Map_setup = Game_Map.prototype.setup;
    Game_Map.prototype.setup = function(mapId) {
        if (
            this._mapId !== mapId &&
            (params_MapIDs.length === 0 || params_MapIDs.includes(this._mapId))
        ) {
            $gameSelfSwitches.delete(this._mapId, params_SelfSwitches);
            if (_importedPlugin('MPP_SelfVariable')) {
                $gameVariables.deleteSelfValues(this._mapId, [], params_SelfVariables);
            }
        }
        _Game_Map_setup.apply(this, arguments);
    };

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

    const _mzCommands = {
        DeleteSelfSwitch: { name:'delete', keys:['mapIds', 'switchs'] }
    };
    Object.assign(_mzCommands, {
        'セルフスイッチ削除': _mzCommands.DeleteSelfSwitch
    });

    const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.apply(this, arguments);
        const mzCommand = _mzCommands[command];
        if (mzCommand) {
            const args2 = Object.assign(...mzCommand.keys.map((k,i) => ({[k]:args[i]})));
            PluginManager.callCommand(this, pluginName, mzCommand.name, args2);
        }
    };

    //-------------------------------------------------------------------------
    // PluginManager

    PluginManager._commands = PluginManager._commands || {};

    if (!PluginManager.registerCommand) {
        PluginManager.registerCommand = function(pluginName, commandName, func) {
            const key = pluginName + ":" + commandName;
            this._commands[key] = func;
        };
    }

    if (!PluginManager.callCommand) {
        PluginManager.callCommand = function(self, pluginName, commandName, args) {
            const key = pluginName + ":" + commandName;
            const func = this._commands[key];
            if (typeof func === "function") {
                func.bind(self)(args);
            }
        };
    }

    PluginManager.registerCommand(pluginName, 'delete', args => {
        const switchs = args.switchs.toUpperCase();
        for (const mapId of PluginManager.mppConvertRange(args.mapIds)) {
            $gameSelfSwitches.delete(mapId, switchs);
        }
    });

    PluginManager.mppConvertRange = function(text) {
        return convertToArray(text.replace(/V\[(\d+)\]/gi, (_, p1) =>
            $gameVariables.value(parseInt(p1))
        ));
    };

})();

repo_name: onms/melphias

license: unknown


code:
//=============================================================================
// MPP_MapLight.js
//=============================================================================
// Copyright (c) 2018 - 2021 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @target MV MZ
 * @plugindesc Allows you to set the brightness of the map.
 * @author Mokusei Penguin
 * @url
 *
 * @help [version 3.2.2]
 * This plugin is for RPG Maker MV and MZ.
 *
 * ▼ Specification
 *  - Only one CharLight and one FrontLight can be added to each character.
 *  - Lights created on events and maps will be reset by changing the map.
 *  - The player's lights will remain even if the map is changed.
 *
 * ▼ Plugin command
 *  - In MV, the variable N is referred to by writing v [N] in the item for
 *    inputting a numerical value.
 *  - In MZ, in the item to enter a numerical value, select the text and
 *    write v [N] to refer to the variable N.
 *  - For the color index (c), specify the one set in the plug-in parameter
 *    [Light Colors].
 *
 *  〇 MV / MZ
 *
 *  〇 SetCharLight evId r c a  / setCharLight
 *      evId : -1:Player, 0:This event, 1..:EventID
 *      r    : radius(1 = 1 square)
 *      c    : color index(Erase with 0)
 *      a    : amplitude(Specify from 0-100 / No blinking at 0 / Not set is 0)
 *   - The light is displayed around the character.
 *
 *  〇 SetPosLight x y r c a  / setPosLight
 *      x   : X coordinate
 *      y   : Y coordinate
 *      r   : radius(1 = 1 square)
 *      c   : color index(Erase with 0)
 *      a   : amplitude(Specify from 0-100 / No blinking at 0 / Not set is 0)
 *   - Lights up at the specified coordinates (x, y).
 *
 *  〇 SetFrontLight evId r c a  / setFrontLight
 *      evId : -1:Player, 0:This event, 1..:EventID
 *      c    : color index(Erase with 0)
 *      a    : amplitude(Specify from 0-100 / No blinking at 0 / Not set is 0)
 *   - A light is displayed in front of the character.
 *
 *  〇 EraseCharLight lId  / eraseCharLight
 *      evId : -1:Player, 0:This event, 1..:EventID
 *   - Turns off the lights centered on the character.
 *
 *  〇 ErasePosLight x y  / erasePosLight
 *      x   : X coordinate
 *      y   : Y coordinate
 *   - Turns off the light at the specified coordinates (x, y).
 *
 *  〇 EraseFrontLight lId  / eraseFrontLight
 *      evId : -1:Player, 0:This event, 1..:EventID
 *   - Turns off the light that illuminates the front of the character.
 *
 *  〇 SetMapDarkness d  / setDarkness
 *      d : Map darkness(Specify from 0-100)
 *   - Change the darkness of the map.
 *
 * ▼ Map notes
 *  〇 <Darkness:n>
 *      n : Map darkness(Specify from 0-100)
 *   - Specifies the darkness of the map.
 *   - By writing v[n], the value of the nth variable is referenced.
 *   - However, it is only referenced when you switch maps.
 *
 *  〇 <PosLight X,Y:r,c,a>
 *      X   : X coordinate
 *      Y   : Y coordinate
 *      r   : radius(1 = 1 square)
 *      c   : color index
 *      a   : amplitude(Specify from 0-100 / No blinking at 0 / Not set is 0)
 *   - Places the light at the specified coordinates (x, y).
 *
 * ▼ Annotation of event execution content
 *  〇 CharLight r c a
 *      r   : radius(1 = 1 square)
 *      c   : color index
 *      a   : amplitude(Specify from 0-100 / No blinking at 0 / Not set is 0)
 *   - Lights are displayed around this event.
 *   - This command applies only to the first annotation of the execution.
 *
 * ================================
 * Mail : wood_penguin＠yahoo.co.jp (＠ is half-width)
 * Blog : http://woodpenguin.blog.fc2.com/
 * License : MIT license
 *
 *  @command setCharLight
 *      @desc
 *      @arg character
 *          @desc -1:Player, 0:This event, 1..:EventID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *      @arg radius
 *          @desc 1 = 1 square
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg colorIndex
 *          @desc Specified by plug-in parameter [Light Colors] / 0:erase
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg amplitude
 *          @desc 0-100
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 0
 *
 *  @command setPosLight
 *      @desc
 *      @arg x
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *      @arg y
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *      @arg radius
 *          @desc 1 = 1 square
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg colorIndex
 *          @desc Specified by plug-in parameter [Light Colors] / 0:erase
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg amplitude
 *          @desc 0-100
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 0
 *
 *  @command setFrontLight
 *      @desc
 *      @arg character
 *          @desc -1:Player, 0:This event, 1..:EventID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *      @arg colorIndex
 *          @desc Specified by plug-in parameter [Light Colors] / 0:erase
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg amplitude
 *          @desc 0-100
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 0
 *
 *  @command eraseCharLight
 *      @desc
 *      @arg character
 *          @desc -1:Player, 0:This event, 1..:EventID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *
 *  @command erasePosLight
 *      @desc
 *      @arg x
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *      @arg y
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *
 *  @command eraseFrontLight
 *      @desc
 *      @arg character
 *          @desc -1:Player, 0:This event, 1..:EventID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *
 *  @command setDarkness
 *      @desc
 *      @arg darkness
 *          @desc
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 100
 *
 *
 *  @param Light Colors
 *      @desc
 *      @type string[]
 *      @default ["255,255,255","192,128,64","32,32,32"]
 *
 *  @param Front Light
 *      @desc
 *      @type struct<FrontLight>
 *      @default {"Radius":"6","Angle":"90","Oy":"4","Turn Duration":"24"}
 *
 *  @param Darkness Size
 *      @desc Resolution per tile
 *      @type number
 *          @min 1
 *          @max 48
 *      @default 3
 *
 */

/*~struct~FrontLight:
 *  @param Radius
 *      @desc
 *      @type number
 *          @min 1
 *          @max 99
 *      @default 6
 *
 *  @param Angle
 *      @desc
 *      @type number
 *          @min 1
 *          @max 180
 *      @default 90
 *
 *  @param Oy
 *      @desc
 *      @type number
 *          @min -9999
 *          @max 9999
 *      @default 4
 *
 *  @param Turn Duration
 *      @desc
 *      @type number
 *          @min 0
 *          @max 999
 *      @default 24
 *
 */

/*:ja
 * @target MV MZ
 * @plugindesc マップの明るさを設定できるようにします。
 * @author 木星ペンギン
 * @url
 *
 * @help [version 3.2.2]
 * このプラグインはRPGツクールMVおよびMZ用です。
 *
 * ▼ 仕様
 *  - キャラクター一人に対して付加できる灯りは、キャラ灯りと前方灯りそれぞれ
 *    １つまでです。
 *  - イベントやマップ上に作成した灯りは、マップ切り替えでリセットされます。
 *  - プレイヤーの灯りはマップ移動しても維持されます。
 *
 * ▼ プラグインコマンド
 *  - MVでは数値を入力する項目で v[N] と記述することで変数N番を参照します。
 *  - MZでは数値を入力する項目で、テキストを選択して v[N] と記述することで
 *    変数N番を参照します。
 *  - 色番号(c)はプラグインパラメータ[Light Colors]で設定したものを指定してください。
 *
 *  〇 MV / MZ
 *
 *  〇 SetCharLight evId r c a  / キャラ灯り設定
 *      evId : イベントID(-1:プレイヤー, 0:このイベント)
 *      r    : 半径(1で1マス分)
 *      c    : 色番号(0で消去)
 *      a    : 明滅の振れ幅(0～100で指定 / 0で明滅なし / 未設定は0)
 *   - キャラクターを中心に灯りを表示します。
 *
 *  〇 SetPosLight x y r c a  / マップ灯り設定
 *      x   : X座標
 *      y   : Y座標
 *      r   : 半径(1で1マス分)
 *      c   : 色番号(0で消去)
 *      a   : 明滅の振れ幅(0～100で指定 / 0で明滅なし / 未設定は0)
 *   - 指定した座標(x,y)に灯り表示します。
 *
 *  〇 SetFrontLight evId r c a  / 前方灯り設定
 *      evId : イベントID(-1:プレイヤー, 0:このイベント)
 *      c    : 色番号(0で消去)
 *      a    : 明滅の振れ幅(0～100で指定 / 0で明滅なし / 未設定は0)
 *   - キャラクターの前方に灯りを表示します。
 *
 *  〇 EraseCharLight lId  / キャラ灯り消去
 *      evId : イベントID(-1:プレイヤー, 0:このイベント)
 *   - キャラクターを中心とした灯りを消去します。
 *
 *  〇 ErasePosLight x y  / マップ灯り消去
 *      x   : X座標
 *      y   : Y座標
 *   - 指定した座標(x,y)の灯りを消去します。
 *
 *  〇 EraseFrontLight lId  / 前方灯り消去
 *      evId : イベントID(-1:プレイヤー, 0:このイベント)
 *   - キャラクターの前方を照らす灯りを消去します。
 *
 *  〇 SetMapDarkness d  / マップ暗さ設定
 *      d : マップの暗さ(0～100で指定)
 *   - マップの暗さを変更します。
 *
 * ▼ マップのメモ
 *  〇 <Darkness:n>
 *      n : マップの暗さ(0～100で指定)
 *   - マップの暗さを指定します。
 *   - v[n] と記述することでn番の変数の値を参照します。
 *   - ただし、参照されるのはマップの切り替えを行ったときのみです。
 *
 *  〇 <PosLight X,Y:r,c,a>
 *      X   : X座標
 *      Y   : Y座標
 *      r   : 半径(1で1マス分)
 *      c   : 色番号
 *      a   : 明滅の振れ幅(0～100で指定 / 0で明滅なし / 未設定は0)
 *   - 指定した座標(x,y)に灯りを配置します。
 *
 * ▼ イベントの実行内容の注釈
 *  〇 灯り r c a
 *      r   : 半径(1で1マス分)
 *      c   : 色番号
 *      a   : 明滅の振れ幅(0～100で指定 / 0で明滅なし / 未設定は0)
 *   - このイベントを中心に灯りを表示します。
 *   - このコマンドは実行内容の最初の注釈のみ適用されます。
 *
 * ================================
 * Mail : wood_penguin＠yahoo.co.jp (＠は半角)
 * Blog : http://woodpenguin.blog.fc2.com/
 * License : MIT license
 *
 *  @command setCharLight
 *      @text キャラ灯り設定
 *      @desc
 *      @arg character
 *          @text 対象キャラクター
 *          @desc -1:プレイヤー, 0:このイベント, 1..:イベントID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *      @arg radius
 *          @text 半径
 *          @desc 1 = 1マス
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg colorIndex
 *          @text 色番号
 *          @desc プラグインパラメータ[Light Colors]で指定 / 0:消去
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg amplitude
 *          @text 明滅の振れ幅
 *          @desc 0～100
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 0
 *
 *  @command setPosLight
 *      @text マップ灯り設定
 *      @desc
 *      @arg x
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *      @arg y
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *      @arg radius
 *          @text 半径
 *          @desc 1 = 1マス
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg colorIndex
 *          @text 色番号
 *          @desc プラグインパラメータ[Light Colors]で指定 / 0:消去
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg amplitude
 *          @text 明滅の振れ幅
 *          @desc 0～100
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 0
 *
 *  @command setFrontLight
 *      @text 前方灯り設定
 *      @desc
 *      @arg character
 *          @text 対象キャラクター
 *          @desc -1:プレイヤー, 0:このイベント, 1..:イベントID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *      @arg colorIndex
 *          @text 色番号
 *          @desc プラグインパラメータ[Light Colors]で指定 / 0:消去
 *          @type number
 *              @min 0
 *              @max 99
 *          @default 1
 *      @arg amplitude
 *          @text 明滅の振れ幅
 *          @desc 0～100
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 0
 *
 *  @command eraseCharLight
 *      @text キャラ灯り消去
 *      @desc
 *      @arg character
 *          @text 対象キャラクター
 *          @desc -1:プレイヤー, 0:このイベント, 1..:イベントID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *
 *  @command erasePosLight
 *      @text マップ灯り消去
 *      @desc
 *      @arg x
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *      @arg y
 *          @desc
 *          @type number
 *              @min -9999
 *              @max 9999
 *          @default 0
 *
 *  @command eraseFrontLight
 *      @text 前方灯り消去
 *      @desc
 *      @arg character
 *          @text 対象キャラクター
 *          @desc -1:プレイヤー, 0:このイベント, 1..:イベントID
 *          @type number
 *              @min -1
 *              @max 999
 *          @default 0
 *
 *  @command setDarkness
 *      @text マップ暗さ設定
 *      @desc
 *      @arg darkness
 *          @desc
 *          @type number
 *              @min 0
 *              @max 100
 *          @default 100
 *
 *
 *  @param Light Colors
 *      @text 灯りの色の配列
 *      @desc
 *      @type string[]
 *      @default ["255,255,255","192,128,64","32,32,32"]
 *
 *  @param Front Light
 *      @text 前方灯りパラメータ
 *      @desc
 *      @type struct<FrontLight>
 *      @default {"Radius":"6","Angle":"90","Oy":"4","Turn Duration":"24"}
 *
 *  @param Darkness Size
 *      @text 暗さの解像度
 *      @desc 1タイル当たりの解像度
 *      @type number
 *          @min 1
 *          @max 48
 *      @default 3
 *
 */

/*~struct~FrontLight:ja
 *  @param Radius
 *      @text 距離
 *      @desc
 *      @type number
 *          @min 1
 *          @max 99
 *      @default 6
 *
 *   @param Angle
 *      @text 角度
 *      @desc
 *      @type number
 *          @min 1
 *          @max 180
 *      @default 90
 *
 *  @param Oy
 *      @text 原点Y
 *      @desc
 *      @type number
 *          @min -9999
 *          @max 9999
 *      @default 4
 *
 *  @param Turn Duration
 *      @text 回転時間
 *      @desc
 *      @type number
 *          @min 0
 *          @max 999
 *      @default 24
 *
 */

(() => {
    'use strict';

    const pluginName = 'MPP_MapLight';

    // Plugin Parameters
    const parameters = PluginManager.parameters(pluginName);
    const paramReplace = (key, value) => {
        try {
            return JSON.parse(value);
        } catch (e) {
            return value;
        }
    };
    const param_LightColors = JSON.parse(parameters['Light Colors']);
    const param_FrontLight = JSON.parse(parameters['Front Light'], paramReplace);
    const param_DarknessSize = Number(parameters['Darkness Size'] || 3);

    // Dealing with other plugins
    const _importedPlugin = (...names) => {
        return names.some(name => PluginManager._scripts.includes(name));
    };

    //-----------------------------------------------------------------------------
    // Bitmap

    if (!Bitmap.prototype.destroy) {

        Bitmap.prototype.destroy = function() {
            if (this._baseTexture) {
                this._baseTexture.destroy();
                this.__baseTexture = null;
            }
            this._destroyCanvas();
        };

        Bitmap.prototype._destroyCanvas = function() {
            if (this._canvas) {
                this._canvas.width = 0;
                this._canvas.height = 0;
                this.__canvas = null;
            }
        };

    }

    Bitmap.prototype.mppBlur = function(level) {
        const { canvas, context, width:w, height:h } = this;
        const tempCanvas = document.createElement('canvas');
        const tempContext = tempCanvas.getContext('2d');
        tempCanvas.width = w + 2;
        tempCanvas.height = h + 2;
        for (let i = 0; i < level; i++) {
            tempContext.clearRect(0, 0, w + 2, h + 2);
            tempContext.drawImage(canvas, 0, 0, w, h, 1, 1, w, h);
            tempContext.drawImage(canvas, 0, 0, w, 1, 1, 0, w, 1);
            tempContext.drawImage(canvas, 0, 0, 1, h, 0, 1, 1, h);
            tempContext.drawImage(canvas, 0, h - 1, w, 1, 1, h + 1, w, 1);
            tempContext.drawImage(canvas, w - 1, 0, 1, h, w + 1, 1, 1, h);
            tempContext.drawImage(canvas, 0, 0, 1, 1, 0, 0, 1, 1);
            tempContext.drawImage(canvas, w - 1, 0, 1, 1, w + 1, 0, 1, 1);
            tempContext.drawImage(canvas, 0, h - 1, 1, 1, 0, h + 1, 1, 1);
            tempContext.drawImage(canvas, w - 1, h - 1, 1, 1, w + 1, h + 1, 1, 1);
            context.save();
            context.clearRect(0, 0, w, h);
            context.globalCompositeOperation = 'lighter';
            context.globalAlpha = 1 / 9;
            for (let y = 0; y < 3; y++) {
                for (let x = 0; x < 3; x++) {
                    context.drawImage(tempCanvas, x, y, w, h, 0, 0, w, h);
                }
            }
            context.restore();
        }
        this._baseTexture.update();
    };

    //-------------------------------------------------------------------------
    // Tilemap

    const _Tilemap_destroy = Tilemap.prototype.destroy;
    Tilemap.prototype.destroy = function() {
        this._darknessLayer.destroy();
        _Tilemap_destroy.apply(this, arguments);
    };

    const _Tilemap__createLayers = Tilemap.prototype._createLayers;
    Tilemap.prototype._createLayers = function() {
        _Tilemap__createLayers.apply(this, arguments);
        this._createDarknessLayer();
    };

    Tilemap.prototype._createDarknessLayer = function() {
        if (this._darknessLayer) {
            if (this._darknessLayer.bitmap) {
                this._darknessLayer.bitmap.destroy();
            }
            this.createDarknessBitmap();
        } else {
            this._darknessLayer = new DarknessLayer();
            this._darknessLayer.z = 9;
            this.addChild(this._darknessLayer);
        }
    };

    const _Tilemap_updateTransform = Tilemap.prototype.updateTransform;
    Tilemap.prototype.updateTransform = function() {
        const ox = Math.ceil(this.origin.x);
        const oy = Math.ceil(this.origin.y);
        const startX = Math.floor((ox - this._margin) / this._tileWidth);
        const startY = Math.floor((oy - this._margin) / this._tileHeight);
        const mx = startX * this._tileWidth - ox;
        const my = startY * this._tileHeight - oy;
        this._moveDarkness(mx, my);
        _Tilemap_updateTransform.apply(this, arguments);
        if (this._darknessLayer.bitmap && this._darknessLayer.opacity > 0) {
            this._addDarknessLayer(startX, startY);
        }
    };

    Tilemap.prototype._moveDarkness = function(x, y) {
        this._darknessLayer.x = x;
        this._darknessLayer.y = y;
        this._darknessLayer.opacity = $gameMap.darknessOpacity();
    };

    Tilemap.prototype._addDarknessLayer = function(startX, startY) {
        const layer = this._darknessLayer;
        layer.clear();
        this._addDarkness();
        const sx = startX - this.origin.x / this._tileWidth;
        const sy = startY - this.origin.y / this._tileHeight;
        for (const light of $gameMap.allMapLights()) {
            layer._addMapLidht(light, sx, sy);
        }
    };

    Tilemap.prototype.createDarknessBitmap = function() {
        const size = param_DarknessSize;
        const widthWithMatgin = this.width + this._margin * 2;
        const heightWithMatgin = this.height + this._margin * 2;
        const tileCols = Math.ceil(widthWithMatgin / this._tileWidth) + 1;
        const tileRows = Math.ceil(heightWithMatgin / this._tileHeight) + 1;
        const bitmap = new Bitmap(tileCols * size, tileRows * size);
        bitmap.smooth = true;
        this._darknessLayer.bitmap = bitmap;
        this._darknessLayer.scale.x = this._tileWidth / size;
        this._darknessLayer.scale.y = this._tileHeight / size;
    };

    Tilemap.prototype._addDarkness = function() {
        this._darknessLayer.fillAll('black');
    };

    //-------------------------------------------------------------------------
    // ShaderTilemap

    if (Utils.RPGMAKER_NAME === 'MV') {

        const _ShaderTilemap_updateTransform = ShaderTilemap.prototype.updateTransform;
        ShaderTilemap.prototype.updateTransform = function() {
            const ox = this.roundPixels ? Math.floor(this.origin.x) : this.origin.x;
            const oy = this.roundPixels ? Math.floor(this.origin.y) : this.origin.y;
            const startX = Math.floor((ox - this._margin) / this._tileWidth);
            const startY = Math.floor((oy - this._margin) / this._tileHeight);
            this._moveDarkness(startX * this._tileWidth - ox, startY * this._tileHeight - oy);
            _ShaderTilemap_updateTransform.apply(this, arguments);
            if (this._darknessLayer.opacity > 0) {
                this._addDarknessLayer(startX, startY);
            }
        };

        const _ShaderTilemap__createLayers = ShaderTilemap.prototype._createLayers;
        ShaderTilemap.prototype._createLayers = function() {
            _ShaderTilemap__createLayers.apply(this, arguments);
            this._createDarknessLayer();
        };

    }

    //-----------------------------------------------------------------------------
    // DarknessLayer

    function DarknessLayer() {
        this.initialize(...arguments);
    }

    if (_importedPlugin('MPP_MapLight_Op2')) {
        window.DarknessLayer = DarknessLayer;
    }

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

    DarknessLayer.prototype.initialize = function() {
        Sprite.prototype.initialize.call(this);
        this._frontBitmaps = {};
        this.blendMode = 2;
    };

    DarknessLayer.prototype.destroy = function() {
        for (const bitmap of Object.values(this._frontBitmaps)) {
            bitmap.destroy();
        }
        if (this.bitmap) {
            this.bitmap.destroy();
        }
        Sprite.prototype.destroy.call(this);
    };

    DarknessLayer.prototype.clear = function() {
        this.bitmap.clear();
    };

    DarknessLayer.prototype.fillAll = function(color) {
        this.bitmap.fillAll(color);
    };

    DarknessLayer.prototype._addMapLidht = function(mapLight, sx, sy) {
        if (mapLight.isValid()) {
            const dx = mapLight.scrolledX() - sx + 0.5;
            const dy = mapLight.scrolledY() - sy + 0.4;
            const alpha = mapLight.opacity / 255;
            const rgb = mapLight.rgb();
            if (mapLight.isFront()) {
                this._addFrontLidht(dx, dy, rgb, mapLight.angle, alpha);
            } else {
                this._addNormalMapLidht(dx, dy, rgb, mapLight.radius, alpha);
            }
        }
    };

    DarknessLayer.prototype._addFrontLidht = function(x, y, rgb, angle, alpha) {
        const frontBitmap = this._createFrontBitmap(rgb);
        const size = param_DarknessSize;
        const bitmap = this.bitmap;
        const context = bitmap.context;
        const { width:sw, height:sh } = frontBitmap;
        const dx = -sw / 2 * size / 4;
        const dy = -param_FrontLight.Oy * size / 4;
        const dw = sw * size / 4;
        const dh = sh * size / 4;

        // MVで size = 4, angle = 0 の場合、他の値の小数点以下が無視されるため、その対処
        if (size === 4 && Utils.RPGMAKER_NAME === 'MV') angle = angle || 0.1;

        context.save();
        context.translate(x * size, y * size);
        context.rotate(angle * Math.PI / 180);
        context.globalAlpha = alpha;
        bitmap.blt(frontBitmap, 0, 0, sw, sh, dx, dy, dw, dh);
        context.restore();
    };

    DarknessLayer.prototype._createFrontBitmap = function(rgb) {
        const dict = this._frontBitmaps;
        if (!dict[rgb]) {
            const { Radius: radius = 6, Angle: angle = 90 } = param_FrontLight;
            const r = radius * 4;
            const bitmap = new Bitmap(r * 2 + 4, r + 4);
            const context = bitmap.context;
            context.save();

            const startAngle = (90 - angle / 2) / 180 * Math.PI;
            const endAngle = (90 + angle / 2) / 180 * Math.PI;
            context.beginPath();
            context.moveTo(r + 2, 2);
            context.arc(r + 2, 2, r, startAngle, endAngle);
            context.closePath();

            const grad = context.createRadialGradient(r + 2, 2, 0, r + 2, 2, r);
            grad.addColorStop(0, `rgba(${rgb},1)`);
            grad.addColorStop(1, `rgba(${rgb},0)`);
            context.fillStyle = grad;
            context.fill();
            context.restore();
            bitmap.mppBlur(2);
            dict[rgb] = bitmap;
        }
        return dict[rgb];
    };

    DarknessLayer.prototype._addNormalMapLidht = function(x, y, rgb, r, alpha) {
        const size = param_DarknessSize;
        const dx = x * size;
        const dy = y * size;
        const dr = r * size;
        const bitmap = this.bitmap;
        const context = bitmap.context;
        const grad = context.createRadialGradient(dx, dy, 0, dx, dy, dr);
        grad.addColorStop(0, `rgba(${rgb},1)`);
        grad.addColorStop(1, `rgba(${rgb},0)`);
        context.globalAlpha = alpha;
        bitmap.drawCircle(dx, dy, dr, grad);
        context.globalAlpha = 1;
    };

    //-----------------------------------------------------------------------------
    // Game_MapLight

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

    window.Game_MapLight = Game_MapLight;

    Object.defineProperties(Game_MapLight.prototype, {
        colorIndex: {
            get() { return this._colorIndex; },
            configurable: true
        },
        radius: {
            get() { return this._radius; },
            configurable: true
        },
        opacity: {
            get() { return this._opacity; },
            configurable: true
        },
        angle: {
            get() { return this._angle; },
            configurable: true
        }
    });

    Game_MapLight.prototype.initialize = function() {
        this._eventId = 0;
        this._x = 0;
        this._y = 0;
        this._colorIndex = 0;
        this._radius = 0;
        this._targetRadius = 0;
        this._isFront = false;
        this._opacity = 0;
        this._targetOpacity = 0;
        this._amplitude = 0;
        this._moveDuration = 0;
        this._angle = 0;
        this._subjectDirection = 0;
        this._angleDuration = 0;
    };

    Game_MapLight.prototype.subject = function() {
        if (this._eventId < 0) {
            return $gamePlayer;
        } else if (this._eventId > 0) {
            return $gameMap.event(this._eventId);
        }
        return null;
    };

    Game_MapLight.prototype.rgb = function() {
        return this._colorIndex > 0
            ? param_LightColors[this._colorIndex - 1]
            : null;
    };

    Game_MapLight.prototype.isFront = function() {
        return this._isFront;
    };

    Game_MapLight.prototype.isValid = function() {
        return (
            (this._radius > 0 || this._isFront) &&
            this._opacity > 0 &&
            this.rgb()
        );
    };

    Game_MapLight.prototype.setCharLight = function(
        eventId, radius, colorIndex, amplitude
    ) {
        this._isFront = false;
        this._eventId = eventId;
        this._targetRadius = radius;
        this._colorIndex = colorIndex;
        this._targetOpacity = 255;
        this._amplitude = amplitude;
        this._moveDuration = 16;
        this._subjectDirection = 0;
        this._angleDuration = 0;
    };

    Game_MapLight.prototype.setPosLight = function(
        x, y, radius, colorIndex, amplitude
    ) {
        this._isFront = false;
        this._x = x;
        this._y = y;
        this._targetRadius = radius;
        this._colorIndex = colorIndex;
        this._targetOpacity = 255;
        this._amplitude = amplitude;
        this._moveDuration = 16;
        this._eventId = 0;
        this._subjectDirection = 0;
        this._angleDuration = 0;
    };

    Game_MapLight.prototype.setFrontLight = function(
        eventId, colorIndex, amplitude
    ) {
        this._isFront = true;
        this._eventId = eventId;
        this._colorIndex = colorIndex;
        this._targetOpacity = 255;
        this._amplitude = amplitude;
        this._moveDuration = 16;
        const subject = this.subject();
        this._angle = this.directionAngle(subject);
        this._subjectDirection = subject ? subject.direction() : 0;
        this._angleDuration = 0;
        this._radius = 0;
    };

    Game_MapLight.prototype.skip = function() {
        this._radius = this._targetRadius;
        this._opacity = this._targetOpacity;
        this.setupAmplitude();
    };

    Game_MapLight.prototype.setupAmplitude = function() {
        if (this._targetOpacity > 0 && this._amplitude > 0) {
            this._targetOpacity = 255 - Math.randomInt(255 * this._amplitude / 100);
            this._moveDuration = 8;
        } else {
            this._moveDuration = 0;
        }
    };

    Game_MapLight.prototype.update = function() {
        this.updateMove();
        this.updateAngle();
    };

    Game_MapLight.prototype.updateMove = function() {
        if (this._moveDuration > 0) {
            const d = this._moveDuration;
            this._radius = (this._radius * (d - 1) + this._targetRadius) / d;
            this._opacity = (this._opacity * (d - 1) + this._targetOpacity) / d;
            this._moveDuration--;
            if (this._moveDuration === 0) this.setupAmplitude();
        }
    };

    Game_MapLight.prototype.updateAngle = function() {
        if (this._isFront) {
            const subject = this.subject();
            if (subject) {
                if (this._subjectDirection !== subject.direction()) {
                    this._subjectDirection = subject.direction();
                    this.startAngle(subject);
                }
                if (this._angleDuration > 0) {
                    const d = this._angleDuration;
                    const target = this.targetAngle(subject);
                    const max = d * (d + 1) / 2;
                    this._angle += (target - this._angle) * d / max;
                    this._angle = (this._angle + 360) % 360;
                    this._angleDuration--;
                }
            }
        }
    };

    Game_MapLight.prototype.startAngle = function(subject) {
        this._angleDuration = param_FrontLight['Turn Duration'] || 0;
        if (this._angleDuration === 0) {
            this._angle = this.directionAngle(subject);
        }
    };

    Game_MapLight.prototype.targetAngle = function(subject) {
        let result = this.directionAngle(subject);
        const sa = this._angle - result;
        if (Math.abs(sa) > Math.abs(sa - 360)) result += 360;
        if (Math.abs(sa) > Math.abs(sa + 360)) result -= 360;
        return result;
    };

    Game_MapLight.prototype.directionAngle = function(subject) {
        if (subject) {
            switch (subject.direction()) {
                case 2: return 0;
                case 4: return 90;
                case 6: return 270;
                case 8: return 180;
            }
        }
        return 0;
    };

    Game_MapLight.prototype.scrolledX = function() {
        const subject = this.subject();
        return subject ? subject.scrolledX() : $gameMap.adjustX(this._x);
    };

    Game_MapLight.prototype.scrolledY = function() {
        const subject = this.subject();
        return subject ? subject.scrolledY() : $gameMap.adjustY(this._y);
    };

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

    const _Game_Map_setup = Game_Map.prototype.setup;
    Game_Map.prototype.setup = function(mapId) {
        this._mapLights = {};
        _Game_Map_setup.apply(this, arguments);
        this._darkness = 0;
        if (mapId > 0) {
            this.setupMapLightCommand();
        }
    };

    Game_Map.prototype.setupMapLightCommand = function() {
        for (const [name, param] of Object.entries($dataMap.meta)) {
            const match = /^PosLight\s+(\d+)\s*,\s*(\d+)\s*$/.exec(name);
            if (match) {
                const x = Number(match[1]);
                const y = Number(match[2]);
                const data = param.split(',').map(Number);
                this.setPosLight(x, y, ...data);
            } else if (name === 'Darkness') {
                this._darkness = PluginManager.mppValue(param).clamp(0, 100);
            }
        }
        for (const light of Object.values(this._mapLights)) {
            light.skip();
        }
    };

    Game_Map.prototype.darknessOpacity = function() {
        return 255 * this._darkness / 100;
    };

    Game_Map.prototype.setDarkness = function(opacity) {
        this._darkness = opacity.clamp(0, 100);
    };

    Game_Map.prototype.allMapLights = function() {
        return [
            ...Object.values(this._mapLights),
            ...$gamePlayer.allMapLights()
        ]
    };

    Game_Map.prototype.getMapLight = function(key) {
        const dict = this._mapLights;
        if (!dict[key]) dict[key] = new Game_MapLight();
        return dict[key];
    };

    Game_Map.prototype.setCharLight = function(eventId, r = 0, c = 0, a = 0) {
        this.getMapLight(`char${eventId}`).setCharLight(eventId, r, c, a);
    };

    Game_Map.prototype.setPosLight = function(x, y, r = 0, c = 0, a = 0) {
        this.getMapLight(`pos${x},${y}`).setPosLight(x, y, r, c, a);
    };

    Game_Map.prototype.setFrontLight = function(eventId, c = 0, a = 0) {
        this.getMapLight(`front${eventId}`).setFrontLight(eventId, c, a);
    };

    Game_Map.prototype.eraseCharLight = function(eventId) {
        this.eraseLight(`char${eventId}`);
    };

    Game_Map.prototype.erasePosLight = function(x, y) {
        this.eraseLight(`pos${x},${y}`);
    };

    Game_Map.prototype.eraseFrontLight = function(eventId) {
        this.eraseLight(`front${eventId}`);
    };

    Game_Map.prototype.eraseLight = function(key) {
        delete this._mapLights[key];
    };

    const _Game_Map_update = Game_Map.prototype.update;
    Game_Map.prototype.update = function(sceneActive) {
        _Game_Map_update.apply(this, arguments);
        for (const light of this.allMapLights()) {
            light.update();
        }
    };

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

    const _Game_Event_clearPageSettings = Game_Event.prototype.clearPageSettings;
    Game_Event.prototype.clearPageSettings = function() {
        _Game_Event_clearPageSettings.apply(this, arguments);
        this.clearCharLight();
        this.clearFrontLight();
    };

    Game_Event.prototype.clearCharLight = function() {
        $gameMap.eraseCharLight(this.eventId());
    };

    Game_Event.prototype.clearFrontLight = function() {
        $gameMap.eraseFrontLight(this.eventId());
    };

    Game_Event.prototype.startCharLight = function(r = 0, c = 0, a = 0) {
        $gameMap.setCharLight(this.eventId(), r, c, a);
    };

    Game_Event.prototype.startFrontLight = function(c = 0, a = 0) {
        $gameMap.eraseCharLight(this.eventId(), c, a);
    };

    const _Game_Event_setupPageSettings = Game_Event.prototype.setupPageSettings;
    Game_Event.prototype.setupPageSettings = function() {
        _Game_Event_setupPageSettings.apply(this, arguments);
        if (!this.setupCharLight()) {
            this.clearCharLight();
        }
        if (!this.setupFrontLight()) {
            this.clearFrontLight();
        }
    };

    Game_Event.prototype.setupCharLight = function() {
        const commandNames = ['CharLight', '灯り'];
        for (const comment of this.generatorCommentCommand(commandNames)) {
            const [_, ...args] = comment.split(' ');
            this.startCharLight(...args.map(Number));
            return true;
        }
        return false;
    };

    Game_Event.prototype.setupFrontLight = function() {
        const commandNames = ['FrontLight', '前方灯り'];
        for (const comment of this.generatorCommentCommand(commandNames)) {
            const [_, ...args] = comment.split(' ');
            this.startFrontLight(...args.map(Number));
            return true;
        }
        return false;
    };

    Game_Event.prototype.generatorCommentCommand = function*(commandNames) {
        for (const evCom of this.list()) {
            switch (evCom.code) {
                case 108:
                case 408:
                    const comment = evCom.parameters[0];
                    if (commandNames.some(name => comment.startsWith(name))) {
                        yield comment;
                    }
                    break;
                default:
                    return;
            }
        }
    };

    //-------------------------------------------------------------------------
    // Game_Player

    const _Game_Player_initMembers = Game_Player.prototype.initMembers;
    Game_Player.prototype.initMembers = function() {
        _Game_Player_initMembers.apply(this, arguments);
        this._charLight = null;
        this._frontLight = null;
    };

    Game_Player.prototype.allMapLights = function() {
        const result = [];
        if (this._charLight) result.push(this._charLight);
        if (this._frontLight) result.push(this._frontLight);
        return result;
    };

    Game_Player.prototype.clearCharLight = function() {
        this._charLight = null;
    };

    Game_Player.prototype.clearFrontLight = function() {
        this._frontLight = null;
    };

    Game_Player.prototype.startCharLight = function(r = 0, c = 0, a = 0) {
        if (!this._charLight) {
            this._charLight = new Game_MapLight();
        }
        this._charLight.setCharLight(-1, r, c, a);
    };

    Game_Player.prototype.startFrontLight = function(c = 0, a = 0) {
        if (!this._frontLight) {
            this._frontLight = new Game_MapLight();
        }
        this._frontLight.setFrontLight(-1, c, a);
    };

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

    const _mzCommands = {
        SetCharLight: {
            name:'setCharLight',
            keys:['character', 'radius', 'colorIndex', 'amplitude']
        },
        SetPosLight: {
            name:'setPosLight',
            keys:['x', 'y', 'radius', 'colorIndex', 'amplitude']
        },
        SetFrontLight: {
            name:'setFrontLight',
            keys:['character', 'colorIndex', 'amplitude']
        },
        EraseCharLight: { name:'eraseCharLight', keys:['character'] },
        ErasePosLight: { name:'erasePosLight', keys:['x', 'y'] },
        EraseFrontLight: { name:'eraseFrontLight', keys:['character'] },
        SetMapDarkness: { name:'setDarkness', keys:['darkness'] }
    };
    Object.assign(_mzCommands, {
        'キャラ灯り設定': _mzCommands.SetCharLight,
        'マップ灯り設定': _mzCommands.SetPosLight,
        '前方灯り設定': _mzCommands.SetFrontLight,
        'キャラ灯り消去': _mzCommands.EraseCharLight,
        'マップ灯り消去': _mzCommands.ErasePosLight,
        '前方灯り消去': _mzCommands.EraseFrontLight,
        'マップ暗さ設定': _mzCommands.SetMapDarkness
    });

    const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.apply(this, arguments);
        const mzCommand = _mzCommands[command];
        if (mzCommand) {
            const args2 = Object.assign(...mzCommand.keys.map((k,i) => ({[k]:args[i]})));
            PluginManager.callCommand(this, pluginName, mzCommand.name, args2);
        }
    };

    //-------------------------------------------------------------------------
    // PluginManager

    PluginManager._commands = PluginManager._commands || {};

    if (!PluginManager.registerCommand) {
        PluginManager.registerCommand = function(pluginName, commandName, func) {
            const key = pluginName + ":" + commandName;
            this._commands[key] = func;
        };
    }

    if (!PluginManager.callCommand) {
        PluginManager.callCommand = function(self, pluginName, commandName, args) {
            const key = pluginName + ":" + commandName;
            const func = this._commands[key];
            if (typeof func === "function") {
                func.bind(self)(args);
            }
        };
    }

    PluginManager.registerCommand(pluginName, 'setCharLight', function(args) {
        const character = this.character(PluginManager.mppValue(args.character));
        const r = PluginManager.mppValue(args.radius);
        const c = PluginManager.mppValue(args.colorIndex);
        const a = PluginManager.mppValue(args.amplitude || '0');
        if (character) {
            character.startCharLight(r, c, a);
        }
    });

    PluginManager.registerCommand(pluginName, 'setPosLight', args => {
        const x = PluginManager.mppValue(args.x);
        const y = PluginManager.mppValue(args.y);
        const r = PluginManager.mppValue(args.radius);
        const c = PluginManager.mppValue(args.colorIndex);
        const a = PluginManager.mppValue(args.amplitude || '0');
        $gameMap.setPosLight(x, y, r, c, a);
    });

    PluginManager.registerCommand(pluginName, 'setFrontLight', function(args) {
        const character = this.character(PluginManager.mppValue(args.character));
        const c = PluginManager.mppValue(args.colorIndex);
        const a = PluginManager.mppValue(args.amplitude || '0');
        if (character) {
            character.startFrontLight(c, a);
        }
    });

    PluginManager.registerCommand(pluginName, 'eraseCharLight', function(args) {
        const character = this.character(PluginManager.mppValue(args.character));
        if (character) {
            character.clearCharLight();
        }
    });

    PluginManager.registerCommand(pluginName, 'erasePosLight', args => {
        const x = PluginManager.mppValue(args.x);
        const y = PluginManager.mppValue(args.y);
        $gameMap.erasePosLight(x, y);
    });

    PluginManager.registerCommand(pluginName, 'eraseFrontLight', function(args) {
        const character = this.character(PluginManager.mppValue(args.character));
        if (character) {
            character.clearFrontLight();
        }
    });

    PluginManager.registerCommand(pluginName, 'setDarkness', args => {
        const darkness = PluginManager.mppValue(args.darkness);
        $gameMap.setDarkness(darkness);
    });

    PluginManager.mppValue = function(value) {
        const match = /^V\[(\d+)\]$/i.exec(value);
        return match ? $gameVariables.value(+match[1]) : +value;
    };

    //-------------------------------------------------------------------------
    // Spriteset_Map

    const _Spriteset_Map_createTilemap = Spriteset_Map.prototype.createTilemap;
    Spriteset_Map.prototype.createTilemap = function() {
        _Spriteset_Map_createTilemap.apply(this, arguments);
        this._tilemap.createDarknessBitmap();
    };

})();


code:
//=============================================================================
// MPP_ScrollBar.js
//=============================================================================
// Copyright (c) 2019 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc 【ver.2.2】ウィンドウにスクロールバーを追加します。
 * @author 木星ペンギン
 *
 * @help ※マウス/タッチ操作改善 [MPP_SimpleTouch3.js] と併用する場合、
 * 　こちらのプラグインが下になるように導入してください。
 *
 * ● ドラッグ操作によるスクロール
 *  スクロールバーをドラッグ操作でスクロールさせることができます。
 *  操作の当たり判定は、ウィンドウの右端からの幅となります。
 *  スクロールバーの幅と当たり判定の幅は関係ありません。
 *
 * ================================
 * 制作 : 木星ペンギン
 * URL : http://woodpenguin.blog.fc2.com/
 *
 * @param Veiw Time
 * @type number
 * @desc 表示時間
 * (0で常に表示)
 * @default 60
 *
 * @param Scroll Bar Color1
 * @desc スクロールバーの色
 * @default 160,160,160
 *
 * @param Scroll Bar Color2
 * @desc スクロールバーの色
 * @default 192,192,192
 *
 * @param Scroll Bar Width
 * @type number
 * @min 1
 * @desc スクロールバーの幅
 * @default 6
 *
 * @param Right Padding
 * @type number
 * @desc スクロールバー右の余白
 * @default 5
 *
 * @param Hitbox Width
 * @type number
 * @min 1
 * @desc スクロールバー操作の当たり判定の幅
 * @default 24
 *
 *
 *
 */

(function () {

var MPPlugin = {};

(function () {

    MPPlugin.contains = {};
    MPPlugin.contains['SimpleTouch3'] = $plugins.some(function(plugin) {
        return (plugin.name === 'MPP_SimpleTouch3' && plugin.status);
    });

    var parameters = PluginManager.parameters('MPP_ScrollBar');

    MPPlugin.VeiwTime = Number(parameters['Veiw Time'] || 0);
    MPPlugin.ScrollBarColor1 = 'rgb(%1)'.format(parameters['Scroll Bar Color1'] || '128,128,128');
    MPPlugin.ScrollBarColor2 = 'rgb(%1)'.format(parameters['Scroll Bar Color2'] || '192,192,192');
    MPPlugin.ScrollBarWidth = Number(parameters['Scroll Bar Width'] || 6);
    MPPlugin.RightPadding = Number(parameters['Right Padding'] || 5);

    MPPlugin.HitboxWidth = Number(parameters['Hitbox Width'] || 18);

})();

var Alias = {};

//-----------------------------------------------------------------------------
// Window_Selectable

//
if (Window_Selectable.prototype.hasOwnProperty('updateTransform')) {
    Alias.WiSe_updateTransform = Window_Selectable.prototype.updateTransform;
}
Window_Selectable.prototype.updateTransform = function () {
    this._updateScrollBar();
    if (Alias.WiSe_updateTransform) {
        Alias.WiSe_updateTransform.call(this);
    } else {
        Window_Base.prototype.updateTransform.call(this);
    }
};

//
if (Window_Selectable.prototype.hasOwnProperty('_refreshAllParts')) {
    Alias.WiSe__refreshAllParts = Window_Selectable.prototype._refreshAllParts;
}
Window_Selectable.prototype._refreshAllParts = function () {
    this._refreshScrollBar();
    if (Alias.WiSe__refreshAllParts) {
        Alias.WiSe__refreshAllParts.call(this);
    } else {
        Window_Base.prototype._refreshAllParts.call(this);
    }
};

Window_Selectable.prototype._refreshScrollBar = function () {
    var maxRow = this.maxRows();
    var maxPageRows = this.maxPageRows();
    if (maxRow > maxPageRows) {
        if (!this._scrollBarSprite) {
            this._scrollBarSprite = new Sprite();
            this._scrollBarSprite.opacity = 0;
            this.addChild(this._scrollBarSprite);
        }
        var height = this.height - this.standardPadding() * 2;
        var barWidth = MPPlugin.ScrollBarWidth;
        var barHeight = Math.ceil(height * maxPageRows / maxRow);
        var bitmap = new Bitmap(barWidth, barHeight);
        var context = bitmap.context;
        var grad = context.createLinearGradient(0, 0, 0, barHeight);
        grad.addColorStop(0, MPPlugin.ScrollBarColor1);
        grad.addColorStop(0.5, MPPlugin.ScrollBarColor2);
        grad.addColorStop(1, MPPlugin.ScrollBarColor1);
        context.save();
        context.fillStyle = grad;
        context.fillRect(0, 0, barWidth, barHeight);
        context.restore();
        bitmap._setDirty();
        this._scrollBarSprite.bitmap = bitmap;
    }
};

Window_Selectable.prototype._updateScrollBar = function () {
    if (this._scrollBarSprite) {
        var barX = this.width - MPPlugin.RightPadding - MPPlugin.ScrollBarWidth;
        var topY = this._scrollY + this.origin.y;
        var maxHeight = this.maxRows() * this.itemHeight();
        var height = this.height - this.standardPadding() * 2;
        var barY = Math.floor(height * topY / maxHeight) + this.standardPadding();
        this._scrollBarSprite.x = barX;
        this._scrollBarSprite.y = barY;
        if (this._lastOy !== this.origin.y) {
            this._lastOy = this.origin.y;
            this._scrollBarCount = MPPlugin.VeiwTime;
        }
        if (this._scrollBarCount > 0) {
            this._scrollBarCount--;
        }
        if (this.isScrollBarActive()) {
            this._scrollBarSprite.opacity += 32;
        } else {
            this._scrollBarSprite.opacity -= 4;
        }
        if (this.isOpen() && this.maxRows() > this.maxPageRows()) {
            this._scrollBarSprite.visible = true;
        } else {
            this._scrollBarSprite.visible = false;
        }
    }
};

Window_Selectable.prototype.isScrollBarActive = function() {
    return (this.active && (MPPlugin.VeiwTime === 0 || this._scrollBarCount > 0));
};

//13
Alias.WiSe_initialize = Window_Selectable.prototype.initialize;
Window_Selectable.prototype.initialize = function(x, y, width, height) {
    Alias.WiSe_initialize.call(this, x, y, width, height);
    this._scrollBarType = -1;
    this._scrollBarDragY = 0;
    this._scrollBarCount = 0;
};

//
if (Window_Selectable.prototype.hasOwnProperty('createContents')) {
    Alias.WiSe_createContents = Window_Selectable.prototype.createContents;
}
Window_Selectable.prototype.createContents = function() {
    if (Alias.WiSe_createContents) {
        Alias.WiSe_createContents.call(this);
    } else {
        Window_Base.prototype.createContents.call(this);
    }
    this._refreshScrollBar();
};

//110
Alias.WiSe_setTopRow = Window_Selectable.prototype.setTopRow;
Window_Selectable.prototype.setTopRow = function(row) {
    Alias.WiSe_setTopRow.call(this, row);
    this._scrollBarCount = MPPlugin.VeiwTime;
};

//340
Alias.WiSe_processTouch = Window_Selectable.prototype.processTouch;
Window_Selectable.prototype.processTouch = function() {
    if (this.isOpenAndActive()) {
        if (TouchInput.isTriggered() && this.isTouchedInsideScrollBox()) {
            var y = this.canvasToLocalY(TouchInput.y);
            var by = this._scrollBarSprite.y;
            var bh = this._scrollBarSprite.height;
            if (y < by) {
                this._scrollBarType = 0;
            } else if (y < by + bh) {
                this._scrollBarType = 1;
                this._scrollBarDragY = TouchInput.y;
            } else {
                this._scrollBarType = 2;
            }
            this._scrollBarCount = MPPlugin.VeiwTime;
        }
        if (this._scrollBarType >= 0) {
            if (TouchInput.isPressed()) {
                switch (this._scrollBarType) {
                    case 0:
                        if (TouchInput.isRepeated()) {
                            this.scrollBarPageup();
                        }
                        break;
                    case 1:
                        this.onScrollBarDrag();
                        break;
                    case 2:
                        if (TouchInput.isRepeated()) {
                            this.scrollBarPagedown();
                        }
                        break;
                }
            } else {
                this._scrollBarType = -1;
            }
        }
    } else {
        this._scrollBarType = -1;
    }
    if (this._scrollBarType < 0) {
        Alias.WiSe_processTouch.call(this);
    }
};

Window_Selectable.prototype.isTouchedInsideScrollBox = function() {
    if (!this._scrollBarSprite || !this._scrollBarSprite.visible) {
        return false;
    }
    var x = this.canvasToLocalX(TouchInput.x);
    var y = this.canvasToLocalY(TouchInput.y);
    var rx = this.width - MPPlugin.HitboxWidth;
    return x >= rx && y >= 0 && x < this.width && y < this.height;
};

Window_Selectable.prototype.scrollBarPagedown = function() {
    var y = this.canvasToLocalY(TouchInput.y);
    var by = this._scrollBarSprite.y;
    var bh = this._scrollBarSprite.height;
    if (y >= by + bh) {
        if (MPPlugin.contains['SimpleTouch3']) {
            this.gainOy(this.maxPageRows() * this.itemHeight());
        } else {
            this.setTopRow(this.topRow() + this.maxPageRows());
        }
    }
};

Window_Selectable.prototype.scrollBarPageup = function() {
    var y = this.canvasToLocalY(TouchInput.y);
    var by = this._scrollBarSprite.y;
    if (y < by) {
        if (MPPlugin.contains['SimpleTouch3']) {
            this.gainOy(-this.maxPageRows() * this.itemHeight());
        } else {
            this.setTopRow(this.topRow() - this.maxPageRows());
        }
    }
};

Window_Selectable.prototype.onScrollBarDrag = function() {
    var sy = TouchInput.y - this._scrollBarDragY;
    if (sy !== 0) {
        var oy = this._scrollY + this.origin.y;
        var height = this.height - this.standardPadding() * 2;
        var amount = sy * this.maxRows() / height;
        if (MPPlugin.contains['SimpleTouch3']) {
            this.gainOy(amount * this.itemHeight());
        } else {
            this.setTopRow(this.topRow() + Math.round(amount));
        }
        if (oy !== this._scrollY + this.origin.y) {
            this._scrollBarDragY = TouchInput.y;
        }
    }
};

})();


code:
/*:
 * NOTE: Images are stored in the img/system folder.
 *
 * @plugindesc Show a Splash Screen "Made with MV" and/or a Custom Splash Screen before going to main screen.
 * @author Dan "Liquidize" Deptula
 *
 * @help This plugin does not provide plugin commands.
 *
 * @param Show Made With MV
 * @desc Enabled/Disables showing the "Made with MV" splash screen.
 * OFF - false     ON - true
 * Default: ON
 * @default true
 *
 * @param Made with MV Image
 * @desc The image to use when showing "Made with MV"
 * Default: MadeWithMv
 * @default MadeWithMv
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param Show Custom Splash
 * @desc Enabled/Disables showing the "Made with MV" splash screen.
 * OFF - false     ON - true
 * Default: OFF
 * @default false
 *
 * @param Custom Image
 * @desc The image to use when showing "Made with MV"
 * Default:
 * @default
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param Fade Out Time
 * @desc The time it takes to fade out, in frames.
 * Default: 120
 * @default 120
 *
 * @param Fade In Time
 * @desc The time it takes to fade in, in frames.
 * Default: 120
 * @default 120
 *
 * @param Wait Time
 * @desc The time between fading in and out, in frames.
 * Default: 160
 * @default 160
 *
 */
/*:ja
 * メモ: イメージはimg／systemフォルダ内に保存されます。
 *
 * @plugindesc メイン画面へ進む前に、"Made with MV"のスプラッシュ画面もしくはカスタマイズされたスプラッシュ画面を表示します。
 * @author Dan "Liquidize" Deptula
 *
 * @help  このプラグインにはプラグインコマンドはありません。
 *
 * @param Show Made With MV
 * @desc "Made with MV"のスプラッシュ画面を表示できる/できないようにします。
 * OFF - false     ON - true
 * デフォルト: ON
 * @default true
 *
 * @param Made with MV Image
 * @desc "Made with MV"を表示する際に使用する画像
 * デフォルト: MadeWithMv
 * @default MadeWithMv
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param Show Custom Splash
 * @desc "Made with MV"のスプラッシュ画面を表示できる/できないようにします。
 * OFF - false     ON - true
 * デフォルト: OFF
 * @default false
 *
 * @param Custom Image
 * @desc "Made with MV"を表示する際に使用する画像
 * デフォルト:
 * @default
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param Fade Out Time
 * @desc フェードアウトに要する時間（フレーム数）
 * デフォルト: 120
 * @default 120
 *
 * @param Fade In Time
 * @desc フェードインに要する時間（フレーム数）
 * デフォルト: 120
 * @default 120
 *
 * @param Wait Time
 * @desc フェードインからフェードアウトまでに要する時間（フレーム数）
 * デフォルト: 160
 * @default 160
 *
 */
var Liquidize = Liquidize || {};
Liquidize.MadeWithMV = {};
Liquidize.MadeWithMV.Parameters = PluginManager.parameters('MadeWithMv');

Liquidize.MadeWithMV.ShowMV = JSON.parse(Liquidize.MadeWithMV.Parameters["Show Made With MV"]);
Liquidize.MadeWithMV.MVImage = String(Liquidize.MadeWithMV.Parameters["Made with MV Image"]);
Liquidize.MadeWithMV.ShowCustom = JSON.parse(Liquidize.MadeWithMV.Parameters["Show Custom Splash"]);
Liquidize.MadeWithMV.CustomImage = String(Liquidize.MadeWithMV.Parameters["Custom Image"]);
Liquidize.MadeWithMV.FadeOutTime = Number(Liquidize.MadeWithMV.Parameters["Fade Out Time"]) || 120;
Liquidize.MadeWithMV.FadeInTime = Number(Liquidize.MadeWithMV.Parameters["Fade In Time"]) || 120;
Liquidize.MadeWithMV.WaitTime = Number(Liquidize.MadeWithMV.Parameters["Wait Time"]) || 160;

//-----------------------------------------------------------------------------
// Scene_Splash
//
// This is a constructor, implementation is done in the inner scope.

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

(function() {

    //-----------------------------------------------------------------------------
    // Scene_Boot
    //
    // The scene class for dealing with the game boot.

    var _Scene_Boot_loadSystemImages = Scene_Boot.prototype.loadSystemImages;
    Scene_Boot.prototype.loadSystemImages = function() {
        _Scene_Boot_loadSystemImages.call(this);
        if (Liquidize.MadeWithMV.ShowMV) {
            ImageManager.loadSystem(Liquidize.MadeWithMV.MVImage);
        }
        if (Liquidize.MadeWithMV.ShowCustom) {
            ImageManager.loadSystem(Liquidize.MadeWithMV.CustomImage);
        }
    };

    var _Scene_Boot_start = Scene_Boot.prototype.start;
    Scene_Boot.prototype.start = function() {
        if ((Liquidize.MadeWithMV.ShowMV || Liquidize.MadeWithMV.ShowCustom) && !DataManager.isBattleTest() && !DataManager.isEventTest()) {
            SceneManager.goto(Scene_Splash);
        } else {
            _Scene_Boot_start.call(this);
        }
    };

    //-----------------------------------------------------------------------------
    // Scene_Splash
    //
    // The scene class for dealing with the splash screens.

    Scene_Splash.prototype = Object.create(Scene_Base.prototype);
    Scene_Splash.prototype.constructor = Scene_Splash;

    Scene_Splash.prototype.initialize = function() {
        Scene_Base.prototype.initialize.call(this);
        this._mvSplash = null;
        this._customSplash = null;
        this._mvWaitTime = Liquidize.MadeWithMV.WaitTime;
        this._customWaitTime = Liquidize.MadeWithMV.WaitTime;
        this._mvFadeOut = false;
        this._mvFadeIn = false;
        this._customFadeOut = false;
        this._customFadeIn = false;
    };

    Scene_Splash.prototype.create = function() {
        Scene_Base.prototype.create.call(this);
        this.createSplashes();
    };

    Scene_Splash.prototype.start = function() {
        Scene_Base.prototype.start.call(this);
        SceneManager.clearStack();
        if (this._mvSplash != null) {
            this.centerSprite(this._mvSplash);
        }
        if (this._customSplash != null) {
            this.centerSprite(this._customSplash);
        }
    };

    Scene_Splash.prototype.update = function() {
        if (Liquidize.MadeWithMV.ShowMV) {
            if (!this._mvFadeIn) {
                this.startFadeIn(Liquidize.MadeWithMV.FadeInTime, false);
                this._mvFadeIn = true;
            } else {
                if (this._mvWaitTime > 0 && this._mvFadeOut == false) {
                    this._mvWaitTime--;
                } else {
                    if (this._mvFadeOut == false) {
                        this._mvFadeOut = true;
                        this.startFadeOut(Liquidize.MadeWithMV.FadeOutTime, false);
                    }
                }
            }
        }

        if (Liquidize.MadeWithMV.ShowCustom) {
            if (Liquidize.MadeWithMV.ShowMV && this._mvFadeOut == true) {
                if (!this._customFadeIn && this._fadeDuration == 0) {
                    this._customSplash.opacity = 255;
                    this._customWaitTime = Liquidize.MadeWithMV.WaitTime;
                    this.startFadeIn(Liquidize.MadeWithMV.FadeInTime, false);
                    this._customFadeIn = true;
                } else {
                    if (this._customWaitTime > 0 && this._customFadeOut == false) {
                        this._customWaitTime--;
                    } else {
                        if (this._customFadeOut == false) {
                            this._customFadeOut = true;
                            this.startFadeOut(Liquidize.MadeWithMV.FadeOutTime, false);
                        }
                    }
                }
            } else if (!Liquidize.MadeWithMV.ShowMV) {
                if (!this._customFadeIn) {
                    this._customSplash.opacity = 255;
                    this.startFadeIn(Liquidize.MadeWithMV.FadeInTime, false);
                    this._customFadeIn = true;
                } else {
                    if (this._customWaitTime > 0 && this._customFadeOut == false) {
                        this._customWaitTime--;
                    } else {
                        if (this._customFadeOut == false) {
                            this._customFadeOut = true;
                            this.startFadeOut(Liquidize.MadeWithMV.FadeOutTime, false);
                        }
                    }
                }
            }
        }

        if (Liquidize.MadeWithMV.ShowCustom) {
            if (Liquidize.MadeWithMV.ShowMV && this._mvFadeOut == true && this._customFadeOut == true) {
                this.gotoTitleOrTest();
            } else if (!Liquidize.MadeWithMV.ShowMV && this._customFadeOut == true) {
                this.gotoTitleOrTest();
            }
        } else {
            if (this._mvFadeOut == true) {
                this.gotoTitleOrTest();
            }
        }

        Scene_Base.prototype.update.call(this);
    };

    Scene_Splash.prototype.createSplashes = function() {
        if (Liquidize.MadeWithMV.ShowMV) {
            this._mvSplash = new Sprite(ImageManager.loadSystem(Liquidize.MadeWithMV.MVImage));
            this.addChild(this._mvSplash);
        }
        if (Liquidize.MadeWithMV.ShowCustom) {
            this._customSplash = new Sprite(ImageManager.loadSystem(Liquidize.MadeWithMV.CustomImage));
            this._customSplash.opacity = 0;
            this.addChild(this._customSplash);
        }
    };

    Scene_Splash.prototype.centerSprite = function(sprite) {
        sprite.x = Graphics.width / 2;
        sprite.y = Graphics.height / 2;
        sprite.anchor.x = 0.5;
        sprite.anchor.y = 0.5;
    };

    Scene_Splash.prototype.gotoTitleOrTest = function() {
        Scene_Base.prototype.start.call(this);
        SoundManager.preloadImportantSounds();
        if (DataManager.isBattleTest()) {
            DataManager.setupBattleTest();
            SceneManager.goto(Scene_Battle);
        } else if (DataManager.isEventTest()) {
            DataManager.setupEventTest();
            SceneManager.goto(Scene_Map);
        } else {
            this.checkPlayerLocation();
            DataManager.setupNewGame();
            SceneManager.goto(Scene_Title);
            Window_TitleCommand.initCommandPosition();
        }
        this.updateDocumentTitle();
    };

    Scene_Splash.prototype.updateDocumentTitle = function() {
        document.title = $dataSystem.gameTitle;
    };

    Scene_Splash.prototype.checkPlayerLocation = function() {
        if ($dataSystem.startMapId === 0) {
            throw new Error('Player\'s starting position is not set');
        }
    };

})();


code:
//=============================================================================
// Mano_ActionForAll.js
// ----------------------------------------------------------------------------
// Copyright (c) 2017-2018 Sigureya
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.0 2018/05/21 初版
// ----------------------------------------------------------------------------
// [Twitter]: https://twitter.com/Sigureya/
//=============================================================================

/*:
 * @plugindesc スキルの一部の効果を拡張します。
 *
 * @help
 * 効果ターンを延長したり、連続攻撃の回数を強化できます。
 * メモ欄に以下の改造を施すことで使えます。
 *
 * ■書き方
 * <RepeatEX:10>
 * <RepeatEX:v[3]>
 *
 * <StateTurnEX:3> 3ターン延長
 * <StateTurnEX:v[3]> 変数3で指定したターン延長
 * 右側の数値部分をevalして動かしています。
 *
 */

(function(){
'use strict'

Game_BattlerBase.prototype.extensionStateCounts =function(stateId,turn){
    if(this._stateTurns[stateId]){
        this._stateTurns[stateId] =this._stateTurns[stateId]+turn;
    }
};

const Game_Action_itemEffectAddNormalState =Game_Action.prototype.itemEffectAddNormalState;
/**
 * @param {Game_Battler} target
 * @param {*} effect
 */
Game_Action.prototype.itemEffectAddNormalState=function(target, effect){
    Game_Action_itemEffectAddNormalState.call(this,target, effect);
    const stateId = effect.dataId;
    const result = target.result();
    if(result.isStateAdded(stateId)){
        const exTurn = this.stateTurnExtends();
        if(exTurn !=0){
            target.extensionStateCounts(effect.dataId,exTurn );
        }
    }
};
Game_Action.prototype.stateTurnExtends =function(){
    return this.numberOrVariable_MA('StateTurnEX');
};

const Game_Action_numRepeats =Game_Action.prototype.numRepeats;
Game_Action.prototype.numRepeats =function(){
    const repeats= Game_Action_numRepeats.call(this);
    return repeats + this.extendsNumRepeats();
};

Game_Action.prototype.numberOrVariable_MA =function(metaKey){
    var item = this.item();
    const expr = item.meta[metaKey];
    if(!expr){
        return 0;
    }
    const a = this.subject();
    const v = $gameVariables._data;
    try {
        var value = eval(expr);
        if (isNaN(value)){
             return 0;
        }
		return value;
    } catch (e) {
        return 0;
    }
};

Game_Action.prototype.extendsNumRepeats=function(){
    return this.numberOrVariable_MA("RepeatEX");
};

})()