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

/*:
 * @plugindesc 【ver.1.4】拡張表示をショップのステータスにも反映させます。
 * @author 木星ペンギン
 *
 * @help ▼ 概要
 * --------------------------------
 *  〇 1ページ内に表示される人数が多いほど、表示されるステータスの行数が減ります。
 *     デフォルトの画面サイズでは全部で9行です。
 *     2人の場合は一人4行、3人の場合は一人3行、4人の場合は一人2行となります。
 *
 *  〇 歩行グラの表示を有効にした場合、グラフィックの幅だけ表示が右にずれます。
 *
 *  〇 [装備中表示]は同じアイテムを装備している場合に表示されます。
 *
 *  〇 その他プラグインパラメータで設定する値は[MPP_EquipStatusEX]と同じです。
 *
 *   > 能力値
 *     0:最大ＨＰ, 1:最大ＭＰ, 2:攻撃力, 3:防御力,
 *     4:魔法力,   5:魔法防御, 6:敏捷性, 7:運,
 *
 *     8:命中率,      9:回避率,     10:会心率, 11:会心回避率,
 *    12:魔法回避率, 13:魔法反射率, 14:反撃率, 15:ＨＰ再生率,
 *    16:ＭＰ再生率, 17:ＴＰ再生率,
 *
 *    18:狙われ率,   19:防御効果率,     20:回復効果率,   21:薬の知識,
 *    22:ＭＰ消費率, 23:ＴＰチャージ率, 24:物理ダメージ, 25:魔法ダメージ,
 *    26:床ダメージ, 27:経験獲得率
 *
 *   > 表示タイプ
 *    [固定ステータス] : 常に表示されるステータス
 *    [装備ステータス] : 装備品に含まれる場合に表示されるステータス
 *    [変動ステータス] : 変更がある場合に表示されるステータス
 *
 *
 * ================================================================
 * ▼プラグインパラメータ詳細
 * --------------------------------
 *  〇 プラグインパラメータの配列
 *   数値を配列で設定する際、
 *   n-m と表記することでnからmまでの数値を指定できます。
 *   (例 : 1-4,8,10-12 => 1,2,3,4,8,10,11,12)
 *
 * ================================
 * 制作 : 木星ペンギン
 * URL : http://woodpenguin.blog.fc2.com/
 *
 * @param === Status ===
 * @default 【通常ステータス】
 *
 * @param Weapon Fixing Status
 * @desc 武器選択時の固定ステータスの配列
 * @default 2
 * @parent === Status ===
 *
 * @param Armor Fixing Status
 * @desc 防具選択時の固定ステータスの配列
 * @default 3
 * @parent === Status ===
 *
 * @param Item Status
 * @desc 変更後のアイテムを選択中、装備品に含まれる場合に表示されるステータス
 * @default 2-7
 * @parent === Status ===
 *
 * @param Flow Status
 * @desc 変更後のアイテムを選択中、ステータスに変更がある場合に表示されるステータス
 * @default 0-27
 * @parent === Status ===
 *
 *
 * @param === Trait ===
 * @default 【特徴】
 *
 * @param Element Rate Type
 * @type select
 * @option 非表示
 * @value 0
 * @option 固定ステータス
 * @value 1
 * @option 装備ステータス
 * @value 2
 * @option 変動ステータス
 * @value 3
 * @option 装備or変動ステータス
 * @value 4
 * @desc 属性有効度の表示タイプ
 * @default 4
 * @parent === Trait ===
 *
 * @param Debuff Rate Type
 * @type select
 * @option 非表示
 * @value 0
 * @option 固定ステータス
 * @value 1
 * @option 装備ステータス
 * @value 2
 * @option 変動ステータス
 * @value 3
 * @option 装備or変動ステータス
 * @value 4
 * @desc 弱体有効度の表示タイプ
 * @default 4
 * @parent === Trait ===
 *
 * @param State Rate Type
 * @type select
 * @option 非表示
 * @value 0
 * @option 固定ステータス
 * @value 1
 * @option 装備ステータス
 * @value 2
 * @option 変動ステータス
 * @value 3
 * @option 装備or変動ステータス
 * @value 4
 * @desc ステート有効度の表示タイプ
 * @default 4
 * @parent === Trait ===
 *
 * @param State Resist Type
 * @type select
 * @option 非表示
 * @value 0
 * @option 固定ステータス
 * @value 1
 * @option 装備ステータス
 * @value 2
 * @option 変動ステータス
 * @value 3
 * @option 装備or変動ステータス
 * @value 4
 * @desc ステート無効化の表示タイプ
 * @default 3
 * @parent === Trait ===
 *
 * @param Original Trait Type
 * @type select
 * @option 非表示
 * @value 0
 * @option 固定ステータス
 * @value 1
 * @option 装備ステータス
 * @value 2
 * @option 変動ステータス
 * @value 3
 * @option 装備or変動ステータス
 * @value 4
 * @desc オリジナルパラメータの表示タイプ
 * @default 3
 * @parent === Trait ===
 *
 *
 * @param === Shop Window ===
 * @default 【ショップウィンドウ】
 *
 * @param Members Size
 * @type number
 * @min 1
 * @max 4
 * @desc １ページに表示する人数
 * @default 4
 * @parent === Shop Window ===
 *
 * @param Actor Name Draw?
 * @type boolean
 * @desc アクターの名前を表示するかどうか
 * @default true
 * @parent === Shop Window ===
 *
 * @param Character Draw?
 * @type boolean
 * @desc アクターの歩行グラを表示するかどうか
 * @default false
 * @parent === Shop Window ===
 *
 * @param Current Item Draw?
 * @type boolean
 * @desc 装備中のアイテム名を表示するかどうか
 * @default false
 * @parent === Shop Window ===
 *
 * @param Equipping Pos
 * @type select
 * @option 非表示
 * @value 0
 * @option 名前の右に表示
 * @value 1
 * @option 歩行グラに重ねて表示
 * @value 2
 * @desc [装備中表示]の表示位置
 * @default 1
 * @parent === Shop Window ===
 *
 * @param Equipping Text
 * @desc 装備中表示
 * @default Ｅ
 * @parent Equipping Pos
 *
 * @param Equipping Font Size
 * @type number
 * @desc [装備中表示]の文字サイズ
 * @default 24
 * @parent Equipping Pos
 *
 * @param Equipping Ox
 * @type number
 * @min -99999999
 * @desc [装備中表示]の表示位置 X軸補正
 * @default 0
 * @parent Equipping Pos
 *
 * @param Equipping Oy
 * @type number
 * @min -99999999
 * @desc [装備中表示]の表示位置 Y軸補正
 * @default 0
 * @parent Equipping Pos
 *
 *
 *
 */

(function () {
  const MPPlugin = {};

  {
    let parameters = PluginManager.parameters("MPP_EquipStatusEX_OP1");

    MPPlugin.contains = {};
    MPPlugin.contains["EquipStatusEX"] = $plugins.some(function (plugin) {
      return plugin.name === "MPP_EquipStatusEX" && plugin.status;
    });

    function convertParam(name) {
      var param = parameters[name];
      var result = [];
      if (param) {
        var data = param.split(",");
        for (var i = 0; i < data.length; i++) {
          if (/(\d+)\s*-\s*(\d+)/.test(data[i])) {
            var min = Number(RegExp.$1);
            var max = Number(RegExp.$2);
            for (var n = min; n <= max; n++) {
              result.push(n);
            }
          } else {
            result.push(Number(data[i]));
          }
        }
      }
      return result;
    }

    // Status
    MPPlugin.WeaponFixingStatus = convertParam("Weapon Fixing Status");
    MPPlugin.ArmorFixingStatus = convertParam("Armor Fixing Status");
    MPPlugin.itemStatus = convertParam("Item Status");
    MPPlugin.flowStatus = convertParam("Flow Status");

    // Traits
    MPPlugin.elementRateType = Number(parameters["Element Rate Type"] || 4);
    MPPlugin.debuffRateType = Number(parameters["Debuff Rate Type"] || 4);
    MPPlugin.stateRateType = Number(parameters["State Rate Type"] || 4);
    MPPlugin.stateResistType = Number(parameters["State Resist Type"] || 3);
    MPPlugin.OriginalTraitType = Number(parameters["Original Trait Type"] || 3);

    // Shop Status
    MPPlugin.MembersSize = Number(parameters["Members Size"] || 4);
    MPPlugin.ActorNameDraw = !!eval(parameters["Actor Name Draw?"]);
    MPPlugin.CharacterDraw = !!eval(parameters["Character Draw?"]);
    MPPlugin.CurrentItemDraw = !!eval(parameters["Current Item Draw?"]);
    MPPlugin.EquippingPos = Number(parameters["Equipping Pos"] || 0);
    MPPlugin.EquippingFontSize = Number(
      parameters["Equipping Font Size"] || 24
    );
    MPPlugin.EquippingOx = Number(parameters["Equipping Ox"] || 0);
    MPPlugin.EquippingOy = Number(parameters["Equipping Oy"] || 0);

    // Terms
    MPPlugin.terms = {};
    MPPlugin.terms.Equipping = parameters["Equipping Text"];
  }

  if (!MPPlugin.contains["EquipStatusEX"]) {
    return;
  }

  const Alias = {};

  //-----------------------------------------------------------------------------
  // Window_ShopStatus

  Window_ShopStatus._directionPattern = [2, 4, 8, 6];

  //14
  Alias.WiShSt_initialize = Window_ShopStatus.prototype.initialize;
  Window_ShopStatus.prototype.initialize = function (x, y, width, height) {
    this._createDrawer = false;
    this._mppEqStGaugeCount = 0;
    this._animeCount = 0;
    this._animeIndex = 0;
    this._animePattern = 0;
    Alias.WiShSt_initialize.apply(this, arguments);
  };

  //21
  Alias.WiShSt_refresh = Window_ShopStatus.prototype.refresh;
  Window_ShopStatus.prototype.refresh = function () {
    this.clearUpdateDrawer();
    this._createDrawer = true;
    this._mppEqStGaugeCount = 28;
    Alias.WiShSt_refresh.apply(this, arguments);
    this._createDrawer = false;
  };

  Window_ShopStatus.prototype.currentSlotId = function (actor, etypeId, item) {
    var equips = actor.equips();
    var slots = actor.equipSlots();
    for (var i = 0; i < slots.length; i++) {
      if (slots[i] === etypeId && equips[i] === item) return i;
    }
    return -1;
  };

  //50
  Window_ShopStatus.prototype.drawEquipInfo = function (x, y) {
    var members = this.statusMembers();
    var itemHeight = this.itemHeight();
    for (var i = 0; i < members.length; i++) {
      this.drawActorEquipInfo(x, y + itemHeight * i, members[i]);
    }
  };

  //63
  Window_ShopStatus.prototype.pageSize = function () {
    return MPPlugin.MembersSize;
  };

  Window_ShopStatus.prototype.itemHeight = function () {
    return (this.contentsHeight() - this.lineHeight() * 2) / this.pageSize();
  };

  //71
  Window_ShopStatus.prototype.drawActorEquipInfo = function (x, y, actor) {
    this._enabled = actor.canEquip(this._item);

    var height = this.lineHeight();
    var maxRow = Math.floor(this.itemHeight() / height);
    var row = 0;

    this._actor = actor;
    this._tempActor = JsonEx.makeDeepCopy(actor);
    var curItem = null;
    if (this._enabled)
      curItem = this.currentEquippedItem(actor, this._item.etypeId);
    this._equippng = curItem === this._item;
    if (!this._equippng) {
      var slotId = this.currentSlotId(actor, this._item.etypeId, curItem);
      if (slotId >= 0) this._tempActor.forceChangeEquip(slotId, this._item);
    }

    if (MPPlugin.CharacterDraw) {
      this.drawActorCharacter(this._tempActor || this._actor, x + 24, y + 48);
      x += 48;
    }
    this.changePaintOpacity(this._enabled);
    this.resetTextColor();
    if (MPPlugin.ActorNameDraw) {
      var width = this.contentsWidth() - x - this.textPadding();
      this.drawActorName(actor, x, y + row * height, width);
      row++;
      if (!MPPlugin.CharacterDraw) x += 24;
    }
    if (this._enabled && row < maxRow) {
      if (MPPlugin.CurrentItemDraw) {
        this.drawItemName(curItem, x, y + row * height);
        row++;
      }
      if (row < maxRow) this.drawParameters(x, y + row * height, maxRow - row);
    }
  };

  Window_ShopStatus.prototype.drawEquipping = function (x, y, width) {
    var text = MPPlugin.terms.Equipping;
    if (text) {
      this.changeTextColor(this.systemColor());
      this.contents.fontSize = MPPlugin.EquippingFontSize;
      this.drawText(text, x, y, width, "right");
      this.contents.fontSize = this.standardFontSize();
    }
  };

  //
  Window_ShopStatus.prototype.drawCharacter = function (
    characterName,
    characterIndex,
    x,
    y
  ) {
    var bitmap = ImageManager.loadCharacter(characterName);
    var big = ImageManager.isBigCharacter(characterName);
    var pw = bitmap.width / (big ? 3 : 12);
    var ph = bitmap.height / (big ? 4 : 8);
    var n = characterIndex;
    var p = this._animePattern % 4;
    p = p < 3 ? p : 1;
    var d = Window_ShopStatus._directionPattern[this._animeIndex];
    d = (d - 2) / 2;
    var sx = ((n % 4) * 3 + p) * pw;
    var sy = (Math.floor(n / 4) * 4 + d) * ph;
    this.contents.blt(bitmap, sx, sy, pw, ph, x - pw / 2, y - 48, pw, ph);
  };

  //
  Window_ShopStatus.prototype.drawActorCharacter = function (actor, x, y) {
    var pattern = this._animePattern;
    if (!this._enabled) this._animePattern = 1;
    this.changePaintOpacity(this._enabled);
    Window_Base.prototype.drawActorCharacter.call(this, actor, x, y);
    this._animePattern = pattern;
    this.changePaintOpacity(true);
    if (this._equippng && MPPlugin.EquippingPos === 2) {
      var height = this.lineHeight();
      var sy = Math.floor((height - MPPlugin.EquippingFontSize) / 2);
      this.drawEquipping(x - 24, y - height + sy, 48);
    }

    if (this._createDrawer) {
      this.createActorCharacterDrawer(
        actor,
        x,
        y,
        this._enabled,
        this._equippng
      );
    }
  };

  Window_ShopStatus.prototype.createActorCharacterDrawer = function (
    actor,
    x,
    y,
    enabled,
    equippng
  ) {
    this.addUpdateDrawer(() => {
      if (this._animeCount === 0) {
        this.clearActorCharacterRect(actor, x, y);
        this._enabled = enabled;
        this._equippng = equippng;
        this.drawActorCharacter(actor, x, y);
      }
      return true;
    });
  };

  Window_ShopStatus.prototype.clearActorCharacterRect = function (actor, x, y) {
    var characterName = actor.characterName();
    var bitmap = ImageManager.loadCharacter(characterName);
    var big = ImageManager.isBigCharacter(characterName);
    var pw = bitmap.width / (big ? 3 : 12);
    var ph = bitmap.height / (big ? 4 : 8);
    this.contents.clearRect(x - pw / 2, y - 48, pw, ph);
  };

  //
  Window_ShopStatus.prototype.drawActorName = function (actor, x, y, width) {
    Window_Base.prototype.drawActorName.call(this, actor, x, y, width);
    if (this._equippng && MPPlugin.EquippingPos === 1) {
      this.drawEquipping(x, y, width);
    }
  };

  //117
  Alias.WiShSt_update = Window_ShopStatus.prototype.update;
  Window_ShopStatus.prototype.update = function () {
    if (this._mppEqStGaugeCount > 0) this._mppEqStGaugeCount--;
    if (MPPlugin.CharacterDraw && this.isEquipItem()) {
      this.updateAnime();
    }
    Alias.WiShSt_update.apply(this, arguments);
  };

  Window_ShopStatus.prototype.updateAnime = function () {
    this._animeCount++;
    if (this._animeCount === 24) {
      this._animeCount = 0;
      this._animePattern++;
      if (this._animePattern === 8) {
        this._animePattern = 0;
        this._animeIndex = (this._animeIndex + 1) % 4;
      }
    }
  };

  //EqStEX
  Window_ShopStatus.prototype.convertList = function (list, type) {
    return list.map((id) => ({
      type: type,
      value: id,
      actor: this._actor,
      tempActor: this._tempActor,
    }));
  };

  //EqStEX
  Window_ShopStatus.prototype.getFixingStatus = function () {
    if (DataManager.isWeapon(this._item)) {
      return MPPlugin.WeaponFixingStatus;
    } else {
      return MPPlugin.ArmorFixingStatus;
    }
  };
  Window_ShopStatus.prototype.getItemStatus = function () {
    return MPPlugin.itemStatus;
  };
  Window_ShopStatus.prototype.getFlowStatus = function () {
    return MPPlugin.flowStatus;
  };
  Window_ShopStatus.prototype.getElementRateType = function () {
    return MPPlugin.elementRateType;
  };
  Window_ShopStatus.prototype.getDebuffRateType = function () {
    return MPPlugin.debuffRateType;
  };
  Window_ShopStatus.prototype.getStateRateType = function () {
    return MPPlugin.stateRateType;
  };
  Window_ShopStatus.prototype.getStateResistType = function () {
    return MPPlugin.stateResistType;
  };
  Window_ShopStatus.prototype.getOriginalTraitType = function () {
    return MPPlugin.OriginalTraitType;
  };

  Window_ShopStatus.prototype.drawItem = function (x, y, data) {
    this._actor = data.actor;
    this._tempActor = data.tempActor;
    this.changePaintOpacity(true);
    Window_EquipStatus.prototype.drawItem.call(this, x, y, data);
  };

  {
    let ShopStatus = Window_ShopStatus.prototype;
    let EquipStatus = Window_EquipStatus.prototype;

    ShopStatus.drawRightArrow = EquipStatus.drawRightArrow;

    ShopStatus.drawParameters = EquipStatus.drawParameters;
    ShopStatus.makeStatusList = EquipStatus.makeStatusList;
    ShopStatus.createEquipParamsList = EquipStatus.createEquipParamsList;
    ShopStatus.isChangedParam = EquipStatus.isChangedParam;
    ShopStatus.isChangedRate = EquipStatus.isChangedRate;
    ShopStatus.createElementRateList = EquipStatus.createElementRateList;
    ShopStatus.createDebuffRateList = EquipStatus.createDebuffRateList;
    ShopStatus.createStateRateList = EquipStatus.createStateRateList;
    ShopStatus.createStateResistList = EquipStatus.createStateResistList;
    ShopStatus.createOriginalTraitList = EquipStatus.createOriginalTraitList;
    ShopStatus.createDefaultParamsList = EquipStatus.createDefaultParamsList;

    ShopStatus.createItemDrawer = EquipStatus.createItemDrawer;

    ShopStatus.drawParamGauge = EquipStatus.drawParamGauge;
    ShopStatus.drawFlatGauge = EquipStatus.drawFlatGauge;
    ShopStatus.drawFlatLine = EquipStatus.drawFlatLine;
    ShopStatus.drawFlatShadow = EquipStatus.drawFlatShadow;
    ShopStatus.drawArcGauge = EquipStatus.drawArcGauge;
    ShopStatus.drawArcLine = EquipStatus.drawArcLine;
    ShopStatus.drawArcShadow = EquipStatus.drawArcShadow;
    ShopStatus.draw2LineGauge = EquipStatus.draw2LineGauge;

    ShopStatus.drawParam = EquipStatus.drawParam;
    ShopStatus.drawParamName = EquipStatus.drawParamName;
    ShopStatus.drawCurrentParam = EquipStatus.drawCurrentParam;
    ShopStatus.drawNewParam = EquipStatus.drawNewParam;
    ShopStatus.includeParam = EquipStatus.includeParam;
    ShopStatus.includeTrait = EquipStatus.includeTrait;
    ShopStatus.includeRate = EquipStatus.includeRate;
    ShopStatus.getActorParam = EquipStatus.getActorParam;
    ShopStatus.getParamMax = EquipStatus.getParamMax;
    ShopStatus.drawElement = EquipStatus.drawElement;
    ShopStatus.drawDebuff = EquipStatus.drawDebuff;
    ShopStatus.drawState = EquipStatus.drawState;
    ShopStatus.drawRate = EquipStatus.drawRate;
    ShopStatus.drawResist = EquipStatus.drawResist;
    ShopStatus.drawOriginal = EquipStatus.drawOriginal;
    ShopStatus.drawTraitText = EquipStatus.drawTraitText;
  }
})();


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

/*:
 * @plugindesc 【ver.1.0】現在アクティブなウィンドウを強調表示します。
 * @author 木星ペンギン
 *
 * @help
 * ================================
 * 制作 : 木星ペンギン
 * URL : http://woodpenguin.blog.fc2.com/
 *
 * @param Back Blend Color
 * @desc 背景の強調表示の色
 * @default 160,192,192,96
 *
 * @param Frame Blend Color
 * @desc フレームの強調表示の色
 * @default 160,128,0,224
 *
 * @param Highlight Type
 * @desc 表示タイプ (0:明滅、1:フラッシュ)
 * @default 0
 *
 *
 *
 */

(function () {
  var MPPlugin = {
    params: PluginManager.parameters("MPP_HighlightActiveWindow"),
  };

  MPPlugin.BackBlendColor = MPPlugin.params["Back Blend Color"]
    .split(",")
    .map(Number);
  MPPlugin.FrameBlendColor = MPPlugin.params["Frame Blend Color"]
    .split(",")
    .map(Number);
  MPPlugin.HighlightType = Number(MPPlugin.params["Highlight Type"]);

  var Alias = {};

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

  //6259
  Alias.Wi_initialize = Window.prototype.initialize;
  Window.prototype.initialize = function () {
    Alias.Wi_initialize.call(this);
    this._highlight = false;
    this._highlightCount = 0;
  };

  Object.defineProperty(Window.prototype, "highlight", {
    get: function () {
      return this._highlight;
    },
    set: function (value) {
      if (this._highlight !== value) {
        this._highlight = value;
        this._highlightCount = 0;
        this._windowBackSprite.setBlendColor([0, 0, 0, 0]);
        this._windowFrameSprite.setBlendColor([0, 0, 0, 0]);
      }
    },
    configurable: true,
  });

  //6605
  Alias.Wi_updateTransform = Window.prototype.updateTransform;
  Window.prototype.updateTransform = function () {
    this._updateHighlight();
    Alias.Wi_updateTransform.call(this);
  };

  Window.prototype._updateHighlight = function () {
    if (this._highlight) {
      if (this._highlightCount % 6 === 0) {
        var color1 = MPPlugin.BackBlendColor.clone();
        var color2 = MPPlugin.FrameBlendColor.clone();
        var alpha = 0;
        if (MPPlugin.HighlightType === 0) {
          alpha = 1 - Math.abs(30 - (this._highlightCount % 60)) / 30;
        } else {
          alpha = Math.max(1 - this._highlightCount / 60, 0);
        }
        color1[3] *= alpha;
        color2[3] *= alpha;
        this._windowBackSprite.setBlendColor(color1);
        this._windowFrameSprite.setBlendColor(color2);
      }
      this._highlightCount++;
    }
  };

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

  //270
  Alias.WiSe_update = Window_Selectable.prototype.update;
  Window_Selectable.prototype.update = function () {
    Alias.WiSe_update.call(this);
    this.highlight = this.active;
  };
})();

repo_name: dazed/translations

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.1]
 * 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.1]
 * このプラグインは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 (Utils.RPGMAKER_NAME === "MV") {
    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;
    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_PreLoadAnime.js
//=============================================================================
// Copyright (c) 2018 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc 【ver.1.2】画像の先読み込みを行うことで、戦闘中のアニメーション表示をスムーズにします。
 * @author 木星ペンギン
 *
 * @help ▼読み込みタイミング
 * --------------------------------
 *  〇通常攻撃
 *   [攻撃]を選択した時点で、アニメーションを読み込みます。
 *
 *  〇スキル・アイテム
 *   実行するスキル・アイテムを決定した時点で、そのアニメーションを読み込みます。
 *
 *  〇操作不能の場合
 *   ステートの[行動制約]によりアクションの選択ができなかったり、
 *   または特徴で[自動戦闘]になっているなど操作できないアクターの場合、
 *   ターン開始時にアニメーションを読み込みます。
 *
 *  〇エネミーのアクション
 *   エネミーの場合はターン開始時にアニメーションを読み込みます。
 *
 * ================================
 * 制作 : 木星ペンギン
 * URL : http://woodpenguin.blog.fc2.com/
 *
 */

(function () {
  var Alias = {};

  var RequestAnime = function (animation) {
    if (animation) {
      var name1 = animation.animation1Name;
      var name2 = animation.animation2Name;
      var hue1 = animation.animation1Hue;
      var hue2 = animation.animation2Hue;
      ImageManager.requestAnimation(name1, hue1);
      ImageManager.requestAnimation(name2, hue2);
    }
  };

  //-----------------------------------------------------------------------------
  // Game_Battler

  Game_Battler.prototype.requestItemAnimation = function (item) {
    if (item) {
      var animationId = item.animationId;
      if (animationId < 0) {
        if (this.isActor()) {
          RequestAnime($dataAnimations[this.attackAnimationId1()]);
          RequestAnime($dataAnimations[this.attackAnimationId2()]);
        }
      } else {
        RequestAnime($dataAnimations[animationId]);
      }
    }
  };

  Game_Battler.prototype.requestActionsAnimation = function () {
    for (var i = 0; i < this.numActions(); i++) {
      var action = this.action(i);
      this.requestItemAnimation(action ? action.item() : null);
    }
  };

  //-----------------------------------------------------------------------------
  // Game_Actor

  //736
  Alias.GaAc_makeActions = Game_Actor.prototype.makeActions;
  Game_Actor.prototype.makeActions = function () {
    Alias.GaAc_makeActions.call(this);
    this.requestActionsAnimation();
  };

  //-----------------------------------------------------------------------------
  // Game_Enemy

  //278
  Alias.GaEn_makeActions = Game_Enemy.prototype.makeActions;
  Game_Enemy.prototype.makeActions = function () {
    Alias.GaEn_makeActions.call(this);
    this.requestActionsAnimation();
  };

  //-----------------------------------------------------------------------------
  // Scene_Battle

  //265
  Alias.ScBa_commandAttack = Scene_Battle.prototype.commandAttack;
  Scene_Battle.prototype.commandAttack = function () {
    var actor = BattleManager.actor();
    actor.requestItemAnimation($dataSkills[actor.attackSkillId()]);
    Alias.ScBa_commandAttack.call(this);
  };

  //361
  Alias.ScBa_onSkillOk = Scene_Battle.prototype.onSkillOk;
  Scene_Battle.prototype.onSkillOk = function () {
    BattleManager.actor().requestItemAnimation(this._skillWindow.item());
    Alias.ScBa_onSkillOk.call(this);
  };

  //374
  Alias.ScBa_onItemOk = Scene_Battle.prototype.onItemOk;
  Scene_Battle.prototype.onItemOk = function () {
    BattleManager.actor().requestItemAnimation(this._itemWindow.item());
    Alias.ScBa_onItemOk.call(this);
  };
})();


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

/*:
 * @plugindesc 【ver.1.1】戦闘に必要な画像を先読み込みすることで、戦闘開始時のロード時間をわずかに減らします。
 * @author 木星ペンギン
 *
 * @help 通常、戦闘画面へ移行する際に読み込みを行う画像を、
 *   戦闘開始エフェクトと同時に先読み込みを行います。
 *
 * デフォルトではエフェクトの時間が60フレーム(1秒)なので
 * 理論上はロード時間が1秒短縮されます。
 *
 * ================================================================
 * ▼デフォルトの仕様
 *  ツクールMVでは、戦闘開始エフェクト後に背景画像とエネミー画像の読み込みを
 *  開始し、読み込み完了までLoadingの文字を表示させます。
 *  アクター画像は戦闘開始後に読み込みが始まり、読み込みができ次第、
 *  画面内に登場します。
 *
 * ▼プラグインパラメータ説明
 *  〇アクターの戦闘画像の先読みを行うかどうか
 *   アクター画像の先読みを行うことで、戦闘開始後の処理落ちを軽減します。
 *   ただし、Loadingが表示される時間が長くなる可能性があります。
 *   主に[キャラクターメイク(MPP_CharacterMake.js)]と
 *   [戦闘開始特殊エフェクト(MPP_EncounterEffect.js)]を併用した場合を
 *   想定した機能です。
 *
 *  〇エネミーの戦闘画像の先読みを行うかどうか
 *   エネミー画像の先読みを無効化した場合、Loadingが表示される時間が
 *   短縮できます。
 *   ただし、戦闘開始後に処理落ちが発生する可能性があります。
 *   主に[敵キャラを遅れて登場させる(MPP_EnemyEntryAfterStart.js)]と
 *   併用した場合を想定した機能です。
 *
 * ================================
 * 制作 : 木星ペンギン
 * URL : http://woodpenguin.blog.fc2.com/
 *
 *
 * @param Actor Image Preload?
 * @type boolean
 * @desc アクターの戦闘画像の先読みを行うかどうか
 * @default false
 *
 * @param Enemy Image Preload?
 * @type boolean
 * @desc エネミーの戦闘画像の先読みを行うかどうか
 * @default true
 *
 */

(function () {
  var MPPlugin = {};

  (function () {
    var parameters = PluginManager.parameters("MPP_PreloadBattleImage");

    MPPlugin.ActorImagePreload = !!eval(
      parameters["Actor Image Preload?"] || "false"
    );
    MPPlugin.EnemyImagePreload = !!eval(
      parameters["Enemy Image Preload?"] || "true"
    );
  })();

  //-----------------------------------------------------------------------------
  // Scene_Map

  //57
  var _Scene_Map_launchBattle = Scene_Map.prototype.launchBattle;
  Scene_Map.prototype.launchBattle = function () {
    _Scene_Map_launchBattle.call(this);
    var spriteset = Object.create(Spriteset_Battle.prototype);
    ImageManager.requestBattleback1(spriteset.battleback1Name());
    ImageManager.requestBattleback2(spriteset.battleback2Name());
    if (MPPlugin.ActorImagePreload) {
      var actors = $gameParty.battleMembers();
      for (var i = 0; i < actors.length; i++) {
        if (actors[i].isSpriteVisible()) {
          var name = actors[i].battlerName();
          ImageManager.requestSvActor(name);
        }
      }
    }
    if (MPPlugin.EnemyImagePreload) {
      var enemies = $gameTroop.members();
      for (var i = 0; i < enemies.length; i++) {
        var name = enemies[i].battlerName();
        var hue = enemies[i].battlerHue();
        if ($gameSystem.isSideView()) {
          ImageManager.requestSvEnemy(name, hue);
        } else {
          ImageManager.requestEnemy(name, hue);
        }
      }
    }
  };
})();


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