code:
//=============================================================================
// main.js v1.6.0
//=============================================================================

const scriptUrls = [
  "js/libs/pixi.js",
  "js/libs/pako.min.js",
  "js/libs/localforage.min.js",
  "js/libs/effekseer.min.js",
  "js/libs/vorbisdecoder.js",
  "js/rmmz_core.js",
  "js/rmmz_managers.js",
  "js/rmmz_objects.js",
  "js/rmmz_scenes.js",
  "js/rmmz_sprites.js",
  "js/rmmz_windows.js",
  "js/plugins.js",
];
const effekseerWasmUrl = "js/libs/effekseer.wasm";

class Main {
  constructor() {
    this.xhrSucceeded = false;
    this.loadCount = 0;
    this.error = null;
  }

  run() {
    this.showLoadingSpinner();
    this.testXhr();
    this.hookNwjsClose();
    this.loadMainScripts();
  }

  showLoadingSpinner() {
    const loadingSpinner = document.createElement("div");
    const loadingSpinnerImage = document.createElement("div");
    loadingSpinner.id = "loadingSpinner";
    loadingSpinnerImage.id = "loadingSpinnerImage";
    loadingSpinner.appendChild(loadingSpinnerImage);
    document.body.appendChild(loadingSpinner);
  }

  eraseLoadingSpinner() {
    const loadingSpinner = document.getElementById("loadingSpinner");
    if (loadingSpinner) {
      document.body.removeChild(loadingSpinner);
    }
  }

  testXhr() {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", document.currentScript.src);
    xhr.onload = () => (this.xhrSucceeded = true);
    xhr.send();
  }

  hookNwjsClose() {
    // [Note] When closing the window, the NW.js process sometimes does
    //   not terminate properly. This code is a workaround for that.
    if (typeof nw === "object") {
      nw.Window.get().on("close", () => nw.App.quit());
    }
  }

  loadMainScripts() {
    for (const url of scriptUrls) {
      const script = document.createElement("script");
      script.type = "text/javascript";
      script.src = url;
      script.async = false;
      script.defer = true;
      script.onload = this.onScriptLoad.bind(this);
      script.onerror = this.onScriptError.bind(this);
      script._url = url;
      document.body.appendChild(script);
    }
    this.numScripts = scriptUrls.length;
    window.addEventListener("load", this.onWindowLoad.bind(this));
    window.addEventListener("error", this.onWindowError.bind(this));
  }

  onScriptLoad() {
    if (++this.loadCount === this.numScripts) {
      PluginManager.setup($plugins);
    }
  }

  onScriptError(e) {
    this.printError("Failed to load", e.target._url);
  }

  printError(name, message) {
    this.eraseLoadingSpinner();
    if (!document.getElementById("errorPrinter")) {
      const errorPrinter = document.createElement("div");
      errorPrinter.id = "errorPrinter";
      errorPrinter.innerHTML = this.makeErrorHtml(name, message);
      document.body.appendChild(errorPrinter);
    }
  }

  makeErrorHtml(name, message) {
    const nameDiv = document.createElement("div");
    const messageDiv = document.createElement("div");
    nameDiv.id = "errorName";
    messageDiv.id = "errorMessage";
    nameDiv.innerHTML = name;
    messageDiv.innerHTML = message;
    return nameDiv.outerHTML + messageDiv.outerHTML;
  }

  onWindowLoad() {
    if (!this.xhrSucceeded) {
      const message = "Your browser does not allow to read local files.";
      this.printError("Error", message);
    } else if (this.isPathRandomized()) {
      const message = "Please move the Game.app to a different folder.";
      this.printError("Error", message);
    } else if (this.error) {
      this.printError(this.error.name, this.error.message);
    } else {
      this.initEffekseerRuntime();
    }
  }

  onWindowError(event) {
    if (!this.error) {
      this.error = event.error;
    }
  }

  isPathRandomized() {
    // [Note] We cannot save the game properly when Gatekeeper Path
    //   Randomization is in effect.
    return (
      typeof process === "object" &&
      process.mainModule.filename.startsWith("/private/var")
    );
  }

  initEffekseerRuntime() {
    const onLoad = this.onEffekseerLoad.bind(this);
    const onError = this.onEffekseerError.bind(this);
    effekseer.initRuntime(effekseerWasmUrl, onLoad, onError);
  }

  onEffekseerLoad() {
    this.eraseLoadingSpinner();
    SceneManager.run(Scene_Boot);
  }

  onEffekseerError() {
    this.printError("Failed to load", effekseerWasmUrl);
  }
}

const main = new Main();
main.run();

//-----------------------------------------------------------------------------

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// AccumulateState.js
// ----------------------------------------------------------------------------
// (C)2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.4.1 2022/05/25 2.4.0の修正で不要なゲージが表示される場合がある問題を修正
// 2.4.0 2022/03/18 マップ画面とステータス画面に蓄積ゲージを表示できるよう修正
// 2.3.0 2021/07/23 敵キャラに対しても蓄積ゲージを表示できる機能を追加
// 2.2.1 2021/07/16 蓄積型ステートが有効になるごとに耐性が上昇する機能を追加
// 2.2.0 2021/07/15 MZで動作するよう全面的に修正
// 2.1.0 2021/07/15 蓄積ゲージ表示の有無をスイッチで切り替えられる機能を追加
// 2.0.0 2017/05/29 蓄積率計算式を独自に指定できるよう仕様変更。運補正と必中補正の有無を設定できる機能を追加
// 1.1.1 2017/05/28 減算の結果が負の値になったときに蓄積率が減算されていた問題を修正
// 1.1.0 2017/05/28 耐性計算式を除算と減算の二つを用意しました。
// 1.0.1 2016/05/31 戦闘テスト以外で戦闘に入るとエラーになる場合がある問題を修正
// 1.0.0 2016/05/28 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc 蓄積型ステートプラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/AccumulateState.js
 * @base PluginCommonBase
 * @orderAfter PluginCommonBase
 * @author トリアコンタン
 *
 * @param GaugeImage
 * @text ゲージ画像ファイル
 * @desc ゲージ表示に使用する画像ファイル(img/pictures)です。空のゲージと満タンのゲージを縦に並べて一つの画像にしてください。
 * @default
 * @dir img/pictures/
 * @type file
 *
 * @param GaugeSwitchId
 * @text ゲージ表示スイッチ
 * @desc 有効にすると指定したスイッチがONのときだけゲージ表示されます。
 * @default 0
 * @type switch
 *
 * @param AccumulateFormula
 * @text 蓄積率計算式
 * @desc 蓄積率を算出する計算式を効果の「ステート付加」および対象の「ステート有効度」から独自作成します。
 * @default
 *
 * @param LuckAdjust
 * @text 運補正
 * @desc ONにすると蓄積率に対して運による補正を掛けます。（デフォルト仕様準拠）
 * @default true
 * @type boolean
 *
 * @param CertainHit
 * @text 必中時有効度無視
 * @desc ONにすると必中スキルに関しては「ステート付加」の値がそのまま蓄積率に反映されます。
 * @default true
 * @type boolean
 *
 * @param ImmunityRate
 * @text 免疫率
 * @desc ステートが有効になるごとに加算される耐性値です。100になると一切、上昇しなくなります。
 * @default 0
 * @type number
 *
 * @command ACCUMULATE
 * @text 蓄積
 * @desc 指定したアクターのステート蓄積量を増減します。
 *
 * @arg actorId
 * @text アクターID
 * @desc 対象のアクターIDです。敵キャラを対象にする場合は0のままでOKです。
 * @default 0
 * @type actor
 *
 * @arg enemyIndex
 * @text 敵キャラインデックス
 * @desc 対象の敵キャラインデックスです。アクターを対象にする場合は-1のままでOKです。
 * @default -1
 * @type number
 * @min -1
 *
 * @arg stateId
 * @text ステートID
 * @desc 対象のステートIDです。蓄積型のステートを指定してください。
 * @default 1
 * @type state
 *
 * @arg rate
 * @text 蓄積率
 * @desc 蓄積率(-100% ～ 100%)です。
 * @default 0
 * @type number
 * @min -100
 * @max 100
 *
 * @help 特定のステートを蓄積型に変更します。
 * 蓄積型のステートにしたい場合、メモ欄に以下の通り設定してください。
 * <蓄積型>
 * <Accumulate>
 *
 * 蓄積型ステートは使用効果「ステート付加」によって値が蓄積していき、
 * 蓄積率が100%(=1.0)を超えると対象のステートが有効になります。
 * 計算式は以下の通りです。
 *
 * 効果「ステート付加」の設定値 * 対象の「ステートの有効度」 = 蓄積率
 * 例：効果の「ステート付加」が80%(0.8)で、対象のステート有効度が50%(0.5)の場合
 * 0.8 * 0.5 = 0.4         # 蓄積率は40%(0.4)
 *
 * さらに上級者向け機能として蓄積率計算式を別途指定できます。
 * 計算式では以下の変数が使用できます。
 *
 * a : 効果の「ステート付加」の設定値
 * b : 対象の「ステート有効度」の設定値
 *
 * 蓄積率計算式の指定例
 * a - (1.0 - b)
 *
 * 例：効果の「ステート付加」が80%(0.8)で、対象のステート有効度が50%(0.5)の場合
 * 0.8 - (1.0 - 0.5) = 0.3  # 蓄積率は30%(0.3)
 *
 * 蓄積率が負の値になった場合は「0」として計算されます。実行時にブザーが鳴る場合、
 * スクリプトの記述に問題があります。
 * F8を押下してデベロッパツールを開き、内容を確認してください。
 *
 * また、「ステート解除」によって蓄積率がリセットされます。
 *
 * ステートをひとつだけ指定して戦闘画面にゲージとして表示することができます。
 * この機能を使う場合は、アクターのメモ欄に以下の通り設定してください。
 * <蓄積ゲージステート:3> // 蓄積型のステートID「3」をゲージとして表示します。
 * <蓄積ゲージX:600>      // ゲージのX座標です。
 * <蓄積ゲージY:400>      // ゲージのY座標です。
 *
 * マップ画面、ステータス画面にゲージを表示したい場合は座標を指定してください。
 * <蓄積マップゲージX:600> // マップ画面のゲージのX座標です。
 * <蓄積マップゲージY:400> // マップ画面のゲージのY座標です。
 * <蓄積ステータスゲージX:600> // ステータス画面のゲージのX座標です。
 * <蓄積ステータスゲージY:400> // ステータス画面のゲージのY座標です。
 *
 * ゲージ画像はパラメータで指定したものを使用します。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(() => {
  "use strict";
  const script = document.currentScript;
  const param = PluginManagerEx.createParameter(script);

  PluginManagerEx.registerCommand(script, "ACCUMULATE", (args) => {
    const actor = $gameActors.actor(args.actorId);
    if (actor) {
      actor.accumulateState(args.stateId, args.rate / 100);
    }
    const enemy = $gameTroop.members()[args.enemyIndex];
    if (enemy) {
      enemy.accumulateState(args.stateId, args.rate / 100);
    }
  });

  //=============================================================================
  // Game_BattlerBase
  //  ステート蓄積量を管理します。
  //=============================================================================
  Game_BattlerBase.prototype.clearStateAccumulationsIfNeed = function () {
    if (!this._stateAccumulations) {
      this._stateAccumulations = {};
    }
    if (!this._stateImmunity) {
      this._stateImmunity = {};
    }
  };

  const _Game_BattlerBase_clearStates = Game_BattlerBase.prototype.clearStates;
  Game_BattlerBase.prototype.clearStates = function () {
    _Game_BattlerBase_clearStates.apply(this, arguments);
    this.clearStateAccumulationsIfNeed();
  };

  const _Game_BattlerBase_eraseState = Game_BattlerBase.prototype.eraseState;
  Game_BattlerBase.prototype.eraseState = function (stateId) {
    _Game_BattlerBase_eraseState.apply(this, arguments);
    this.clearStateAccumulationsIfNeed();
    delete this._stateAccumulations[stateId];
  };

  const _Game_Battler_removeState = Game_Battler.prototype.removeState;
  Game_Battler.prototype.removeState = function (stateId) {
    _Game_Battler_removeState.apply(this, arguments);
    this.clearStateAccumulationsIfNeed();
    delete this._stateAccumulations[stateId];
  };

  const _Game_BattlerBase_attackStates =
    Game_BattlerBase.prototype.attackStates;
  Game_BattlerBase.prototype.attackStates = function (accumulateFlg) {
    if (arguments.length === 0) accumulateFlg = false;
    const states = _Game_BattlerBase_attackStates.apply(this, arguments);
    return states.filter(
      function (stateId) {
        return BattleManager.isStateAccumulate(stateId) === accumulateFlg;
      }.bind(this)
    );
  };

  Game_Battler.prototype.accumulateState = function (stateId, value) {
    this.clearStateAccumulationsIfNeed();
    if (BattleManager.isStateAccumulate(stateId)) {
      this._stateAccumulations[stateId] =
        (this._stateAccumulations[stateId] || 0) + value;
      if (
        !this.isStateAffected(stateId) &&
        this._stateAccumulations[stateId] >= 1.0
      ) {
        this.addState(stateId);
        this._stateImmunity[stateId] = (this._stateImmunity[stateId] || 0) + 1;
        return true;
      }
    }
    return false;
  };

  Game_BattlerBase.prototype.getStateImmunity = function (stateId) {
    return (this._stateImmunity[stateId] * param.ImmunityRate) / 100 || 0;
  };

  Game_BattlerBase.prototype.getStateAccumulation = function (stateId) {
    return this._stateAccumulations[stateId] || 0;
  };

  Game_BattlerBase.prototype.getGaugeStateAccumulation = function () {
    return this.getStateAccumulation(this.getGaugeStateId());
  };

  Game_BattlerBase.prototype.getGaugeX = function () {
    return this.getGaugeInfo(SceneManager.findAccumulateGaugeTagX());
  };

  Game_BattlerBase.prototype.getGaugeY = function () {
    return this.getGaugeInfo(SceneManager.findAccumulateGaugeTagY());
  };

  Game_BattlerBase.prototype.getGaugeStateId = function () {
    return this.getGaugeInfo(["蓄積ゲージステート", "AccumulateGaugeState"]);
  };

  Game_BattlerBase.prototype.getGaugeInfo = function (names) {
    return PluginManagerEx.findMetaValue(this.getData(), names);
  };

  Game_BattlerBase.prototype.getData = function () {
    return null;
  };

  Game_Actor.prototype.getData = function () {
    return this.actor();
  };

  Game_Enemy.prototype.getData = function () {
    return this.enemy();
  };

  SceneManager.findAccumulateGaugeTagX = function () {
    if (this._scene instanceof Scene_Map) {
      return ["蓄積マップゲージX", "AccumulateMapGaugeX"];
    }
    if (this._scene instanceof Scene_Status) {
      return ["蓄積ステータスゲージX", "AccumulateStatusGaugeX"];
    }
    return ["蓄積ゲージX", "AccumulateGaugeX"];
  };

  SceneManager.findAccumulateGaugeTagY = function () {
    if (this._scene instanceof Scene_Map) {
      return ["蓄積マップゲージY", "AccumulateMapGaugeY"];
    }
    if (this._scene instanceof Scene_Status) {
      return ["蓄積ステータスゲージY", "AccumulateStatusGaugeY"];
    }
    return ["蓄積ゲージY", "AccumulateGaugeY"];
  };

  //=============================================================================
  // Game_Action
  //  行動によってステート蓄積量を増やします。
  //=============================================================================
  const _Game_Action_itemEffectAddAttackState =
    Game_Action.prototype.itemEffectAddAttackState;
  Game_Action.prototype.itemEffectAddAttackState = function (target, effect) {
    _Game_Action_itemEffectAddAttackState.apply(this, arguments);
    this.subject()
      .attackStates(true)
      .forEach((stateId) => {
        let accumulation =
          effect.value1 * this.subject().attackStatesRate(stateId);
        accumulation = this.applyResistanceForAccumulateState(
          accumulation,
          target,
          stateId
        );
        const result = target.accumulateState(stateId, accumulation);
        if (result) this.makeSuccess(target);
      });
  };

  const _Game_Action_itemEffectAddNormalState =
    Game_Action.prototype.itemEffectAddNormalState;
  Game_Action.prototype.itemEffectAddNormalState = function (target, effect) {
    if (BattleManager.isStateAccumulate(effect.dataId)) {
      let accumulation = effect.value1;
      if (!this.isCertainHit() || !param.CertainHit) {
        accumulation = this.applyResistanceForAccumulateState(
          accumulation,
          target,
          effect.dataId
        );
      }
      const result = target.accumulateState(effect.dataId, accumulation);
      if (result) this.makeSuccess(target);
    } else {
      _Game_Action_itemEffectAddNormalState.apply(this, arguments);
    }
  };

  Game_Action.prototype.applyResistanceForAccumulateState = function (
    effectValue,
    target,
    stateId
  ) {
    if (param.AccumulateFormula) {
      const a = effectValue;
      const b = target.stateRate(stateId);
      try {
        effectValue = eval(param.AccumulateFormula);
      } catch (e) {
        SoundManager.playBuzzer();
        console.warn("Script Error : " + param.AccumulateFormula);
        console.warn(e.stack);
      }
    } else {
      effectValue *= target.stateRate(stateId);
    }
    if (param.LuckAdjust) {
      effectValue *= this.lukEffectRate(target);
    }
    effectValue *= 1.0 - target.getStateImmunity(stateId);
    return effectValue.clamp(0.0, 1.0);
  };

  //=============================================================================
  // BattleManager
  //  蓄積型のステートかどうかを判定します。
  //=============================================================================
  BattleManager.isStateAccumulate = function (stateId) {
    return (
      stateId > 0 &&
      !!PluginManagerEx.findMetaValue($dataStates[stateId], [
        "蓄積型",
        "Accumulate",
      ])
    );
  };

  //=============================================================================
  // Scene_Base
  //  ステートゲージを作成します。
  //=============================================================================
  Scene_Battle.prototype.createAccumulateState = function (detailMenu) {
    Scene_Base.prototype.createAccumulateState.call(this, detailMenu);
    for (let i = 0, n = $gameTroop.members().length; i < n; i++) {
      const sprite = new Sprite_AccumulateState(i, $gameTroop, false);
      this.addChild(sprite);
    }
  };

  Scene_Base.prototype.createAccumulateState = function (detailMenu) {
    for (let i = 0, n = $gameParty.members().length; i < n; i++) {
      const sprite = new Sprite_AccumulateState(i, $gameParty, detailMenu);
      this.addChild(sprite);
    }
  };

  const _Scene_Battle_createSpriteset = Scene_Battle.prototype.createSpriteset;
  Scene_Battle.prototype.createSpriteset = function () {
    _Scene_Battle_createSpriteset.apply(this, arguments);
    this.createAccumulateState(false);
  };

  const _Scene_Map_createSpriteset = Scene_Map.prototype.createSpriteset;
  Scene_Map.prototype.createSpriteset = function () {
    _Scene_Map_createSpriteset.apply(this, arguments);
    this.createAccumulateState(false);
  };

  const _Scene_Status_create = Scene_Status.prototype.create;
  Scene_Status.prototype.create = function () {
    _Scene_Status_create.apply(this, arguments);
    this.createAccumulateState(true);
  };

  //=============================================================================
  // Sprite_AccumulateState
  //  ステート蓄積表示用スプライトです。
  //=============================================================================
  function Sprite_AccumulateState() {
    this.initialize.apply(this, arguments);
  }

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

  Sprite_AccumulateState.prototype.initialize = function (
    index,
    unit,
    detailMenu
  ) {
    this._index = index;
    this._battler = null;
    this._unit = unit;
    this._rate = null;
    this._detailMenu = detailMenu;
    Sprite.prototype.initialize.call(this);
    this.create();
  };

  Sprite_AccumulateState.prototype.getBattler = function () {
    return this._unit.members()[this._index];
  };

  Sprite_AccumulateState.prototype.create = function () {
    this.bitmap = ImageManager.loadPicture(param.GaugeImage);
    this.createGaugeSprite();
    this.bitmap.addLoadListener(this.onLoadBitmap.bind(this));
    this.visible = false;
  };

  Sprite_AccumulateState.prototype.createGaugeSprite = function () {
    this._gaugeSprite = new Sprite();
    this._gaugeSprite.bitmap = this.bitmap;
    this.addChild(this._gaugeSprite);
  };

  Sprite_AccumulateState.prototype.onLoadBitmap = function () {
    const height = this.bitmap.height / 2;
    this.setFrame(0, height, this.bitmap.width, height);
    this._gaugeSprite.setFrame(0, 0, this.bitmap.width, height);
  };

  Sprite_AccumulateState.prototype.update = function () {
    const battler = this.getBattler();
    if (!battler) return;
    if (this._battler !== battler) {
      this._battler = battler;
    }
    this.updateVisibility();
    if (this.visible) {
      this.updatePosition();
      this.updateRate();
    }
  };

  Sprite_AccumulateState.prototype.updateVisibility = function () {
    this.visible = true;
    const stateId = this._battler.getGaugeStateId();
    if (!stateId) {
      this.visible = false;
    }
    if (param.GaugeSwitchId && !$gameSwitches.value(param.GaugeSwitchId)) {
      this.visible = false;
    }
    if (this._detailMenu && $gameParty.menuActor() !== this._battler) {
      this.visible = false;
    }
  };

  Sprite_AccumulateState.prototype.updateRate = function () {
    const rate = Math.min(this._battler.getGaugeStateAccumulation(), 1.0);
    if (rate !== this._rate) {
      this._rate = rate;
      this.bitmap.addLoadListener(
        function () {
          this._gaugeSprite.setFrame(
            0,
            0,
            this.bitmap.width * rate,
            this.bitmap.height / 2
          );
        }.bind(this)
      );
    }
  };

  Sprite_AccumulateState.prototype.updatePosition = function () {
    this.x = this._battler.getGaugeX();
    this.y = this._battler.getGaugeY();
  };
})();


code:
//=============================================================================
// RPG Maker MZ - Alternative Menu Screen
//=============================================================================

/*:
 * @target MZ
 * @plugindesc Alternative menu screen layout.
 * @author Yoji Ojima
 *
 * @help AltMenuScreen.js
 *
 * This plugin changes the layout of the menu screen.
 * It puts the commands on the top and the status on the bottom.
 *
 * It does not provide plugin commands.
 */

/*:ja
 * @target MZ
 * @plugindesc メニュー画面のレイアウトを変更します。
 * @author Yoji Ojima
 *
 * @help AltMenuScreen.js
 *
 * このプラグインは、メニュー画面のレイアウトを変更します。
 * コマンドを上側に、ステータスを下側に配置します。
 *
 * プラグインコマンドはありません。
 */

(() => {
  Scene_MenuBase.prototype.commandWindowHeight = function () {
    return this.calcWindowHeight(2, true);
  };

  Scene_MenuBase.prototype.goldWindowHeight = function () {
    return this.calcWindowHeight(1, true);
  };

  Scene_Menu.prototype.commandWindowRect = function () {
    const ww = Graphics.boxWidth;
    const wh = this.commandWindowHeight();
    const wx = 0;
    const wy = this.mainAreaTop();
    return new Rectangle(wx, wy, ww, wh);
  };

  Scene_Menu.prototype.statusWindowRect = function () {
    const h1 = this.commandWindowHeight();
    const h2 = this.goldWindowHeight();
    const ww = Graphics.boxWidth;
    const wh = this.mainAreaHeight() - h1 - h2;
    const wx = 0;
    const wy = this.mainAreaTop() + this.commandWindowHeight();
    return new Rectangle(wx, wy, ww, wh);
  };

  Scene_ItemBase.prototype.actorWindowRect = function () {
    const rect = Scene_Menu.prototype.statusWindowRect();
    rect.y = this.mainAreaBottom() - rect.height;
    return rect;
  };

  Window_MenuCommand.prototype.maxCols = function () {
    return 4;
  };

  Window_MenuCommand.prototype.numVisibleRows = function () {
    return 2;
  };

  Window_MenuStatus.prototype.maxCols = function () {
    return 4;
  };

  Window_MenuStatus.prototype.numVisibleRows = function () {
    return 1;
  };

  Window_MenuStatus.prototype.drawItemImage = function (index) {
    const actor = this.actor(index);
    const rect = this.itemRectWithPadding(index);
    const w = Math.min(rect.width, 144);
    const h = Math.min(rect.height, 144);
    const lineHeight = this.lineHeight();
    this.changePaintOpacity(actor.isBattleMember());
    this.drawActorFace(actor, rect.x, rect.y + lineHeight * 2, w, h);
    this.changePaintOpacity(true);
  };

  Window_MenuStatus.prototype.drawItemStatus = function (index) {
    const actor = this.actor(index);
    const rect = this.itemRectWithPadding(index);
    const x = rect.x;
    const y = rect.y;
    const width = rect.width;
    const bottom = y + rect.height;
    const lineHeight = this.lineHeight();
    this.drawActorName(actor, x, y + lineHeight * 0, width);
    this.drawActorLevel(actor, x, y + lineHeight * 1, width);
    this.drawActorClass(actor, x, bottom - lineHeight * 4, width);
    this.placeBasicGauges(actor, x, bottom - lineHeight * 3, width);
    this.drawActorIcons(actor, x, bottom - lineHeight * 1, width);
  };
})();


code:
//=============================================================================
// RPG Maker MZ - Alternative Save Screen
//=============================================================================

/*:
 * @target MZ
 * @plugindesc Alternative save/load screen layout.
 * @author Yoji Ojima
 *
 * @help AltSaveScreen.js
 *
 * This plugin changes the layout of the save/load screen.
 * It puts the file list on the top and the details on the bottom.
 *
 * It does not provide plugin commands.
 */

/*:ja
 * @target MZ
 * @plugindesc セーブ／ロード画面のレイアウトを変更します。
 * @author Yoji Ojima
 *
 * @help AltSaveScreen.js
 *
 * このプラグインは、セーブ／ロード画面のレイアウトを変更します。
 * ファイル一覧を上側に、詳細を下側に配置します。
 *
 * プラグインコマンドはありません。
 */

(() => {
  const _Scene_File_create = Scene_File.prototype.create;
  Scene_File.prototype.create = function () {
    _Scene_File_create.apply(this, arguments);
    this._listWindow.height = this._listWindow.fittingHeight(3);
    const x = 0;
    const y = this._listWindow.y + this._listWindow.height;
    const width = Graphics.boxWidth;
    const height = Graphics.boxHeight - y;
    const rect = new Rectangle(x, y, width, height);
    const statusWindow = new Window_SavefileStatus(rect);
    this._listWindow.mzkp_statusWindow = statusWindow;
    this.addWindow(statusWindow);
  };

  const _Scene_File_start = Scene_File.prototype.start;
  Scene_File.prototype.start = function () {
    _Scene_File_start.apply(this, arguments);
    this._listWindow.ensureCursorVisible();
    this._listWindow.callUpdateHelp();
  };

  Window_SavefileList.prototype.windowWidth = function () {
    return Graphics.boxWidth;
  };

  Window_SavefileList.prototype.maxCols = function () {
    return 4;
  };

  Window_SavefileList.prototype.itemHeight = function () {
    return this.lineHeight() * 2 + 16;
  };

  const _Window_SavefileList_callUpdateHelp =
    Window_SavefileList.prototype.callUpdateHelp;
  Window_SavefileList.prototype.callUpdateHelp = function () {
    _Window_SavefileList_callUpdateHelp.apply(this, arguments);
    if (this.active && this.mzkp_statusWindow) {
      this.mzkp_statusWindow.setSavefileId(this.savefileId());
    }
  };

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

  Window_SavefileStatus.prototype = Object.create(Window_Base.prototype);
  Window_SavefileStatus.prototype.constructor = Window_SavefileStatus;

  Window_SavefileStatus.prototype.initialize = function (rect) {
    Window_Base.prototype.initialize.call(this, rect);
    this._savefileId = 1;
  };

  Window_SavefileStatus.prototype.setSavefileId = function (id) {
    this._savefileId = id;
    this.refresh();
  };

  Window_SavefileStatus.prototype.refresh = function () {
    const info = DataManager.savefileInfo(this._savefileId);
    const rect = this.contents.rect;
    this.contents.clear();
    this.resetTextColor();
    this.drawTitle(this._savefileId, rect.x, rect.y);
    if (info) {
      this.drawContents(info, rect);
    }
  };

  Window_SavefileStatus.prototype.drawTitle = function (savefileId, x, y) {
    if (savefileId === 0) {
      this.drawText(TextManager.autosave, x, y, 180);
    } else {
      this.drawText(TextManager.file + " " + savefileId, x, y, 180);
    }
  };

  Window_SavefileStatus.prototype.drawContents = function (info, rect) {
    const bottom = rect.y + rect.height;
    const playtimeY = bottom - this.lineHeight();
    this.drawText(info.title, rect.x + 192, rect.y, rect.width - 192);
    this.drawPartyfaces(info.faces, rect.x, bottom - 144);
    this.drawText(info.playtime, rect.x, playtimeY, rect.width, "right");
  };

  Window_SavefileStatus.prototype.drawPartyfaces = function (faces, x, y) {
    if (faces) {
      for (let i = 0; i < faces.length; i++) {
        const data = faces[i];
        this.drawFace(data[0], data[1], x + i * 150, y);
      }
    }
  };
})();


code:
//=============================================================================
// AutoBattlePlus.js
//=============================================================================

/*:
 * @plugindesc add 'auto' and 'repeat' to battle party command
 * @author Sasuke KANNAZUKI (thx to tomoaky)
 *
 * @param Auto Command Name
 * @desc Command name of Auto
 * @default Auto
 *
 * @param Repeat Command Name
 * @desc Command name of Repeat
 * @default Repeat
 *
 * @help This plugin does not provide plugin commands.
 *
 * - Choose "Auto" to all actors determine automatically their actions
 *   at the turn.
 * - Choose "Repeat" to make actors the same action as the previous turn.
 *
 * note:
 * - At "Repeat" mode, when the actor cannot perform the same action
 * (ex. MP has run out), perform normal attack instead.
 * - When choose "Repeat" at first turn, let all actions be normal attack.
 *
 * copyright: this plugin is based on tomoaky's RGSS3 script material.
 * see "Hikimoki" http://hikimoki.sakura.ne.jp/
 * Thanks to tomoaky.
 *
 * This plugin is released under MIT license.
 * http://opensource.org/licenses/mit-license.php
 */

/*:ja
 * @plugindesc パーティコマンドに「自動戦闘」と「リピート」を追加します
 * @author 神無月サスケ (原案: tomoaky)
 *
 * @param Auto Command Name
 * @desc 自動戦闘のコマンド名です
 * @default 自動戦闘
 *
 * @param Repeat Command Name
 * @desc リピートのコマンド名です
 * @default リピート
 *
 * @help このプラグインには、プラグインコマンドはありません。
 *
 * - 「自動戦闘」を選ぶと、そのターンの間だけ全アクターが
 *   自動戦闘の状態になります。
 * - 「リピート」を選ぶと、全アクターが前のターンと同じ行動をとります。
 *
 * 注意:
 * - 前のターンと同じ行動がコスト不足などで実行できない場合は
 *   代わりに通常攻撃を行います。
 * - １ターン目にリピートを選択した場合は全アクターの行動が通常攻撃になります。
 * - 前ターン開始時に選択されている行動がリピート対象となります。、
 *   コスト不足などで行動内容が変化した場合、次ターン以降も変化したままです。
 *
 * 著作権表記:
 * このプラグインは、tomoaky氏のRGSS3素材をベースに作成しました。
 * Webサイト：ひきも記 http://hikimoki.sakura.ne.jp/
 * tomoaky氏に謝意を示します。
 *
 * このプラグインは MIT ライセンスで配布されます。
 * ご自由にお使いください。
 * http://opensource.org/licenses/mit-license.php
 */

(function () {
  //
  // process parameters
  //
  var parameters = PluginManager.parameters("AutoBattlePlus");
  var autoName = parameters["Auto Command Name"] || "Auto";
  var repeatName = parameters["Repeat Command Name"] || "Repeat";

  //
  // add commands and handlers
  //
  Window_PartyCommand.prototype.makeCommandList = function () {
    this.addCommand(TextManager.fight, "fight");
    this.addCommand(autoName, "auto");
    this.addCommand(repeatName, "repeat");
    this.addCommand(TextManager.escape, "escape", BattleManager.canEscape());
  };

  var _Scene_Battle_createPartyCommandWindow =
    Scene_Battle.prototype.createPartyCommandWindow;
  Scene_Battle.prototype.createPartyCommandWindow = function () {
    _Scene_Battle_createPartyCommandWindow.call(this);
    this._partyCommandWindow.setHandler("auto", this.commandAuto.bind(this));
    this._partyCommandWindow.setHandler(
      "repeat",
      this.commandRepeat.bind(this)
    );
  };

  //
  // handler functions
  //
  Scene_Battle.prototype.commandAuto = function () {
    $gameParty.members().forEach(function (actor) {
      if (actor.canMove() && actor._actionState === "undecided") {
        actor.makeAutoBattleActions();
      }
    });
    this.endCommandSelection();
    BattleManager.startTurn();
  };

  Scene_Battle.prototype.commandRepeat = function () {
    BattleManager.resumeCommandRecord();
    this.endCommandSelection();
    BattleManager.startTurn();
  };

  //
  // command record cotrol functions
  //
  var _BattleManager_initMembers = BattleManager.initMembers;
  BattleManager.initMembers = function () {
    _BattleManager_initMembers.call(this);
    this.resetCommandRecord();
  };

  var _BattleManager_startBattle = BattleManager.startBattle;
  BattleManager.startBattle = function () {
    _BattleManager_startBattle.call(this);
    this.resetCommandRecord();
  };

  var _BattleManager_startTurn = BattleManager.startTurn;
  BattleManager.startTurn = function () {
    this.setCommandRecord();
    _BattleManager_startTurn.call(this);
  };

  //
  // record command module
  //
  BattleManager.resetCommandRecord = function () {
    this._commandRecord = [];
  };

  BattleManager.setCommandRecord = function () {
    var actors = $gameParty.members();
    for (var i = 0; i < actors.length; i++) {
      if (actors[i].canMove()) {
        this._commandRecord[i] = actors[i]._actions.clone();
      }
    }
  };

  BattleManager.resumeCommandRecord = function () {
    var actors = $gameParty.members();
    for (var i = 0; i < actors.length; i++) {
      var actor = actors[i];
      if (!actor.canMove()) {
        actor.clearActions();
      }
      if (actor.canMove() && actor._actionState === "undecided") {
        var oldAct = this._commandRecord[i] || [];
        for (var j = 0; j < actor.numActions(); j++) {
          if (oldAct[j] && oldAct[j].isValid()) {
            actor._actions[j] = oldAct[j];
          } else {
            actor._actions[j].setAttack();
          }
        }
      }
    }
  };
})();


code:
/*=============================================================================
 BattleLogSpeed.js
----------------------------------------------------------------------------
 (C)2022 Triacontane
 This software is released under the MIT License.
 http://opensource.org/licenses/mit-license.php
----------------------------------------------------------------------------
 Version
 1.0.0 2022/08/22 初版
----------------------------------------------------------------------------
 [Blog]   : https://triacontane.blogspot.jp/
 [Twitter]: https://twitter.com/triacontane/
 [GitHub] : https://github.com/triacontane/
=============================================================================*/

/*:
 * @plugindesc バトルログ速度調整プラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/BattleLogSpeed.js
 * @base PluginCommonBase
 * @orderAfter PluginCommonBase
 * @author トリアコンタン
 *
 * @param speedVariable
 * @text 速度変数
 * @desc 指定した変数値をログメッセージスピード(フレーム数)として扱います。
 * @default 1
 * @type variable
 *
 * @help BattleLogSpeed.js
 *
 * バトルログのスピードを可変にできます。
 * パラメータからスピードを取得する変数番号を指定してください。
 * 変数値が0以下の場合は無効となり、デフォルト値(16)が採用されます。
 *
 * このプラグインの利用にはベースプラグイン『PluginCommonBase.js』が必要です。
 * 『PluginCommonBase.js』は、RPGツクールMZのインストールフォルダ配下の
 * 以下のフォルダに格納されています。
 * dlc/BasicResources/plugins/official
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(() => {
  "use strict";
  const script = document.currentScript;
  const param = PluginManagerEx.createParameter(script);

  const _Window_BattleLog_messageSpeed =
    Window_BattleLog.prototype.messageSpeed;
  Window_BattleLog.prototype.messageSpeed = function () {
    const defaultSpeed = _Window_BattleLog_messageSpeed.apply(this, arguments);
    const speed = $gameVariables.value(param.speedVariable);
    return speed > 0 ? speed : defaultSpeed;
  };
})();


code:
//=============================================================================
// RPG Maker MZ - Button Picture
//=============================================================================

/*:
 * @target MZ
 * @plugindesc Makes a picture clickable.
 * @author Yoji Ojima
 *
 * @help ButtonPicture.js
 *
 * This plugin provides a command to call a common event when a picture is
 * clicked.
 *
 * Use it in the following procedure.
 *   1. Execute "Show Picture" to display your button image.
 *   2. Call the plugin command "Set Button Picture".
 *
 * @command set
 * @text Set Button Picture
 * @desc Makes the specified picture clickable.
 *
 * @arg pictureId
 * @type number
 * @min 1
 * @max 100
 * @default 1
 * @text Picture Number
 * @desc Control number of the picture.
 *
 * @arg commonEventId
 * @type common_event
 * @default 1
 * @text Common Event
 * @desc Common event to call when the picture is clicked.
 */

/*:ja
 * @target MZ
 * @plugindesc ピクチャをクリック可能にします。
 * @author Yoji Ojima
 *
 * @help ButtonPicture.js
 *
 * このプラグインは、ピクチャのクリック時にコモンイベントを呼び出すコマンドを
 * 提供します。
 *
 * 次の手順で使用してください。
 *   1. 「ピクチャの表示」を実行して、ボタン画像を表示します。
 *   2. プラグインコマンド「ボタンピクチャの設定」を呼び出します。
 *
 * @command set
 * @text ボタンピクチャの設定
 * @desc 指定したピクチャをクリック可能にします。
 *
 * @arg pictureId
 * @type number
 * @min 1
 * @max 100
 * @default 1
 * @text ピクチャ番号
 * @desc ピクチャの管理番号です。
 *
 * @arg commonEventId
 * @type common_event
 * @default 1
 * @text コモンイベント
 * @desc ピクチャがクリックされた時に呼び出すコモンイベントです。
 */

(() => {
  const pluginName = "ButtonPicture";

  PluginManager.registerCommand(pluginName, "set", (args) => {
    const pictureId = Number(args.pictureId);
    const commonEventId = Number(args.commonEventId);
    const picture = $gameScreen.picture(pictureId);
    if (picture) {
      picture.mzkp_commonEventId = commonEventId;
    }
  });

  Sprite_Picture.prototype.isClickEnabled = function () {
    const picture = this.picture();
    return picture && picture.mzkp_commonEventId && !$gameMessage.isBusy();
  };

  Sprite_Picture.prototype.onClick = function () {
    $gameTemp.reserveCommonEvent(this.picture().mzkp_commonEventId);
  };

  Spriteset_Base.prototype.mzkp_isAnyPicturePressed = function () {
    return this._pictureContainer.children.some((sprite) => sprite.isPressed());
  };

  const _Scene_Map_isAnyButtonPressed = Scene_Map.prototype.isAnyButtonPressed;
  Scene_Map.prototype.isAnyButtonPressed = function () {
    return (
      _Scene_Map_isAnyButtonPressed.apply(this, arguments) ||
      this._spriteset.mzkp_isAnyPicturePressed()
    );
  };
})();


code:
/*
############################################
	作者: KOBRA
	営利・非営利・18禁問わず配布可、改造も可、報告不要
	積極的に配布して皆のゲーム開発を快適にしてあげて
	http://cobrara.blogspot.jp/
	https://twitter.com/onarinin_san
############################################
*/

/*:
 * @target MZ
 * @plugindesc エロステータスを追加します
 * @author
 *
 * @param SE
 * @text SE
 * @default Cursor3
 * @desc ページを変更した時のSE音を指定、デフォルト：Cursor3
 *
 * @param SEvol
 * @text SEボリューム
 * @type number
 * @default 100
 * @desc SE音の音量を指定、デフォルト：100
 *
 * @param window
 * @text ウィンドウの表示
 * @type boolean
 * @default true
 * @desc 背景としてウィンドウの枠を表示するかどうか
 *
 * @param font
 * @text フォント
 * @default
 * @desc Project\fontsにwoffファイルを入れ、ファイル名を記入してください
 *
 * @help エロステータスプラグイン ver 1.0.1
 *
 * イベントのスクリプトでエロステータス画面を作る事が可能に
 *
 *　～開く～
 *　イベントのスクリプトで
 *　SceneManager.push(Scene_EroStatus)
 *　とやるだけ
 *
 *　～設定～
 *  スクリプトで1行目に｢CBR-エロステータス｣と記入するとエロステータスのスクリプトを使うよーって合図に
 *
 *　～初期化～
 *　｢初期化-???｣　ALLと書くと前ページ初期化、数値だと指定したページのみ初期化
 *
 *　～データ入れる～
 * ｢ページ-???｣ 数値を入れると｢今からこのページにデータ入れるよー｣という合図を行います
 *
 * ～画像～
 * ※注※　必ず画像-????.png を2行目に持ってきてください
 *
 * ｢画像-??????.png｣って書くととpicturesフォルダに保存された画像を表示、\V[2]で変数2を使ったりも可能
 * ｢x-???｣　x座標を指定
 * ｢y-???｣　y座標
 * ｢透明度-???｣　書かなくてもいい、無かったら100になる　数値は0～100
 * ｢サイズ-???｣　書かなくてもいい、無かったら100になる　数値は0～
 *
 *
 * ～テキスト～
 * ※注※　必ず テキスト-??? を2行目に持ってきてください
 *
 * ｢テキスト-??????｣　\V[2]で変数3を表示したり\{でフォントを大きくしたりできます
 * ｢x-???｣　x座標を指定
 * ｢y-???｣　y座標
 * ｢左右-?｣ 書かなくてもいい、無かったら左になる　左、中、右でx座標の始点を指定
 * ｢上下-?｣ 書かなくてもいい、無かったら上になる　上、中、下で途中でフォントサイズ大きくした時の揃え方を指定
 * ｢サイズ-??｣　書かなくてもいい、無かったら28になる
 *
 *
 */

//(function(){

var CBR = CBR || {};
CBR.eroStatus = {
  event: 0,
  se: "Cursor3",
  seVol: 100,
  addPage: 0,
  pageNow: 0,
  window: 0,
  font: false,
  data: [],
};

if (!CBR_Game_Interpreter_command355) {
  var CBR_Game_Interpreter_command355 = Game_Interpreter.prototype.command355;
  Game_Interpreter.prototype.command355 = function () {
    //CBR-xxxの場合CBR.xxxにobjを渡す
    var key = this.currentCommand().parameters[0];
    if (key.match(/^CBR\-/)) {
      var obj = [];
      //下に続いてるスクリプトの取得
      while (this.nextEventCode() === 655) {
        this._index++;
        obj[obj.length] = this.currentCommand().parameters[0];
      }
      var temp = key.split("-");
      //CBR-×××があったら
      if (CBR[temp[1]]) {
        //下に続くデータを入れる
        CBR[temp[1]](obj);
      }
      //普通にスクリプト実行
    } else {
      CBR_Game_Interpreter_command355.call(this);
    }
    return true;
  };
}

CBR["エロステータス"] = function (ary) {
  //スクリプト毎に実行されるヤツ
  //全てのデータを格納しよう
  //変数の変換は開く時かなー
  var obj = {};
  for (var A of ary) {
    //A = A.replace(/\\V\[(\d+)\]/g,function(a,b){//汚いけどこれは毎回やらないとね
    //		return $gameVariables.value(b);//律儀にNumberしなくてもいいか
    //});
    var temp = A.split(/\-(.*)/, 2);

    switch (
      temp[0] //初期化とページ変更はここで終わる
    ) {
      case "初期化":
        if (temp[1] == "ALL") {
          CBR.eroStatus.data.length = 0;
        } else {
          delete CBR.eroStatus.data[Number(temp[1]) - 1];
        }
        return; //break;
      case "ページ":
        CBR.eroStatus.addPage = Number(temp[1]) - 1;
        return; //break;
      case "画像":
      case "テキスト":
        obj.val = temp[1];
        obj.type = temp[0];
        break;
      case "x":
      case "y":
      case "サイズ":
      case "左右":
      case "上下":
      case "透明度":
        obj[temp[0]] = temp[1];
        break;
      default:
        //console.log("なにこれ？"+temp[0]);
        return;
    }
  }
  CBR.eroStatus.data[CBR.eroStatus.addPage] = CBR.eroStatus.data[
    CBR.eroStatus.addPage
  ] || { 画像: [], テキスト: [] }; //ページがなかったら作る
  CBR.eroStatus.data[CBR.eroStatus.addPage][obj.type][
    CBR.eroStatus.data[CBR.eroStatus.addPage][obj.type].length
  ] = obj; //んで入れる
};

//まずstarted const boxMargin = 4;が原因でマージンができてしまう

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

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

Scene_EroStatus.prototype.initialize = function () {
  Scene_Base.prototype.initialize.call(this);
};
Scene_EroStatus.prototype.create = function () {
  Scene_Base.prototype.create.call(this);

  //data[{},{},,,]ってなってたら空の部分を削る
  var i = CBR.eroStatus.data.length - 1;
  while (CBR.eroStatus.data.length && i && !CBR.eroStatus.data[i]) {
    CBR.eroStatus.data.pop();
    i--;
  }

  //開いた時表示するページ
  CBR.eroStatus.pageNow = 0;
  var i = 0;
  while (CBR.eroStatus.data.length && !CBR.eroStatus.data[i]) {
    i++;
  }
  CBR.eroStatus.pageNow = i;

  var param = PluginManager.parameters("CBR_EroStatus");
  CBR.eroStatus.se = param["SE"] || 100;
  CBR.eroStatus.seVol = param["SEvol"] || 100;
  if (param["window"] == "true") {
    CBR.eroStatus.window = true;
  } else {
    CBR.eroStatus.window = false;
  }
  CBR.eroStatus.font = param["font"] || false;
  if (CBR.eroStatus.font) {
    if (
      FontManager._urls["rmmz-mainfont"] !=
      "fonts/" + CBR.eroStatus.font + ".woff"
    ) {
      FontManager._states["rmmz-mainfont"] = null;
      FontManager.load("rmmz-mainfont", CBR.eroStatus.font + ".woff");
    }
  }

  this.createBackground();
  this.createWindowLayer();
  this._windowLayer.x = 0;
  this._windowLayer.y = 0;
  this.createEroStatusWindow();
};
//今まで自力でロードフラグやってたけど今回は便利な物が、シーン.isReadyのおかげ
Scene_EroStatus.prototype.start = function () {
  Scene_MenuBase.prototype.start.call(this);
  this._eroStatusWindow.refresh();
};
Scene_EroStatus.prototype.createEroStatusWindow = function () {
  const rect = this.eroStatusWindowRect();
  this._eroStatusWindow = new Window_EroStatus(rect);
  this._eroStatusWindow.setHandler("cancel", this.popScene.bind(this));
  this.addWindow(this._eroStatusWindow);
};
Scene_EroStatus.prototype.eroStatusWindowRect = function () {
  const ww = Graphics.width;
  const wh = Graphics.height;
  const wx = 0;
  const wy = 0;
  return new Rectangle(wx, wy, ww, wh);
};
Scene_EroStatus.prototype.update = function () {
  Scene_Base.prototype.update.call(this);
};
Scene_EroStatus.prototype.createBackground = function () {
  this._backgroundFilter = new PIXI.filters.BlurFilter();
  this._backgroundSprite = new Sprite();
  this._backgroundSprite.bitmap = SceneManager.backgroundBitmap();
  //なんか黒いフチが右下だけっていうのが気に入らないので四方に
  this._backgroundFilter.autoFit = false;

  this._backgroundSprite.filters = [this._backgroundFilter];
  this.addChild(this._backgroundSprite);
  this.setBackgroundOpacity(192);
};
Scene_EroStatus.prototype.setBackgroundOpacity = function (opacity) {
  this._backgroundSprite.opacity = opacity;
};
Scene_EroStatus.prototype.popScene = function () {
  FontManager._states["rmmz-mainfont"] = null;
  FontManager.load("rmmz-mainfont", $dataSystem.advanced.mainFontFilename);
  SceneManager.pop();
};

//ウィンドウ
function Window_EroStatus() {
  this.initialize(...arguments);
}

Window_EroStatus.prototype = Object.create(Window_Selectable.prototype);
Window_EroStatus.prototype.constructor = Window_EroStatus;

Window_EroStatus.prototype.initialize = function (rect) {
  Window_Selectable.prototype.initialize.call(this, rect);
  this._CBR_drawn = false;
  this.refresh();
};
Window_EroStatus.prototype.itemPadding = function () {
  return 0;
};
Window_EroStatus.prototype.updatePadding = function () {
  this.padding = 0;
};

Window_EroStatus.prototype.colSpacing = function () {
  return 0;
};
Window_EroStatus.prototype.rowSpacing = function () {
  return 0;
};

Window_EroStatus.prototype.update = function () {
  Window_Selectable.prototype.update.call(this);

  if (
    CBR.eroStatus.data.length !== 1 &&
    ImageManager.isReady() &&
    FontManager.isReady()
  ) {
    //読み込み終わってたら、結局画像読み終えてない限りリフレッシュする必要なし
    var pn = CBR.eroStatus.pageNow;
    var n;
    if (Input.isRepeated("right")) {
      for (var i = 1, len = CBR.eroStatus.data.length; i < len; i++) {
        n = i + pn;
        if (len <= i + pn) {
          n -= len;
        }
        if (CBR.eroStatus.data[n]) {
          break;
        }
      }
    } else if (Input.isRepeated("left")) {
      for (var i = 1, len = CBR.eroStatus.data.length; i < len; i++) {
        n = pn - i;
        if (n < 0) {
          n += len;
        }
        if (CBR.eroStatus.data[n]) {
          break;
        }
      }
    }
    if (
      n !== undefined &&
      CBR.eroStatus.pageNow != n &&
      CBR.eroStatus.data[n]
    ) {
      //ページの変更だったら
      CBR.eroStatus.pageNow = n;
      AudioManager.playSe({
        name: CBR.eroStatus.se,
        volume: CBR.eroStatus.seVol,
        pitch: 100,
        pan: 0,
      });
      this._CBR_drawn = false;
      this.refresh();
    } else if (!this._CBR_drawn) {
      //画像が読み込まれてるというのに描写されて無い時
      this.refresh();
    }
  }
};

Window_EroStatus.prototype.refresh = function () {
  const rect = this.itemLineRect(0);
  const x = rect.x;
  const y = rect.y;
  const width = rect.width;
  this.contents.clear();

  var test = CBR.eroStatus.data[CBR.eroStatus.pageNow]; //このページの画像&&テキスト
  if (!test) {
    return;
  }
  for (var obj of test["画像"]) {
    var val = obj.val.replace(/\\V\[(\d+)\]/g, function (a, b) {
      return $gameVariables.value(b);
    });
    const bitmap = ImageManager.loadPicture(val.slice(0, -4));

    const pw = bitmap.width;
    const ph = bitmap.height;
    var top = 0;
    var left = 0;
    if (obj["左右"] == "中") {
      left -= pw / 2;
    } else if (obj["左右"] == "右") {
      left -= pw;
    }
    if (obj["上下"] == "中") {
      top -= ph / 2;
    } else if (obj["上下"] == "下") {
      top -= ph;
    }
    if (obj["透明度"]) {
      this.contents.paintOpacity = (255 * Number(obj["透明度"])) / 100;
    }
    var zoom = 1;
    if (obj["サイズ"]) {
      zoom = Number(obj["サイズ"]) / 100;
    }
    this.contents.blt(
      bitmap,
      0,
      0,
      pw,
      ph,
      Number(obj.x) + left,
      Number(obj.y) + top,
      pw * zoom,
      ph * zoom
    );
    this.contents.paintOpacity = 255;
  }

  //画像読み込み全部終わってなかったら終了
  if (!ImageManager.isReady()) {
    return;
  }

  for (var obj of test["テキスト"]) {
    //まず変数や値を変換
    var text = obj.val.replace(
      /\\(\\)|\\([VNP])\[(\d+)\]|\\(<)(.+)\\>/g,
      function (a, b, c, d, e, f) {
        if (b) {
          //\\
          return "\\";
        } else if (c) {
          //[VNP]
          d = Number(d);
          switch (c) {
            case "V":
              return $gameVariables.value(d);
              break;
            case "N":
              return $gameActors._data[d]._name;
              break;
            case "P":
              return $dataActors[$gameParty._actors[d - 1]].name;
              break;
          }
        } else {
          //script
          return eval(f);
        }
      }
    );

    this.contents.context.font = this.contents._makeFontNameText();
    this.contents.fontSize =
      Number(obj["サイズ"]) || $gameSystem.mainFontSize();
    this.resetTextColor();

    const reg = RegExp(/\\([CI])\[(\d+)\]|\\\{|\\\}/, "g");
    var ary;
    var c = 0;
    var left = 0;

    var strAry = []; //分割された文字列いれる
    var wAry = []; //分割された横幅いれる
    var fAry = []; //分割ごとの操作を入れる

    var ii = 0;
    var strWidth = 0;
    var maxH = this.contents.fontSize;
    //テキストのwidthや分割集め
    while ((ary = reg.exec(text)) !== null) {
      var str = text.substring(c, ary.index); //描写したい部分を抜き出す
      strAry[ii] = str;
      wAry[ii] = this.textWidth(str);
      strWidth += wAry[ii];

      switch (ary[1]) {
        case undefined: //{や}の時
          if (ary[0].substring(1) == "{") {
            fAry[ii] = { type: "{" };
            this.contents.fontSize += 6;
            if (maxH < this.contents.fontSize) {
              maxH = this.contents.fontSize;
            }
          } else {
            fAry[ii] = { type: "}" };
            this.contents.fontSize -= 6;
          }
          break;
        default:
          fAry[ii] = { type: ary[1], val: ary[2] };
          break;
      }

      c = reg.lastIndex;
      ii++;
    }
    if (c != text.length) {
      var str = text.substring(c); //描写したい部分を抜き出す
      strAry[ii] = str;
      fAry[ii] = { type: false, val: false };
      wAry[ii] = this.textWidth(str);
      strWidth += wAry[ii];
      ii++;
    }

    this.contents.context.font = this.contents._makeFontNameText();
    this.contents.fontSize =
      Number(obj["サイズ"]) || $gameSystem.mainFontSize();

    var left = 0;
    var top = 0;
    if (obj["左右"] == "中") {
      left -= strWidth / 2;
    } else if (obj["左右"] == "右") {
      left -= strWidth;
    }
    for (var i = 0; i < ii; i++) {
      var top = 0;
      if (obj["上下"] == "中") {
        top = maxH / 2 - this.contents.fontSize / 2;
      } else if (obj["上下"] == "下") {
        top = maxH - this.contents.fontSize;
      }
      this.drawText(
        strAry[i],
        Number(obj.x) + left,
        Number(obj.y) + top,
        wAry[i],
        this.contents.fontSize,
        "right"
      );
      left += wAry[i];
      switch (fAry[i].type) {
        case "C":
          this.changeTextColor(ColorManager.textColor(fAry[i].val)); //カラチェン
          break;
        case "I":
          //return $gameActors._data[d]._name;
          break;
        case "{":
          this.contents.fontSize += 6;
          break;
        case "}":
          this.contents.fontSize -= 6;
          break;
      }
    }

    this.resetTextColor();
    this.contents.fontSize = $gameSystem.mainFontSize();
    this._CBR_drawn = true;
  }
};
//window.drawTextだとlineHeightが36に固定されちゃうので変える
Window_EroStatus.prototype.drawText = function (
  text,
  x,
  y,
  maxWidth,
  h,
  align
) {
  this.contents.drawText(text, x, y, maxWidth, h, align);
};

Window_EroStatus.prototype.open = function () {
  this.refresh();
  Window_Selectable.prototype.open.call(this);
};
//アクティブじゃなくてもキャンセルできるように
Window_EroStatus.prototype.processHandling = function () {
  if (this.isCancelEnabled() && this.isCancelTriggered()) {
    return this.processCancel();
  }
};
Window_EroStatus.prototype.loadWindowskin = function () {
  if (CBR.eroStatus.window) {
    this.windowskin = ImageManager.loadSystem("Window");
  } else {
    return;
  }
};


code:
//=============================================================================
// CharacterFreeze.js
// ----------------------------------------------------------------------------
// (C)2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.1.1 2020/11/05 変数の宣言誤りを修正
// 2.1.0 2020/11/05 並列処理のマップイベント実行も停止できる機能を追加
// 2.0.2 2020/10/10 MZ版としてリファクタリング。一部機能を削減
// 2.0.1 2020/10/10 簡易的な英語ヘルプを整備
// 2.0.0 2020/10/10 パラメータ構造を変更
//                  停止時にアニメーションも停止できる機能を追加
// 1.1.1 2020/07/19 停止スイッチをONにした直後に戦闘を開始しかつ逃走した場合、もともと演奏していたBGMが再生されない問題を修正
// 1.1.0 2017/03/03 停止中にピクチャを表示する機能、BGMの音量を変化する機能を追加
// 1.0.0 2017/03/01 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc CharacterFreeze
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/CharacterFreeze.js
 * @base PluginCommonBase
 * @author triacontane
 *
 * @param freezeSwitchId
 * @desc This is the switch ID that triggers a full stop of the character.
 * @default
 * @type switch
 *
 * @param freezePictureId
 * @desc This is the picture number for displaying the picture when it is stopped.
 * @default 0
 * @type number
 *
 * @param freezePictureName
 * @desc The name of the picture file to be displayed when stopped.
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param freezePictureX
 * @desc X-coordinate of the picture to be displayed while stopped.
 * @default 0
 * @type number
 * @min -2000
 *
 * @param freezePictureY
 * @desc The Y-coordinate of the picture to be displayed while stopped.
 * @default 0
 * @type number
 * @min -2000
 *
 * @param freezePictureOpacity
 * @desc The opacity of the picture to be displayed while stopped.
 * @default 255
 * @max 255
 * @type number
 *
 * @param freezePictureBlendMode
 * @desc This is a method of composing a picture to be displayed while stopped.
 * @default 0
 * @type select
 * @option 0
 * @option 1
 * @option 2
 * @option 3
 *
 * @param freezeBgmVolume
 * @desc This is the ratio of the BGM volume when the music is stopped. It will be multiplied by the original volume.
 * @default 100
 * @type number
 *
 * @param freezeParallelMapEvent
 * @desc When stopped, parallel map events processing are stopped at the same time.
 * @default false
 * @type boolean
 *
 * @help All autonomous movement and animation of events will be stopped.
 * At the same time, the player will not be able to move.
 * Turning the switch ON will stop the event, and turning it OFF will restart it.
 *
 * Also, while the game is stopped, a special picture can be displayed and
 * the volume of the BGM can be adjusted.
 */
/*:ja
 * @plugindesc キャラクター停止プラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/CharacterFreeze.js
 * @base PluginCommonBase
 * @author トリアコンタン
 *
 * @param freezeSwitchId
 * @text 停止スイッチID
 * @desc キャラクターを全停止させるトリガーになるスイッチIDです。
 * @default
 * @type switch
 *
 * @param freezePictureId
 * @text 停止中ピクチャID
 * @desc 停止中にピクチャを表示する場合のピクチャ番号です。
 * @default 0
 * @type number
 *
 * @param freezePictureName
 * @text 停止中ピクチャ名
 * @desc 停止中に表示するピクチャファイル名です。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param freezePictureX
 * @text 停止中ピクチャX座標
 * @desc 停止中に表示するピクチャのX座標です。
 * @default 0
 * @type number
 * @min -2000
 *
 * @param freezePictureY
 * @text 停止中ピクチャY座標
 * @desc 停止中に表示するピクチャのY座標です。
 * @default 0
 * @type number
 * @min -2000
 *
 * @param freezePictureOpacity
 * @text 停止中ピクチャ不透明度
 * @desc 停止中に表示するピクチャの不透明度です。
 * @default 255
 * @max 255
 * @type number
 *
 * @param freezePictureBlendMode
 * @text 停止中ピクチャ合成方法
 * @desc 停止中に表示するピクチャの合成方法です。
 * @default 0
 * @type select
 * @option 通常
 * @value 0
 * @option 加算
 * @value 1
 * @option 乗算
 * @value 2
 * @option スクリーン
 * @value 3
 *
 * @param freezeBgmVolume
 * @text 停止中BGM音量
 * @desc 停止中のBGM音量の倍率です。もとの音量に対して乗算されます。
 * @default 100
 * @type number
 *
 * @param freezeParallelMapEvent
 * @text 並列マップイベント停止
 * @desc 停止中、並列処理のマップイベントも実行も同時に停止します。
 * @default false
 * @type boolean
 *
 * @help イベントの自律移動とアニメーションを全停止します。
 * 同時にプレイヤーも動けなくなります。
 * パラメータで指定したスイッチをONにすると停止、OFFにすると再開します。
 *
 * また停止中に専用のピクチャを表示したり、BGMの音量を調整したりできます。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";
  const script = document.currentScript;
  const param = PluginManagerEx.createParameter(script);

  //=============================================================================
  // Game_Map
  //  フリーズ時に専用のピクチャを表示します。
  //=============================================================================
  const _Game_Map_update = Game_Map.prototype.update;
  Game_Map.prototype.update = function (sceneActive) {
    _Game_Map_update.apply(this, arguments);
    this.updateFreeze();
  };

  Game_Map.prototype.updateFreeze = function () {
    if (this.isFreeze() && !this._lastFreeze) {
      this.startFreeze();
    }
    if (!this.isFreeze() && this._lastFreeze) {
      this.finishFreeze();
    }
    this._lastFreeze = this.isFreeze();
  };

  Game_Map.prototype.startFreeze = function () {
    if (param.freezePictureId) {
      this.showFreezePicture();
    }
    if (param.freezeBgmVolume) {
      let oldBgm = AudioManager.saveBgm();
      if (SceneManager.isNextScene(Scene_Battle)) {
        oldBgm = BattleManager._mapBgm;
      }
      const freezeVolume = (oldBgm.volume * param.freezeBgmVolume) / 100;
      const freezeBgm = {
        name: oldBgm.name,
        volume: freezeVolume,
        pitch: oldBgm.pitch,
        pan: oldBgm.pan,
      };
      if (SceneManager.isNextScene(Scene_Battle)) {
        BattleManager._mapBgm = freezeBgm;
      } else {
        AudioManager.playBgm(freezeBgm);
      }
      this._preFreezeVolume = oldBgm.volume;
    }
  };

  Game_Map.prototype.showFreezePicture = function () {
    const id = param.freezePictureId;
    const name = param.freezePictureName;
    const x = param.freezePictureX || 0;
    const y = param.freezePictureY || 0;
    const opacity = param.freezePictureOpacity || 255;
    const blendName = param.freezePictureBlendMode;
    $gameScreen.showPicture(id, name, 0, x, y, 100, 100, opacity, blendName);
  };

  Game_Map.prototype.finishFreeze = function () {
    if (param.freezePictureId) {
      $gameScreen.erasePicture(param.freezePictureId);
    }
    if (param.freezeBgmVolume) {
      const bgm = AudioManager.saveBgm();
      bgm.volume = this._preFreezeVolume;
      AudioManager.playBgm(bgm);
      this._preFreezeVolume = null;
    }
  };

  Game_Map.prototype.isFreeze = function () {
    return $gameSwitches.value(param.freezeSwitchId);
  };

  var _Game_Event_updateParallel = Game_Event.prototype.updateParallel;
  Game_Event.prototype.updateParallel = function () {
    if (param.freezeParallelMapEvent && this.isFreeze()) {
      return;
    }
    _Game_Event_updateParallel.apply(this, arguments);
  };

  //=============================================================================
  // Game_CharacterBase
  //  フリーズ時にイベントとプレイヤーの動きを止めます。
  //=============================================================================
  Game_CharacterBase.prototype.isFreeze = function () {
    return $gameMap.isFreeze();
  };

  const _Game_CharacterBase_update = Game_CharacterBase.prototype.update;
  Game_CharacterBase.prototype.update = function () {
    if (this.isFreeze()) return;
    _Game_CharacterBase_update.apply(this, arguments);
  };

  const _Game_Player_canMove = Game_Player.prototype.canMove;
  Game_Player.prototype.canMove = function () {
    return !this.isFreeze() && _Game_Player_canMove.apply(this, arguments);
  };
})();


code:
//=============================================================================
// CharacterGraphicExtend.js
// ----------------------------------------------------------------------------
// (C)2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.4.1 2022/01/30 色相を変化させたとき入力した数値を反転させた内容が反映されてしまう問題を修正
// 2.4.0 2021/07/12 敵キャラやピクチャを表示する際、色相を指定できる機能を追加
// 2.3.2 2021/07/07 ヘルプの記載ミスを修正
// 2.3.1 2021/06/24 プラグイン未適用のデータをロードしたときに発生するいくつかの事象を修正
// 2.3.0 2021/05/18 プライオリティ設定に「-1」(下層タイルの背後で遠景の手前)を設定できるようにしました
// 2.2.1 2021/05/05 アイコンセットの行を変更したときに正しくトリミングできない問題を修正
// 2.2.0 2021/02/22 色調変更のタグが正常に機能していなかった問題を修正し、グレースケールを指定できるようにしました。
// 2.1.1 2020/11/28 Trb_SimpleDashMotion.jsと併用したとき、プレイヤーの拡大率を変更したときも想定通りに表示されるよう修正
// 2.1.0 2020/11/22 ApngPicture.jsと組み合わせてキャラクターとして表示したピクチャ、敵キャラ画像がアニメーションする機能を追加
// 2.0.1 2020/11/01 一部リファクタリング
// 2.0.0 2020/10/30 MZで動作するよう全面的に修正
// 1.10.4 2020/03/22 MOG_ChronoEngine.jsとの間で発生するエラーを解消(全面的な競合対策ではありません)
//                   MOG_CharPoses.jsとの競合を解消
// 1.10.3 2020/01/25 フレーム更新時に無駄な処理が実行されることでパフォーマンスが低下していた問題を修正
// 1.10.2 2018/11/19 UltraMode7との競合を解消(by けんせい様)
//                   TMNamePop.jsとの併用時、ネームポップがイベント画像の傾き、反転に影響されないよう修正
// 1.10.1 2018/10/05 敵キャラやピクチャを表示する際、エディタで元画像にインデックス1以外を指定していると画像が表示されない問題を修正
// 1.10.0 2018/09/25 イベント画像をトリミングして表示できる機能を追加
// 1.9.2 2018/07/11 EventEffects.jsとの競合を解消
// 1.9.1 2018/06/05 メモ欄タグで変数指定＋並列処理で変数操作にて発生するいくつかの問題を修正（by 奏ねこま様）
// 1.9.0 2018/02/20 不透明度をメモ欄で設定できる機能を追加
// 1.8.0 2017/08/27 マップで使用しているタイルセット以外のタイルセットを使ったイベントを作成できる機能を追加
// 1.7.0 2017/08/24 画像を別のものに変更するスクリプトを追加
// 1.6.1 2017/08/06 ヘルプを修正
// 1.6.0 2017/08/05 アクターのバトラー画像をマップ上に表示する機能を追加
// 1.5.3 2017/06/22 プラグインを適用していないデータをロードしたときにプレイヤーが表示されない問題を修正
// 1.5.2 2017/06/11 プライオリティの設定を0にすると設定が有効にならない問題を修正
// 1.5.1 2017/06/11 GALV_CamControl.jsとの競合を解消
// 1.5.0 2017/03/28 色調変更機能を追加
// 1.4.2 2017/02/03 メモ欄に制御文字\v[n]を使った場合に、一度マップ移動しないと反映されない問題を修正しました。
// 1.4.1 2016/11/27 T_dashMotion.jsとの競合を解決
// 1.4.0 2016/11/21 複数のページに対して別々の画像を割り当てる機能を追加しました。
// 1.3.0 2016/07/16 以下の機能を追加しました。
//                  遠景をイベントグラフィックとして利用可能
//                  イベント画像の原点を変更する機能、イベント画像の画面表示位置を絶対値指定する機能
// 1.2.1 2016/05/08 HalfMove.jsとの競合を解消
// 1.2.0 2016/03/19 戦闘発生時にイベントを消去しない設定を追加しました。
// 1.1.2 2016/03/04 本体バージョン1.1.0に合わせてキャラクターの乗算とスクリーンに対応しました。
// 1.1.1 2016/01/21 競合対策（YEP_MessageCore.js）
// 1.1.0 2016/01/11 キャラクターに回転角を設定する機能を追加
//                  移動ルートの指定のスクリプトから、回転角、拡大率、位置調整ができる機能を追加
// 1.0.0 2016/01/08 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc キャラクターグラフィック表示拡張プラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/CharacterGraphicExtend.js
 * @base PluginCommonBase
 * @author トリアコンタン
 *
 * @param EventHideInvalid
 * @text イベント消去無効
 * @desc エンカウント発生時にイベントを一瞬消去するエフェクトを無効にします。
 * @default false
 * @type boolean
 *
 * @help イベントのグラフィック表示方法を拡張して多彩な表現を可能にします。
 * イベントのメモ欄に所定の書式で記入してください。
 * 項目はカンマで区切ってください。文章の表示と同じ制御文字が使用できます。
 * また、ページ数に「A」と入力すると全てのページが対象になります。
 *
 * <CGピクチャ:（ページ数）,（ファイル名）>
 * 指定したページが有効になった場合のグラフィックをピクチャ画像から取得します。
 * 拡張子は不要です。歩行アニメ待機アニメは無効化されます。
 *
 * ファイル名には公式プラグイン「MaterialBase.js」の
 * 制御文字「\mi[aaa]」が使用できます。
 *
 * 例：<CGピクチャ:1,Test> or <CGPicture:1,Test>
 *
 * 〇追加機能
 * 複数のページに対して別々の画像を割り当てたい場合は
 * ページごとにタグを作成してください。
 * 以下の例だと1ページ目ではaaa.pngが、2ページ目ではbbb.pngが使用されます。
 * 他のタグも同様です。
 * 例：<CGピクチャ:1,aaa><CGピクチャ:2,bbb>
 *
 * <CG敵キャラ:（ページ数）,（ファイル名）,（色相）>
 * 指定したページが有効になった場合のグラフィックを敵キャラ画像から取得します。
 * 拡張子は不要です。歩行アニメ待機アニメは無効化されます。
 *
 * 例：<CG敵キャラ:1,Bat,90> or <CGEnemy:1,Bat,90>
 *
 * <CGアイコン:（ページ数）,（インデックス）>
 * 指定したページが有効になった場合のグラフィックをアイコン画像から取得します。
 * 歩行アニメ待機アニメは無効化されます。
 *
 * 例：<CGアイコン:1,128> or <CGIcon:1,128>
 *
 * <CGフェイス:（ページ数）,（ファイル名）,（インデックス）>
 * 指定したページが有効になった場合のグラフィックをフェイス画像から取得します。
 * 拡張子は不要です。歩行アニメ待機アニメは無効化されます。
 *
 * 例：<CGフェイス:1,Actor1,4> or <CGFace:1,Actor1,4>
 *
 * <CGアクター:（ページ数）,（ファイル名）,（インデックス）>
 * 指定したページが有効になった場合のグラフィックをバトラー画像から取得します。
 * 拡張子は不要です。歩行アニメ待機アニメは無効化されます。
 *
 * 例：<CGアクター:1, Actor1_1, 0> or <CGActor:1, Actor1_1, 0>
 *
 * <CG遠景:（ページ数）,（ファイル名）>
 * 指定したページが有効になった場合のグラフィックを遠景画像から取得します。
 * 拡張子は不要です。歩行アニメ待機アニメは無効化されます。
 *
 * 例：<CG遠景:1,Test> or <CGParallax:1,Test>
 *
 * 要注意！　これらのメモ欄でファイルを指定した場合、デプロイメント時に
 * 未使用ファイルとして除外される可能性があります。
 * その場合、削除されたファイルを入れ直す等の対応が必要です。
 *
 * <CGタイル:（ページ数）,（横幅）,（高さ）>
 * 指定したページが有効になった場合のグラフィックをタイル画像から取得します。
 * 横幅と高さを指定して本棚やベッドが一つのイベントで表現できます。
 * イベントの画像選択から一番左上のタイルを選択してください。
 *
 * 例：<CGタイル:1,2,2> or <CGTile:1,2,2>
 *
 * <CGタイルセット:（ページ数）,（タイルセットID）>
 * 指定したページが有効になった場合のタイルセットを指定します。
 * マップで使用しているタイルセット以外のタイルセット画像が使えます。
 *
 * 例：<CGタイルセット:1,2> or <CGTileset:1,2>
 *
 * <CGシフト:（ページ数）,（X座標）,（Y座標）>
 * 指定したページが有効になった場合のグラフィック表示位置を
 * 指定したピクセル分ずらして表示します。
 *
 * 例：<CGシフト:1,16,-16> or <CGShift:1,16,-16>
 *
 * <CGプライオリティ:（ページ数）,（プライオリティ）>
 * 指定したページが有効になった場合の表示優先度を設定します。
 * 1～9までの値を設定できます。
 *
 * 例：<CGプライオリティ:1,6> or <CGPriority:1,6>
 *
 * ※それぞれのプライオリティの値
 * 0 : 下層タイル
 * 1 : 通常キャラの下
 * 3 : 通常キャラと同じ
 * 4 : 上層タイル
 * 5 : 通常キャラの上
 * 6 : 飛行船の影
 * 7 : フキダシ
 * 8 : アニメーション
 * 9 : マップタッチの行き先（白く光るヤツ）
 *
 * <CG合成方法:（ページ数）,（合成方法）>
 * 指定したページが有効になった場合のグラフィックの合成方法を設定します。
 * 0:通常 1:加算 2:乗算 3:スクリーン
 *
 * 例：<CG合成方法:1,2> or <CGBlendType:1,2>
 *
 * <CG拡大率:（ページ数）,（X拡大率）（Y拡大率）>
 * 指定したページが有効になった場合のグラフィックの拡大率を設定します。
 * 負の値を設定すると画像が反転します。
 *
 * 例：<CG拡大率:1,100,-100> or <CGScale:1,100,-100>
 *
 * <CG回転角:（ページ数）,（回転角）>
 * 指定したページが有効になった場合のグラフィックの回転角を設定します。
 * 回転の中心は、キャラクターの足下になります。0～360の範囲内で設定してください。
 *
 * 例：<CG回転角:1,180> or <CGAngle:1,180>
 *
 * <CG原点:（ページ数）,（X原点）,（Y原点）>
 * 指定したページが有効になった場合のグラフィックの原点(0...100)を設定します。
 * デフォルトではX原点が50、Y原点が100(画像の足下が原点になる)です。
 *
 * 例：<CG原点:1,0,0> or <CGOrigin:1,100,100>
 *
 * <CG絶対座標:（ページ数）,（X座標）,（Y座標）>
 * 指定したページが有効になった場合のグラフィック表示位置を
 * 絶対座標(ピクチャのようにマップのスクロールとは無関係に表示する)にします。
 * ただし、イベントそのものの位置は変わりません。
 *
 * 例：<CG絶対座標:1,16,-16> or <CGAbsolute:1,16,-16>
 *
 * <CG色調:（ページ数）,（R値）,（G値）,（B値）,（グレースケール）>
 * 指定したページが有効になった場合の色調(-255～255)を設定します。
 * グレースケールは省略可能で、省略すると0になります。
 *
 * 例：<CG色調:1,-255,0,255,0> or <CGTone:1,-255,0,255,0>
 *
 * <CG不透明度:（ページ数）,（合成方法）>
 * 指定したページが有効になった場合のグラフィックの不透明度を設定します。
 * 0:透明 - 255:不透明
 *
 * 例：<CG不透明度:1,64> or <CGOpacity:1,64>
 *
 * <CGトリミング:（ページ数）,（X座標）,（Y座標）,（横幅）,（縦幅）>
 * 画像を指定した矩形でトリミングして表示します。
 *
 * 例：<CGトリミング:1,0,0,24,24> or <CGトリミング:1,0,0,24,24>
 *
 * 〇スクリプト（高度な設定。移動ルートの指定からスクリプトで実行）
 *
 * ・拡大率の設定
 * this.setScale(（X座標）,（Y座標）);
 * 例：this.setScale(100, 100);
 *
 * ・回転角の設定
 * this.setAngle(（回転角）);
 * 例：this.setAngle(180);
 *
 * ・ピクセル単位位置の設定
 * this.shiftPosition(（X座標）,（Y座標）);
 * 例：this.shiftPosition(24, 24);
 *
 * ・色調の設定
 * this.setTone(（R値）,（G値）,（B値）, （グレースケール）);
 * 例：this.setTone(255, -255, -255, 0);
 *
 * ・画像の変更
 * this.changeImage(（新しいファイル名）, （インデックス）);
 * 例：this.changeImage('Package1', 3);
 *
 * ※1 画像種別(ピクチャ⇒遠景など)を変更することはできません。
 * ※2 インデックスの指定を省略した場合、変更前の値が維持されます。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * EventEffects.jsと併用する場合は、本プラグインを下に配置してください。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
(function () {
  "use strict";

  const script = document.currentScript;
  const param = PluginManagerEx.createParameter(script);

  const getArgArrayString = function (args, upperFlg) {
    const values = getArgString(args, upperFlg).split(",");
    for (let i = 0; i < values.length; i++) values[i] = values[i].trim();
    return values;
  };

  const getArgString = function (args, upperFlg) {
    args = PluginManagerEx.convertEscapeCharacters(args);
    return upperFlg ? args.toUpperCase() : args;
  };

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

  //=============================================================================
  // Game_CharacterBase
  //  拡張するプロパティを定義します。
  //=============================================================================
  const _DataManager_extractMetadata = DataManager.extractMetadata;
  DataManager.extractMetadata = function (data) {
    _DataManager_extractMetadata.apply(this, arguments);
    this.extractMetadataArray(data);
  };

  DataManager.extractMetadataArray = function (data) {
    const re = /<([^<>:]+)(:?)([^>]*)>/g;
    data.metaArray = {};
    let match = true;
    while (match) {
      match = re.exec(data.note);
      if (match) {
        const metaName = match[1];
        data.metaArray[metaName] = data.metaArray[metaName] || [];
        data.metaArray[metaName].push(match[2] === ":" ? match[3] : true);
      }
    }
  };

  //=============================================================================
  // Game_System
  //  ロード時にプレイヤーの初期化が必要な場合は初期化します。
  //=============================================================================
  const _Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
  Game_System.prototype.onAfterLoad = function () {
    _Game_System_onAfterLoad.apply(this, arguments);
    if (!$gamePlayer.hasOwnProperty("_customResource")) {
      $gamePlayer.clearCgInfo();
      $gamePlayer
        .followers()
        .data()
        .forEach((follower) => follower.clearCgInfo());
      $gameMap.vehicles().forEach((vehicle) => vehicle.clearCgInfo());
    }
  };

  //=============================================================================
  // Game_CharacterBase
  //  拡張するプロパティを定義します。
  //=============================================================================
  const _Game_CharacterBase_initMembers =
    Game_CharacterBase.prototype.initMembers;
  Game_CharacterBase.prototype.initMembers = function () {
    _Game_CharacterBase_initMembers.apply(this, arguments);
    this.clearCgInfo();
  };

  Game_CharacterBase.prototype.clearCgInfo = function () {
    this._customResource = null;
    this._graphicColumns = 1;
    this._graphicRows = 1;
    this._additionalX = 0;
    this._additionalY = 0;
    this._customPriority = null;
    this._scaleX = 100;
    this._scaleY = 100;
    this._tileBlockWidth = 1;
    this._tileBlockHeight = 1;
    this._angle = 0;
    this._originX = null;
    this._originY = null;
    this._absoluteX = null;
    this._absoluteY = null;
    this._customTilesetId = 0;
    this._graphicHue = 0;
    this.setBlendMode(0);
  };

  Game_CharacterBase.prototype.customResource = function () {
    return this._customResource;
  };

  Game_CharacterBase.prototype.customResourceHue = function () {
    return this._graphicHue;
  };

  Game_CharacterBase.prototype.customTilesetId = function () {
    return this._customTilesetId;
  };

  Game_CharacterBase.prototype.graphicColumns = function () {
    return this._graphicColumns;
  };

  Game_CharacterBase.prototype.graphicRows = function () {
    return this._graphicRows;
  };

  Game_CharacterBase.prototype.scaleX = function () {
    return this._scaleX;
  };

  Game_CharacterBase.prototype.scaleY = function () {
    return this._scaleY;
  };

  Game_CharacterBase.prototype.setScale = function (x, y) {
    this._scaleX = x;
    this._scaleY = y;
  };

  Game_CharacterBase.prototype.originX = function () {
    return this._originX;
  };

  Game_CharacterBase.prototype.originY = function () {
    return this._originY;
  };

  Game_CharacterBase.prototype.setOrigin = function (x, y) {
    this._originX = x / 100;
    this._originY = y / 100;
  };

  Game_CharacterBase.prototype.absoluteX = function () {
    return this._absoluteX;
  };

  Game_CharacterBase.prototype.absoluteY = function () {
    return this._absoluteY;
  };

  Game_CharacterBase.prototype.setAbsolute = function (x, y) {
    this._absoluteX = x;
    this._absoluteY = y;
  };

  Game_CharacterBase.prototype.tone = function () {
    return this._tone;
  };

  Game_CharacterBase.prototype.setTone = function (r, g, b, gray) {
    this._tone = [r, g, b, gray || 0];
  };

  Game_CharacterBase.prototype.angle = function () {
    return this._angle;
  };

  Game_CharacterBase.prototype.setAngle = function (angle) {
    this._angle = angle;
  };

  Game_CharacterBase.prototype.shiftPosition = function (x, y) {
    this._additionalX = x;
    this._additionalY = y;
  };

  Game_CharacterBase.prototype.tileBlockWidth = function () {
    return this._tileBlockWidth;
  };

  Game_CharacterBase.prototype.tileBlockHeight = function () {
    return this._tileBlockHeight;
  };

  Game_CharacterBase.prototype.getTrimRect = function () {
    return this._trimRect || null;
  };

  const _Game_CharacterBase_pos = Game_CharacterBase.prototype.pos;
  Game_CharacterBase.prototype.pos = function (x, y) {
    if (this.tileBlockWidth() >= 2) {
      return (
        this._x - this.tileBlockWidth() / 2 <= x &&
        this._x + this.tileBlockWidth() / 2 >= x &&
        this._y === y
      );
    } else {
      return _Game_CharacterBase_pos.apply(this, arguments);
    }
  };

  const _Game_CharacterBase_screenX = Game_CharacterBase.prototype.screenX;
  Game_CharacterBase.prototype.screenX = function () {
    return this._absoluteX > 0
      ? this.absoluteX()
      : _Game_CharacterBase_screenX.apply(this, arguments) + this._additionalX;
  };

  const _Game_CharacterBase_screenY = Game_CharacterBase.prototype.screenY;
  Game_CharacterBase.prototype.screenY = function () {
    return this._absoluteY > 0
      ? this.absoluteY()
      : _Game_CharacterBase_screenY.apply(this, arguments) + this._additionalY;
  };

  const _Game_CharacterBase_screenZ = Game_CharacterBase.prototype.screenZ;
  Game_CharacterBase.prototype.screenZ = function () {
    return this._customPriority !== null
      ? this._customPriority
      : _Game_CharacterBase_screenZ.apply(this, arguments);
  };

  Game_CharacterBase.prototype.changeImage = function (fileName, fileIndex) {
    if (arguments.length < 2) {
      fileIndex = this._characterIndex;
    }
    Game_CharacterBase.prototype.setImage.call(this, fileName, fileIndex);
  };

  //=============================================================================
  // Game_Event
  //  拡張するプロパティを定義します。
  //=============================================================================
  Game_Event.blendModeParams = {
    1: 1,
    加算: 1,
    2: 2,
    乗算: 2,
    3: 3,
    スクリーン: 3,
  };

  Game_Event.prototype.getMetaCg = function (names) {
    if (!this.event().metaArray) {
      return null;
    }
    if (!Array.isArray(names)) names = [names];
    const metaParams = this.getMetaParameter(names);
    if (!metaParams) return null;
    let result = null;
    metaParams.some(
      function (metaParam) {
        const params = getArgArrayString(metaParam);
        if (this.isValidCgeParam(params)) {
          result = params;
          if (metaParam.match(/\\v/gi)) {
            this._graphicDynamic = true;
          }
        }
        return result;
      }.bind(this)
    );
    return result;
  };

  Game_Event.prototype.getMetaParameter = function (names) {
    let metaParams = null;
    names.some(
      function (name) {
        if (!metaParams || metaParams[0] === "") {
          metaParams = this.event().metaArray["CG" + name];
        }
        return metaParams;
      }.bind(this)
    );
    return metaParams;
  };

  Game_Event.prototype.isValidCgeParam = function (params) {
    const pageIndex = getArgNumber(params[0]);
    return (
      params.length > 1 &&
      (pageIndex === this._pageIndex + 1 || params[0].toUpperCase() === "A")
    );
  };

  const _Game_Event_refresh = Game_Event.prototype.refresh;
  Game_Event.prototype.refresh = function () {
    // added by nekoma start
    const moveRoute = this._moveRoute;
    const moveRouteIndex = this._moveRouteIndex;
    const moveRouteForcing = this._moveRouteForcing;
    const starting = this._starting;
    // added by nekoma end
    if (this._graphicDynamic) {
      this._pageIndex = -1;
    }
    _Game_Event_refresh.apply(this, arguments);
    // added by nekoma start
    if (this._graphicDynamic) {
      this._moveRoute = moveRoute;
      this._moveRouteIndex = moveRouteIndex;
      this._moveRouteForcing = moveRouteForcing;
      this._starting = starting;
    }
    // added by nekoma end
  };

  const _Game_Event_setupPageSettings = Game_Event.prototype.setupPageSettings;
  Game_Event.prototype.setupPageSettings = function () {
    this.clearCgInfo();
    _Game_Event_setupPageSettings.apply(this, arguments);
    let cgParams = this.getMetaCg(["シフト", "Shift"]);
    if (cgParams) {
      this.shiftPosition(getArgNumber(cgParams[1]), getArgNumber(cgParams[2]));
    }
    cgParams = this.getMetaCg(["プライオリティ", "Priority"]);
    if (cgParams) {
      this._customPriority = getArgNumber(cgParams[1]);
    }
    cgParams = this.getMetaCg(["合成方法", "BlendType"]);
    if (cgParams) {
      const blendMode = Game_Event.blendModeParams[cgParams[1]] || 0;
      this.setBlendMode(blendMode);
    }
    cgParams = this.getMetaCg(["拡大率", "Scale"]);
    if (cgParams) {
      this._scaleX = getArgNumber(cgParams[1]);
      this._scaleY = getArgNumber(cgParams[2]);
    }
    cgParams = this.getMetaCg(["回転角", "Angle"]);
    if (cgParams) {
      this.setAngle(getArgNumber(cgParams[1], 0, 360));
    }
    cgParams = this.getMetaCg(["原点", "Origin"]);
    if (cgParams) {
      this.setOrigin(getArgNumber(cgParams[1]), getArgNumber(cgParams[2]));
    }
    cgParams = this.getMetaCg(["絶対座標", "Absolute"]);
    if (cgParams) {
      this.setAbsolute(getArgNumber(cgParams[1]), getArgNumber(cgParams[2]));
    }
    cgParams = this.getMetaCg(["色調", "Tone"]);
    if (cgParams) {
      this.setTone(
        getArgNumber(cgParams[1]),
        getArgNumber(cgParams[2]),
        getArgNumber(cgParams[3]),
        getArgNumber(cgParams[4])
      );
    }
    cgParams = this.getMetaCg(["不透明度", "Opacity"]);
    if (cgParams) {
      this.setOpacity(getArgNumber(cgParams[1]));
    }
    cgParams = this.getMetaCg(["トリミング", "Trimming"]);
    if (cgParams) {
      this._trimRect = new Rectangle(
        getArgNumber(cgParams[1]),
        getArgNumber(cgParams[2]),
        getArgNumber(cgParams[3]),
        getArgNumber(cgParams[4])
      );
    }
  };

  const _Game_Event_setTileImage = Game_Event.prototype.setTileImage;
  Game_Event.prototype.setTileImage = function (tileId) {
    _Game_Event_setTileImage.apply(this, arguments);
    let cgParams = this.getMetaCg(["タイル", "Tile"]);
    if (cgParams) {
      this._tileBlockWidth = getArgNumber(cgParams[1]);
      this._tileBlockHeight = getArgNumber(cgParams[2]);
    }
    cgParams = this.getMetaCg(["タイルセット", "Tileset"]);
    if (cgParams) {
      this._customTilesetId = getArgNumber(cgParams[1]);
    }
  };

  const _Game_Event_setImage = Game_Event.prototype.setImage;
  Game_Event.prototype.setImage = function (characterName, characterIndex) {
    this._graphicHue = 0;
    let cgParams = this.getMetaCg(["ピクチャ", "Picture"]);
    if (cgParams) {
      this._customResource = "Picture";
      this._graphicColumns = 1;
      this._graphicRows = 1;
      this._graphicHue = getArgNumber(cgParams[2]);
      arguments[0] = cgParams[1];
      arguments[1] = 0;
    }
    cgParams = this.getMetaCg(["敵キャラ", "Enemy"]);
    if (cgParams) {
      this._customResource = $gameSystem.isSideView() ? "SvEnemy" : "Enemy";
      this._graphicColumns = 1;
      this._graphicRows = 1;
      this._graphicHue = getArgNumber(cgParams[2]);
      arguments[0] = cgParams[1];
      arguments[1] = 0;
    }
    cgParams = this.getMetaCg(["アイコン", "Icon"]);
    if (cgParams) {
      const bitmap = ImageManager.loadSystem("IconSet");
      this._customResource = "System";
      this._graphicColumns = 16;
      this._graphicRows = bitmap.height / ImageManager.iconHeight || 20;
      arguments[0] = "IconSet";
      arguments[1] = getArgNumber(
        cgParams[1],
        0,
        this._graphicColumns * this._graphicRows - 1
      );
    }
    cgParams = this.getMetaCg(["フェイス", "Face"]);
    if (cgParams) {
      this._customResource = "Face";
      this._graphicColumns = 4;
      this._graphicRows = 2;
      this._graphicHue = getArgNumber(cgParams[3]);
      arguments[0] = cgParams[1];
      arguments[1] = getArgNumber(
        cgParams[2],
        0,
        this._graphicColumns * this._graphicRows - 1
      );
    }
    cgParams = this.getMetaCg(["遠景", "Parallax"]);
    if (cgParams) {
      this._customResource = "Parallax";
      this._graphicColumns = 1;
      this._graphicRows = 1;
      this._graphicHue = getArgNumber(cgParams[2]);
      arguments[0] = cgParams[1];
      arguments[1] = 0;
    }
    cgParams = this.getMetaCg(["アクター", "Actor"]);
    if (cgParams) {
      this._customResource = "SvActor";
      this._graphicColumns = 9;
      this._graphicRows = 6;
      this._graphicHue = getArgNumber(cgParams[3]);
      arguments[0] = cgParams[1];
      arguments[1] = getArgNumber(
        cgParams[2],
        0,
        this._graphicColumns * this._graphicRows - 1
      );
    }
    _Game_Event_setImage.apply(this, arguments);
  };

  //=============================================================================
  // Spriteset_Map
  //  イベントを消去するエフェクトを無効にします。
  //=============================================================================
  const _Spriteset_Map_hideCharacters = Spriteset_Map.prototype.hideCharacters;
  Spriteset_Map.prototype.hideCharacters = function () {
    if (!param.EventHideInvalid)
      _Spriteset_Map_hideCharacters.apply(this, arguments);
  };

  //=============================================================================
  // Sprite_Character
  //  拡張したプロパティに基づいてエフェクトを反映させます。
  //=============================================================================
  const _Sprite_Character_initMembers = Sprite_Character.prototype.initMembers;
  Sprite_Character.prototype.initMembers = function () {
    _Sprite_Character_initMembers.apply(this, arguments);
    this._customTilesetId = 0;
  };

  const _Sprite_Character_tilesetBitmap =
    Sprite_Character.prototype.tilesetBitmap;
  Sprite_Character.prototype.tilesetBitmap = function (tileId) {
    this._customTilesetId = this._character.customTilesetId();
    const tileSet = $dataTilesets[this._customTilesetId];
    if (this._customTilesetId && tileSet) {
      const setNumber = 5 + Math.floor(tileId / 256);
      return ImageManager.loadTileset(tileSet.tilesetNames[setNumber]);
    } else {
      return _Sprite_Character_tilesetBitmap.apply(this, arguments);
    }
  };

  const _Sprite_Character_updateBitmap =
    Sprite_Character.prototype.updateBitmap;
  Sprite_Character.prototype.updateBitmap = function () {
    if (this.isImageChanged())
      this._customResource = this._character.customResource();
    _Sprite_Character_updateBitmap.apply(this, arguments);
    this.updateExtend();
  };

  // Resolve conflict for MOG_CharPoses.js
  const _Sprite_Character_setBitmapCache =
    Sprite_Character.prototype.setBitmapCache;
  Sprite_Character.prototype.setBitmapCache = function () {
    if (this._customResource) {
      return;
    }
    _Sprite_Character_setBitmapCache.apply(this, arguments);
  };

  const _Sprite_Character_update = Sprite_Character.prototype.update;
  Sprite_Character.prototype.update = function () {
    _Sprite_Character_update.apply(this, arguments);
    // for T_dashMotion.js
    if (this.updateDashMotion) {
      this.resolveConflictForDashMotion();
    }

    // for UltraMode7.jp PRTN added ----
    if ($gameMap.useUltraMode7) {
      this.resolveConflictForUltraMode7();
    }
  };

  // PRTN added ---------
  Sprite_Character.prototype.resolveConflictForUltraMode7 = function () {
    if (this._character.scaleY() !== 100) {
      this.scale.x = (this._character.scaleX() / 100) * this.scale.x;
      this.scale.y = (this._character.scaleY() / 100) * this.scale.y;
    }
    if (this._character.angle() !== 0) {
      const angle = (this._character.angle() * Math.PI) / 180;
      if (this.rotation !== angle) this.rotation = angle;
    }
  };
  // --------------------

  Sprite_Character.prototype.resolveConflictForDashMotion = function () {
    if (this._character.scaleY() / 100 !== this.scale.y) {
      this.scale.y = (this._character.scaleY() / 100) * this.scale.y;
    }
    if (this._character.angle() !== 0) {
      const angle = (this._character.angle() * Math.PI) / 180;
      if (this.rotation !== angle) this.rotation = angle;
    }
  };

  Sprite_Character.prototype.updateExtend = function () {
    const scaleX = this._character.scaleX() / 100;
    const scaleY = this._character.scaleY() / 100;
    this.scale.x = scaleX;
    this.scale.y = scaleY;
    // for TMNamePop.js
    if (this._namePop && this._namePopSprite) {
      this._namePopSprite.scale.x = scaleX;
      this._namePopSprite.scale.y = scaleY;
    }
    const originX = this._character.originX();
    if (originX != null) this.anchor.x = originX;
    const originY = this._character.originY();
    if (originY != null) this.anchor.y = originY;
    const angle = (this._character.angle() * Math.PI) / 180;
    if (this.rotation !== angle) this.rotation = angle;
    const tone = this._character.tone();
    if (tone) this.setColorTone(tone);
  };

  // Resolve conflict by EventEffects.js
  const _Sprite_Character_updateAngle = Sprite_Character.prototype.updateAngle;
  Sprite_Character.prototype.updateAngle = function () {
    if (this._character.originY() != null) {
      return;
    }
    _Sprite_Character_updateAngle.apply(this, arguments);
  };

  const _Sprite_Character_setFrame = Sprite_Character.prototype.setFrame;
  Sprite_Character.prototype.setFrame = function (sx, sy, pw, ph) {
    const rect = this._character.getTrimRect();
    if (rect) {
      _Sprite_Character_setFrame.call(
        this,
        sx + rect.x,
        sy + rect.y,
        rect.width,
        rect.height
      );
    } else {
      _Sprite_Character_setFrame.call(
        this,
        sx,
        sy,
        pw * this._character.tileBlockWidth(),
        ph * this._character.tileBlockHeight()
      );
    }
  };

  const _Sprite_Character_isImageChanged =
    Sprite_Character.prototype.isImageChanged;
  Sprite_Character.prototype.isImageChanged = function () {
    return (
      _Sprite_Character_isImageChanged.apply(this, arguments) ||
      this.isCustomImageChanged()
    );
  };

  Sprite_Character.prototype.isCustomImageChanged = function () {
    return (
      this._customResource !== this._character.customResource() ||
      this._customTilesetId !== this._character.customTilesetId()
    );
  };

  const _Sprite_Character_setCharacterBitmap =
    Sprite_Character.prototype.setCharacterBitmap;
  Sprite_Character.prototype.setCharacterBitmap = function () {
    if (this._customResource) {
      const hue = this._character.customResourceHue() || 0;
      this.bitmap = ImageManager["load" + this._customResource](
        this._characterName
      );
      if (hue > 0) {
        this.setHue(hue);
      }
    } else {
      _Sprite_Character_setCharacterBitmap.apply(this, arguments);
    }
  };

  const _Sprite_Character_characterBlockX =
    Sprite_Character.prototype.characterBlockX;
  Sprite_Character.prototype.characterBlockX = function () {
    if (this._customResource) {
      return this._characterIndex % this._character.graphicColumns();
    } else {
      return _Sprite_Character_characterBlockX.apply(this, arguments);
    }
  };

  const _Sprite_Character_characterBlockY =
    Sprite_Character.prototype.characterBlockY;
  Sprite_Character.prototype.characterBlockY = function () {
    if (this._customResource) {
      return Math.floor(
        this._characterIndex / this._character.graphicColumns()
      );
    } else {
      return _Sprite_Character_characterBlockY.apply(this, arguments);
    }
  };

  const _Sprite_Character_patternWidth =
    Sprite_Character.prototype.patternWidth;
  Sprite_Character.prototype.patternWidth = function () {
    if (this._customResource) {
      return this.bitmap.width / this._character.graphicColumns();
    } else {
      return _Sprite_Character_patternWidth.apply(this, arguments);
    }
  };

  const _Sprite_Character_patternHeight =
    Sprite_Character.prototype.patternHeight;
  Sprite_Character.prototype.patternHeight = function () {
    if (this._customResource) {
      return this.bitmap.height / this._character.graphicRows();
    } else {
      return _Sprite_Character_patternHeight.apply(this, arguments);
    }
  };

  const _Sprite_Character_characterPatternX =
    Sprite_Character.prototype.characterPatternX;
  Sprite_Character.prototype.characterPatternX = function () {
    if (this._customResource) {
      return 0;
    } else {
      return _Sprite_Character_characterPatternX.apply(this, arguments);
    }
  };

  const _Sprite_Character_characterPatternY =
    Sprite_Character.prototype.characterPatternY;
  Sprite_Character.prototype.characterPatternY = function () {
    if (this._customResource) {
      return 0;
    } else {
      return _Sprite_Character_characterPatternY.apply(this, arguments);
    }
  };

  // for ApngPicture.js
  var _Sprite_Character_setCharacterBitmap2 =
    Sprite_Character.prototype.setCharacterBitmap;
  Sprite_Character.prototype.setCharacterBitmap = function () {
    _Sprite_Character_setCharacterBitmap2.apply(this, arguments);
    if (this.addApngChild) {
      this.addApngChild(this._characterName);
    }
  };

  Sprite_Character.prototype.loadApngSprite = function (name) {
    switch (this._customResource) {
      case "Picture":
        return SceneManager.tryLoadApngPicture(name);
      case "SvEnemy":
        return SceneManager.tryLoadApngSideEnemy(name);
      case "Enemy":
        return SceneManager.tryLoadApngEnemy(name);
      default:
        return null;
    }
  };

  var _Scene_Base_terminate = Scene_Base.prototype.terminate;
  Scene_Base.prototype.terminate = function () {
    _Scene_Base_terminate.apply(this, arguments);
    if (this._spriteset && this._spriteset.destroyApngCharacter) {
      this._spriteset.destroyApngCharacter();
    }
  };

  Spriteset_Map.prototype.destroyApngCharacter = function () {
    this._characterSprites.forEach(function (sprite) {
      if (sprite.destroyApngIfNeed) {
        sprite.destroyApngIfNeed();
      }
    });
  };
})();