code:
//=============================================================================
// CustomizeConfigItem.js
// ----------------------------------------------------------------------------
// (C) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.4.0 2023/02/16 スクリプトで現在の設定値を取得できるよう修正
// 2.3.0 2021/12/21 項目に余白を設定できる機能を追加
// 2.2.1 2021/08/05 セーブがある状態で隠し項目を追加した時に上手く動作しない問題を修正(by柊菜緒さま)
// 2.2.0 2021/03/09 スクリプトが指定されているときに項目決定すると決定SEを演奏するよう修正
// 2.1.2 2020/10/13 Mano_InputConfig.jsと併用したとき、項目を末尾以外に追加すると表示不整合が発生する競合を修正
// 2.1.0 2017/12/15 追加項目のデフォルト項目を含めた並び順を自由に設定できる機能を追加
//                  項目名称を日本語化
// 2.0.1 2017/10/15 2.0.0の修正によりスイッチ項目を有効にしたときにゲーム開始するとエラーになる問題を修正
// 2.0.0 2017/09/10 ツクールの型指定機能に対応し、各オプション項目を任意の数だけ追加できる機能を追加
// 1.2.3 2017/06/08 1.2.2の修正により起動できなくなっていた問題を修正
// 1.2.2 2017/05/27 競合の可能性のある記述（Objectクラスへのプロパティ追加）をリファクタリング
// 1.2.1 2016/12/08 1.2.0の機能追加以降、デフォルト項目で決定ボタンを押すとエラーになっていた現象を修正
// 1.2.0 2016/12/02 各項目で決定ボタンを押したときに実行されるスクリプトを設定できる機能を追加
// 1.1.1 2016/08/14 スイッチ項目、音量項目の初期値が無効になっていた問題を修正
// 1.1.0 2016/04/29 項目をクリックしたときに項目値が循環するよう修正
// 1.0.0 2016/01/17 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc オプション任意項目作成プラグイン
 * @author トリアコンタン
 *
 * @param 数値項目
 * @desc 追加する数値項目のオプション項目情報です。
 * @default
 * @type struct<NumberData>[]
 *
 * @param 文字項目
 * @desc 追加する文字項目のオプション項目情報です。
 * @default
 * @type struct<StringData>[]
 *
 * @param スイッチ項目
 * @desc 追加するスイッチ項目のオプション項目情報です。
 * @default
 * @type struct<BooleanData>[]
 *
 * @param 音量項目
 * @desc 追加する音量項目のオプション項目情報です。
 * @default
 * @type struct<VolumeData>[]
 *
 * @help オプション画面に任意の項目を追加します。
 * 項目の種類は、以下の四種類があります。
 * 不要な項目は値を空に設定してください。
 *
 * ・スイッチ項目：
 * ON/OFFを選択する項目です。指定した番号のスイッチと値が同期されます。
 * オプションから値を設定すれば、それがスイッチに反映され、
 * スイッチを変更すれば、オプションの値に反映されます。
 * さらに、値はセーブデータ間で共有されます。
 * 隠しフラグを設定すると、オプション画面に表示されなくなります。
 * ゲームを進めないと出現しない項目などに利用できます。
 * 隠しフラグはプラグインコマンドから解除できます。
 *
 * スクリプトは上級者向け項目です。対象にカーソルを合わせて決定ボタンを
 * 押下すると指定したJavaScriptを実行できます。
 * 主に専用の設定画面などの遷移に使用します。
 *
 * ・数値項目：
 * 数値を選択する項目です。指定した番号の変数と値が同期されます。
 * スイッチ項目で指定した内容に加えて、
 * 最小値と最大値および一回の入力で変化する値を指定します。
 *
 * ・音量項目：
 * 音量を選択する項目です。BGMボリュームなどと同じ仕様で
 * キャラクターごとのボイス音量等に使ってください。
 *
 * ・文字項目：
 * 文字を選択する項目です。指定した文字の配列から項目を選択します。
 * 選択した文字のインデックス(開始位置は0)が変数に設定されます。
 * 初期値に設定する値もインデックスです。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 *  CC_UNLOCK or
 *  オプション任意項目の隠し解除 [項目名]
 *  　指定した項目の隠しフラグを解除します。
 *  使用例：CC_UNLOCK 数値項目1
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~NumberData:
 * @param Name
 * @text 項目名称
 * @desc 項目の名称です。
 * @default 数値項目1
 *
 * @param DefaultValue
 * @text 初期値
 * @desc 項目の初期値です。
 * @default 0
 * @type number
 *
 * @param VariableID
 * @text 変数番号
 * @desc 項目の設定内容が格納される変数番号です。
 * @default 0
 * @type variable
 *
 * @param HiddenFlag
 * @text 隠しフラグ
 * @desc 項目がデフォルトで隠されるようになります。プラグインコマンドの実行で表示されます。
 * @default false
 * @type boolean
 *
 * @param Script
 * @text スクリプト
 * @desc 項目を決定したときに実行されるスクリプトです。
 * @default
 *
 * @param NumberMin
 * @text 最小値
 * @desc 項目の最小値です。
 * @default 0
 * @type number
 *
 * @param NumberMax
 * @text 最大値
 * @desc 項目の最大値です。
 * @default 100
 * @type number
 *
 * @param NumberStep
 * @text 変化値
 * @desc 項目を操作したときの数値の変化量です。
 * @default 20
 * @type number
 *
 * @param AddPosition
 * @text 追加位置
 * @desc 項目を追加する位置です。指定した項目の上に追加されます。
 * @default
 * @type select
 * @option 末尾に追加
 * @value
 * @option 常時ダッシュ
 * @value alwaysDash
 * @option コマンド記憶
 * @value commandRemember
 * @option BGM 音量
 * @value bgmVolume
 * @option BGS 音量
 * @value bgsVolume
 * @option ME 音量
 * @value meVolume
 * @option SE 音量
 * @value seVolume
 *
 * @param PaddingTop
 * @text 余白
 * @desc 項目の上の余白ピクセル数です。項目の間隔を開けたいときに指定します。
 * @default 0
 * @type number
 */
/*~struct~BooleanData:
 * @param Name
 * @text 項目名称
 * @desc 項目の名称です。
 * @default スイッチ項目1
 *
 * @param DefaultValue
 * @text 初期値
 * @desc 項目の初期値です。
 * @default false
 * @type boolean
 *
 * @param SwitchID
 * @text スイッチ番号
 * @desc 項目の設定内容が格納されるスイッチ番号です。
 * @default 0
 * @type switch
 *
 * @param HiddenFlag
 * @text 隠しフラグ
 * @desc 項目がデフォルトで隠されるようになります。プラグインコマンドの実行で表示されます。
 * @default false
 * @type boolean
 *
 * @param Script
 * @text スクリプト
 * @desc 項目を決定したときに実行されるスクリプトです。
 * @default
 *
 * @param AddPosition
 * @text 追加位置
 * @desc 項目を追加する位置です。指定した項目の上に追加されます。
 * @default
 * @type select
 * @option 末尾に追加
 * @value
 * @option 常時ダッシュ
 * @value alwaysDash
 * @option コマンド記憶
 * @value commandRemember
 * @option BGM 音量
 * @value bgmVolume
 * @option BGS 音量
 * @value bgsVolume
 * @option ME 音量
 * @value meVolume
 * @option SE 音量
 * @value seVolume
 *
 * @param PaddingTop
 * @text 余白
 * @desc 項目の上の余白ピクセル数です。項目の間隔を開けたいときに指定します。
 * @default 0
 * @type number
 */
/*~struct~StringData:
 * @param Name
 * @text 項目名称
 * @desc 項目の名称です。
 * @default 文字列項目1
 *
 * @param DefaultValue
 * @text 初期値
 * @desc 項目の初期値です。インデックスの数値を指定します。
 * @default 0
 * @type number
 *
 * @param VariableID
 * @text 変数番号
 * @desc 項目の設定内容が格納される変数番号です。
 * @default 0
 * @type variable
 *
 * @param HiddenFlag
 * @text 隠しフラグ
 * @desc 項目がデフォルトで隠されるようになります。プラグインコマンドの実行で表示されます。
 * @default false
 * @type boolean
 *
 * @param Script
 * @text スクリプト
 * @desc 項目を決定したときに実行されるスクリプトです。
 * @default
 *
 * @param StringItems
 * @text 内容の配列
 * @desc 項目の設定内容の配列です。
 * @default
 * @type string[]
 *
 * @param AddPosition
 * @text 追加位置
 * @desc 項目を追加する位置です。指定した項目の上に追加されます。
 * @default
 * @type select
 * @option 末尾に追加
 * @value
 * @option 常時ダッシュ
 * @value alwaysDash
 * @option コマンド記憶
 * @value commandRemember
 * @option BGM 音量
 * @value bgmVolume
 * @option BGS 音量
 * @value bgsVolume
 * @option ME 音量
 * @value meVolume
 * @option SE 音量
 * @value seVolume
 *
 * @param PaddingTop
 * @text 余白
 * @desc 項目の上の余白ピクセル数です。項目の間隔を開けたいときに指定します。
 * @default 0
 * @type number
 */
/*~struct~VolumeData:
 * @param Name
 * @text 項目名称
 * @desc 項目の名称です。
 * @default 音量項目1
 *
 * @param DefaultValue
 * @text 初期値
 * @desc 項目の初期値です。
 * @default 0
 * @type number
 *
 * @param VariableID
 * @text 変数番号
 * @desc 項目の設定内容が格納される変数番号です。
 * @default 0
 * @type variable
 *
 * @param HiddenFlag
 * @text 隠しフラグ
 * @desc 項目がデフォルトで隠されるようになります。プラグインコマンドの実行で表示されます。
 * @default false
 * @type boolean
 *
 * @param Script
 * @text スクリプト
 * @desc 項目を決定したときに実行されるスクリプトです。変数[value]で現在の選択値が参照できます。
 * @default
 *
 * @param AddPosition
 * @text 追加位置
 * @desc 項目を追加する位置です。指定した項目の上に追加されます。
 * @default
 * @type select
 * @option 末尾に追加
 * @value
 * @option 常時ダッシュ
 * @value alwaysDash
 * @option コマンド記憶
 * @value commandRemember
 * @option BGM 音量
 * @value bgmVolume
 * @option BGS 音量
 * @value bgsVolume
 * @option ME 音量
 * @value meVolume
 * @option SE 音量
 * @value seVolume
 *
 * @param PaddingTop
 * @text 余白
 * @desc 項目の上の余白ピクセル数です。項目の間隔を開けたいときに指定します。
 * @default 0
 * @type number
 */

(function () {
  "use strict";
  var pluginName = "CustomizeConfigItem";

  var getParamString = function (paramNames) {
    var value = getParamOther(paramNames);
    return value == null ? "" : value;
  };

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

  var getParamArrayJson = function (paramNames, defaultValue) {
    var value = getParamString(paramNames) || null;
    try {
      value = JSON.parse(value);
      if (value === null) {
        value = defaultValue;
      } else {
        value = value.map(function (valueData) {
          return JSON.parse(valueData);
        });
      }
    } catch (e) {
      alert(
        `!!!Plugin param is wrong.!!!\nPlugin:${pluginName}.js\nName:[${paramNames}]\nValue:${value}`
      );
      value = defaultValue;
    }
    return value;
  };

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

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

  var getArgBoolean = function (arg) {
    return (arg || "").toUpperCase() === "TRUE";
  };

  var getArgJson = function (arg, defaultValue) {
    try {
      arg = JSON.parse(arg || null);
      if (arg === null) {
        arg = defaultValue;
      }
    } catch (e) {
      alert(
        `!!!Plugin param is wrong.!!!\nPlugin:${pluginName}.js\nValue:${arg}`
      );
      arg = defaultValue;
    }
    return arg;
  };

  var iterate = function (that, handler) {
    Object.keys(that).forEach(function (key, index) {
      handler.call(that, key, that[key], index);
    });
  };

  //=============================================================================
  // パラメータの取得と整形
  //=============================================================================
  var param = {};
  param.numberOptions = getParamArrayJson(["NumberOptions", "数値項目"], []);
  param.stringOptions = getParamArrayJson(["StringOptions", "文字項目"], []);
  param.switchOptions = getParamArrayJson(
    ["SwitchOptions", "スイッチ項目"],
    []
  );
  param.volumeOptions = getParamArrayJson(["VolumeOptions", "音量項目"], []);

  var localOptionWindowIndex = 0;

  //=============================================================================
  // Game_Interpreter
  //  プラグインコマンドを追加定義します。
  //=============================================================================
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    this.pluginCommandCustomizeConfigItem(command, args);
  };

  Game_Interpreter.prototype.pluginCommandCustomizeConfigItem = function (
    command,
    args
  ) {
    switch (getCommandName(command)) {
      case "CC_UNLOCK":
      case "オプション任意項目の隠し解除":
        ConfigManager.customParamUnlock(args[0]);
        break;
    }
  };

  //=============================================================================
  // ConfigManager
  //  追加項目の設定値や初期値を管理します。
  //=============================================================================
  ConfigManager.customParams = null;
  ConfigManager.hiddenInfo = {};
  ConfigManager._symbolNumber = "Number";
  ConfigManager._symbolBoolean = "Boolean";
  ConfigManager._symbolString = "String";
  ConfigManager._symbolVolume = "Volume";

  ConfigManager.getCustomParams = function () {
    if (this.customParams) {
      return this.customParams;
    }
    this.customParams = {};
    param.numberOptions.forEach(function (optionItem, index) {
      this.makeNumberOption(optionItem, index);
    }, this);
    param.stringOptions.forEach(function (optionItem, index) {
      this.makeStringOption(optionItem, index);
    }, this);
    param.switchOptions.forEach(function (optionItem, index) {
      this.makeSwitchOption(optionItem, index);
    }, this);
    param.volumeOptions.forEach(function (optionItem, index) {
      this.makeVolumeOption(optionItem, index);
    }, this);
    return this.customParams;
  };

  ConfigManager.makeNumberOption = function (optionItem, index) {
    var data = this.makeCommonOption(optionItem, index, this._symbolNumber);
    data.min = getArgNumber(optionItem.NumberMin);
    data.max = getArgNumber(optionItem.NumberMax);
    data.offset = getArgNumber(optionItem.NumberStep);
    this.pushOptionData(data);
  };

  ConfigManager.makeStringOption = function (optionItem, index) {
    var data = this.makeCommonOption(optionItem, index, this._symbolString);
    data.values = getArgJson(optionItem.StringItems, ["no item"]);
    data.min = 0;
    data.max = data.values.length - 1;
    this.pushOptionData(data);
  };

  ConfigManager.makeSwitchOption = function (optionItem, index) {
    var data = this.makeCommonOption(optionItem, index, this._symbolBoolean);
    data.initValue = getArgBoolean(optionItem.DefaultValue);
    data.variable = getArgNumber(optionItem.SwitchID);
    this.pushOptionData(data);
  };

  ConfigManager.makeVolumeOption = function (optionItem, index) {
    var data = this.makeCommonOption(optionItem, index, this._symbolVolume);
    this.pushOptionData(data);
  };

  ConfigManager.makeCommonOption = function (optionItem, index, type) {
    var data = {};
    data.symbol = `${type}${index + 1}`;
    data.name = optionItem.Name;
    data.hidden = getArgBoolean(optionItem.HiddenFlag);
    data.script = optionItem.Script;
    data.initValue = getArgNumber(optionItem.DefaultValue);
    data.variable = getArgNumber(optionItem.VariableID, 0);
    data.addPotion = optionItem.AddPosition;
    data.padding = getArgNumber(optionItem.PaddingTop);
    return data;
  };

  ConfigManager.pushOptionData = function (data) {
    this.customParams[data.symbol] = data;
  };

  var _ConfigManager_makeData = ConfigManager.makeData;
  ConfigManager.makeData = function () {
    var config = _ConfigManager_makeData.apply(this, arguments);
    config.hiddenInfo = {};
    iterate(
      this.getCustomParams(),
      function (symbol) {
        config[symbol] = this[symbol];
        config.hiddenInfo[symbol] = this.hiddenInfo[symbol];
      }.bind(this)
    );
    return config;
  };

  var _ConfigManager_applyData = ConfigManager.applyData;
  ConfigManager.applyData = function (config) {
    _ConfigManager_applyData.apply(this, arguments);
    iterate(
      this.getCustomParams(),
      function (symbol, item) {
        if (symbol.contains(this._symbolBoolean)) {
          this[symbol] = this.readFlagCustom(config, symbol, item);
        } else if (symbol.contains(this._symbolVolume)) {
          this[symbol] = this.readVolumeCustom(config, symbol, item);
        } else {
          this[symbol] = this.readOther(config, symbol, item);
        }
        if (config.hiddenInfo) {
          this.hiddenInfo[symbol] =
            typeof config.hiddenInfo[symbol] === "boolean"
              ? config.hiddenInfo[symbol]
              : item.hidden;
        } else {
          this.hiddenInfo[symbol] = item.hidden;
        }
      }.bind(this)
    );
  };

  ConfigManager.customParamUnlock = function (name) {
    iterate(
      this.getCustomParams(),
      function (symbol, item) {
        if (item.name === name) this.hiddenInfo[symbol] = false;
      }.bind(this)
    );
    this.save();
  };

  ConfigManager.readOther = function (config, name, item) {
    var value = config[name];
    if (value !== undefined) {
      return Number(value).clamp(item.min, item.max);
    } else {
      return item.initValue;
    }
  };

  ConfigManager.readFlagCustom = function (config, name, item) {
    if (config[name] !== undefined) {
      return this.readFlag(config, name);
    } else {
      return item.initValue;
    }
  };

  ConfigManager.readVolumeCustom = function (config, name, item) {
    if (config[name] !== undefined) {
      return this.readVolume(config, name);
    } else {
      return item.initValue;
    }
  };

  ConfigManager.exportCustomParams = function () {
    if (!$gameVariables || !$gameSwitches) return;
    iterate(
      this.getCustomParams(),
      function (symbol, item) {
        if (item.variable > 0) {
          if (symbol.contains(this._symbolBoolean)) {
            $gameSwitches.setValue(item.variable, !!this[symbol]);
          } else {
            $gameVariables.setValue(item.variable, this[symbol]);
          }
        }
      }.bind(this)
    );
  };

  ConfigManager.importCustomParams = function () {
    if (!$gameVariables || !$gameSwitches) return;
    iterate(
      this.getCustomParams(),
      function (symbol, item) {
        if (item.variable > 0) {
          if (symbol.contains(this._symbolBoolean)) {
            this[symbol] = $gameSwitches.value(item.variable);
          } else if (symbol.contains(this._symbolVolume)) {
            this[symbol] = $gameVariables.value(item.variable).clamp(0, 100);
          } else {
            this[symbol] = $gameVariables
              .value(item.variable)
              .clamp(item.min, item.max);
          }
        }
      }.bind(this)
    );
  };

  var _ConfigManager_save = ConfigManager.save;
  ConfigManager.save = function () {
    _ConfigManager_save.apply(this, arguments);
    this.exportCustomParams();
  };

  //=============================================================================
  // Game_Map
  //  リフレッシュ時にオプション値を同期します。
  //=============================================================================
  var _Game_Map_refresh = Game_Map.prototype.refresh;
  Game_Map.prototype.refresh = function () {
    _Game_Map_refresh.apply(this, arguments);
    ConfigManager.importCustomParams();
  };

  //=============================================================================
  // DataManager
  //  セーブ時とロード時にオプション値を同期します。
  //=============================================================================
  var _DataManager_setupNewGame = DataManager.setupNewGame;
  DataManager.setupNewGame = function () {
    _DataManager_setupNewGame.apply(this, arguments);
    ConfigManager.exportCustomParams();
  };

  var _DataManager_loadGameWithoutRescue = DataManager.loadGameWithoutRescue;
  DataManager.loadGameWithoutRescue = function (savefileId) {
    var result = _DataManager_loadGameWithoutRescue.apply(this, arguments);
    ConfigManager.exportCustomParams();
    return result;
  };

  //=============================================================================
  // Window_Options
  //  追加項目を描画します。
  //=============================================================================
  var _Window_Options_initialize = Window_Options.prototype.initialize;
  Window_Options.prototype.initialize = function () {
    this._customParams = ConfigManager.getCustomParams();
    _Window_Options_initialize.apply(this, arguments);
    this.select(localOptionWindowIndex);
    localOptionWindowIndex = 0;
  };

  var _Window_Options_itemRect = Window_Options.prototype.itemRect;
  Window_Options.prototype.itemRect = function (index) {
    var rect = _Window_Options_itemRect.apply(this, arguments);
    rect.y += this.findAdditionalHeight(index);
    return rect;
  };

  Window_Options.prototype.findAdditionalHeight = function (index) {
    return this._list.reduce(function (prev, item, itemIndex) {
      return prev + (itemIndex <= index && item.ext ? item.ext : 0);
    }, 0);
  };

  var _Window_Options_makeCommandList =
    Window_Options.prototype.makeCommandList;
  Window_Options.prototype.makeCommandList = function () {
    _Window_Options_makeCommandList.apply(this, arguments);
    this.addCustomOptions();
  };

  Window_Options.prototype.addCustomOptions = function () {
    iterate(
      this._customParams,
      function (key, item) {
        if (!ConfigManager.hiddenInfo[key]) {
          this.addCommand(item.name, key, undefined, item.padding);
          if (item.addPotion) {
            this.shiftCustomOptions(item.addPotion);
          }
        }
      }.bind(this)
    );
  };

  Window_Options.prototype.shiftCustomOptions = function (addPotion) {
    var targetCommand = this._list.filter(function (command) {
      return command.symbol === addPotion;
    })[0];
    if (!targetCommand) {
      return;
    }
    var targetIndex = this._list.indexOf(targetCommand);
    var newCommand = this._list.pop();
    this.addIndexForManoInputConfig(targetIndex);
    this._list.splice(targetIndex, 0, newCommand);
  };

  Window_Options.prototype.addIndexForManoInputConfig = function (index) {
    if (this._gamepadOptionIndex > index) {
      this._gamepadOptionIndex += 1;
    }
    if (this._keyboardConfigIndex > index) {
      this._keyboardConfigIndex += 1;
    }
  };

  var _Window_Options_statusText = Window_Options.prototype.statusText;
  Window_Options.prototype.statusText = function (index) {
    var result = _Window_Options_statusText.apply(this, arguments);
    var symbol = this.commandSymbol(index);
    var value = this.getConfigValue(symbol);
    if (this.isNumberSymbol(symbol)) {
      result = this.numberStatusText(value);
    } else if (this.isStringSymbol(symbol)) {
      result = this.stringStatusText(value, symbol);
    }
    return result;
  };

  Window_Options.prototype.isNumberSymbol = function (symbol) {
    return symbol.contains(ConfigManager._symbolNumber);
  };

  Window_Options.prototype.isStringSymbol = function (symbol) {
    return symbol.contains(ConfigManager._symbolString);
  };

  Window_Options.prototype.isCustomSymbol = function (symbol) {
    return !!this._customParams[symbol];
  };

  Window_Options.prototype.numberStatusText = function (value) {
    return value;
  };

  Window_Options.prototype.stringStatusText = function (value, symbol) {
    return this._customParams[symbol].values[value];
  };

  var _Window_Options_processOk = Window_Options.prototype.processOk;
  Window_Options.prototype.processOk = function () {
    if (!this._shiftValue(1, true))
      _Window_Options_processOk.apply(this, arguments);
    this.execScript();
  };

  var _Window_Options_cursorRight = Window_Options.prototype.cursorRight;
  Window_Options.prototype.cursorRight = function (wrap) {
    if (!this._shiftValue(1, false))
      _Window_Options_cursorRight.apply(this, arguments);
    this.execScript();
  };

  var _Window_Options_cursorLeft = Window_Options.prototype.cursorLeft;
  Window_Options.prototype.cursorLeft = function (wrap) {
    if (!this._shiftValue(-1, false))
      _Window_Options_cursorLeft.apply(this, arguments);
    this.execScript();
  };

  Window_Options.prototype._shiftValue = function (sign, loopFlg) {
    var symbol = this.commandSymbol(this.index());
    var value = this.getConfigValue(symbol);
    if (this.isNumberSymbol(symbol)) {
      value += this.numberOffset(symbol) * sign;
      this.changeValue(symbol, this._clampValue(value, symbol, loopFlg));
      return true;
    }
    if (this.isStringSymbol(symbol)) {
      value += sign;
      this.changeValue(symbol, this._clampValue(value, symbol, loopFlg));
      return true;
    }
    return false;
  };

  Window_Options.prototype.execScript = function () {
    var symbol = this.commandSymbol(this.index());
    if (!this.isCustomSymbol(symbol)) return;
    var script = this._customParams[symbol].script;
    var value = this.getConfigValue(symbol);
    if (script) {
      eval(script);
      SoundManager.playOk();
    }
    localOptionWindowIndex = this.index();
  };

  Window_Options.prototype._clampValue = function (value, symbol, loopFlg) {
    var maxValue = this._customParams[symbol].max;
    var minValue = this._customParams[symbol].min;
    if (loopFlg) {
      if (value > maxValue) value = minValue;
      if (value < minValue) value = maxValue;
    }
    return value.clamp(
      this._customParams[symbol].min,
      this._customParams[symbol].max
    );
  };

  Window_Options.prototype.numberOffset = function (symbol) {
    var value = this._customParams[symbol].offset;
    if (Input.isPressed("shift")) value *= 10;
    return value;
  };

  Window_Options.prototype.windowHeight = function () {
    var height = this.fittingHeight(Math.min(this.numVisibleRows(), 14));
    return height + this.findAdditionalHeight(this.maxItems());
  };
})();


code:
//=============================================================================
// CustomizeMaxSaveFile.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.1 2017/02/25 セーブファイル数により大きな値を設定できるよう上限を開放
// 1.1.0 2016/11/03 オートセーブなど最大数以上のIDに対してセーブするプラグインとの競合に対応
// 1.0.0 2016/03/19 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc Customize max save file number
 * @author triacontane
 *
 * @param SaveFileNumber
 * @desc max save file number(1...100)
 * @default 20
 *
 * @help Customize max save file number
 *
 * No plugin command
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc 最大セーブファイル数変更プラグイン
 * @author トリアコンタン
 *
 * @param セーブファイル数
 * @desc 最大セーブファイル数です。
 * @default 20
 *
 * @help 最大セーブファイル数をパラメータで指定した値に変更します。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";
  var pluginName = "CustomizeMaxSaveFile";

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

  var getParamOther = function (paramNames) {
    if (!Array.isArray(paramNames)) paramNames = [paramNames];
    for (var i = 0; i < paramNames.length; i++) {
      var name = PluginManager.parameters(pluginName)[paramNames[i]];
      if (name) return name;
    }
    return null;
  };
  var paramSaveFileNumber = getParamNumber(
    ["SaveFileNumber", "セーブファイル数"],
    0
  );

  //=============================================================================
  // DataManager
  //  セーブファイルの数をカスタマイズします。
  //=============================================================================
  var _DataManager_loadGlobalInfo = DataManager.loadGlobalInfo;
  DataManager.loadGlobalInfo = function () {
    if (!this._globalInfo) {
      this._globalInfo = _DataManager_loadGlobalInfo.apply(this, arguments);
    }
    return this._globalInfo;
  };

  var _DataManager_saveGlobalInfo = DataManager.saveGlobalInfo;
  DataManager.saveGlobalInfo = function (info) {
    _DataManager_saveGlobalInfo.apply(this, arguments);
    this._globalInfo = null;
  };

  var _DataManager_maxSavefiles = DataManager.maxSavefiles;
  DataManager.maxSavefiles = function () {
    return paramSaveFileNumber
      ? paramSaveFileNumber
      : _DataManager_maxSavefiles.apply(this, arguments);
  };

  var _DataManager_isThisGameFile = DataManager.isThisGameFile;
  DataManager.isThisGameFile = function (savefileId) {
    if (savefileId > this.maxSavefiles()) {
      return false;
    } else {
      return _DataManager_isThisGameFile.apply(this, arguments);
    }
  };
})();

repo_name: Idkwtcm/violated

license: unknown


code:
//=============================================================================
// 🏤drowsepost Plugins - Map Camera Controller
// DP_MapZoom.js
// Version: 0.87
//
// Copyright (c) 2016 - 2019 canotun
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

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

var drowsepost = drowsepost || {};

//=============================================================================
/*:
 * @plugindesc Control the magnification of the map scene.
 * @author drowsepost
 *
 * @param Base Scale
 * @desc Set the basic magnification ratio.(Start up)
 * Default: 1 (0 or more)
 * @default 1
 *
 * @param Encount Effect
 * @desc Corrected code of encounter effect
 * Default: true (ON: true / OFF: false)
 * @default true
 * @type boolean
 *
 * @param Camera Controll
 * @desc camera control during magnification processing
 * Default: true (ON: true / OFF: false / Minimum: minimum)
 * @default true
 * @type select
 * @option ON
 * @value true
 * @option OFF
 * @value false
 * @option Minimum
 * @value minimum
 *
 * @param Weather Patch
 * @desc Change weather sprite generation range
 * Default: true (ON: true / OFF: false)
 * @default true
 * @type boolean
 *
 * @param Picture Size Fixation
 * @desc Exclude pictures from map zooming process
 * Default: ALL (ALL: true / OFF: false / $ / screen_ / fix_)
 * @default true
 * @type select
 * @option OFF
 * @value false
 * @option ALL
 * @value true
 * @option $
 * @value $
 * @option screen_
 * @value screen_
 * @option fix_
 * @value fix_
 *
 * @param Old Focus
 * @desc Use trackless focus similar to the old version.
 * Default: false (ON: true / OFF: false)
 * @default false
 * @type boolean
 *
 * @param Easing Function
 * @desc animation Easing function.
 * args: t (0.00～1.00) return: Number (0.00～1.00) Default: t
 * @default t
 * @type string
 *
 * @help
 * ============================================================================
 * About
 * ============================================================================
 * It controls the enlargement ratio of the map scene by
 * reflecting the calculation of the enlargement ratio
 * to various coordinate processing.
 * (sorry... english support is immature. by drowsepost)
 *
 * ============================================================================
 * Knowing issue
 * ============================================================================
 * If the enlargement ratio is too small in a huge map,
 * processing will be dropped in the canvas mode,
 * and the map missing problem will occur in the webgl mode.
 * This is the limit of the PIXI library and the solution is under investigation
 *
 * ============================================================================
 * How To Use
 * ============================================================================
 *
 * ◆ plugin command:
 * dpZoom {zoom ratio} {animate frames} {event id or "this" or "player"}
 * rename: mapSetZoom
 *
 * e.g.:
 * dpZoom 0.8 360 this
 * -> zoom out to 0.8x , animate 360 frames, centering to event of called
 *
 * dpZoom 1
 * -> zoom to 1x(reset), Immediate
 *
 * dpZoom 3 60 1
 * -> zoom to 3x , animate 60 frames, centering to Event id:001
 *
 * dpFocus {event id or "this" or "player"} {animate frames}
 * Place the specified event in the center of the screen without changing
 * the enlargement ratio of the screen.
 * The camera follows the movement of the event
 *
 * ◆ map meta:
 * if you need setting to Default Magnification on the map,
 * fill in the following in the "Note" field
 *
 * <zoomScale: {zoom ratio}>
 * Specify the enlargement ratio to be the basis for each map
 *
 * e.g.:
 * <zoomScale:0.5>
 * -> zoom out to 0.5x , Immediate
 *
 * if you need setting to Default Camera target on the map,
 * fill in the following in the "Note" field
 *
 * <camTarget: {event id or "player"}>
 * Events can be in the center of the screen.
 * The screen follows the movement of the event.
 *
 * e.g.:
 * <camTarget: 3>
 * -> set center of the screen Event ID "3"
 *
 * ============================================================================
 * Technical information
 * ============================================================================
 * If "screenX" or "screenY" used by another plugin is misaligned,
 * multiply "screenX" or "screenY" by "$gameScreen.zoomScale()".
 *
 * This plugin controls "$gameScreen"
 *
 * This plugin use savedata
 * "$gameMap._dp_scale", "$gameMap._dp_pan", "$gameMap._dp_target"
 *
 */
/*:ja
 * @plugindesc マップの拡大率を制御します。
 * @author drowsepost
 *
 * @param Base Scale
 * @desc 基本の拡大率を設定します。(0以上)
 * Default: 1
 * @default 1
 *
 * @param Encount Effect
 * @desc エンカウントエフェクトに拡大率を反映
 * Default: true (ON: true / OFF: false)
 * @default true
 * @type boolean
 *
 * @param Camera Controll
 * @desc 拡大処理中のセンタリング制御をこのプラグインが行う
 * Default: true (ON: true / OFF: false / 最小: minimum)
 * @default true
 * @type select
 * @option ON
 * @value true
 * @option OFF
 * @value false
 * @option Minimum
 * @value minimum
 *
 * @param Weather Patch
 * @desc 天候スプライトの生成範囲を広げる修正を適用します。
 * Default: true (ON: true / OFF: false)
 * @default true
 * @type boolean
 *
 * @param Picture Size Fixation
 * @desc ピクチャをマップの拡大処理から除外します
 * Default: ALL (ALL: true / OFF: false / $ / screen_ / fix_)
 * @default true
 * @type select
 * @option OFF
 * @value false
 * @option ALL
 * @value true
 * @option $
 * @value $
 * @option screen_
 * @value screen_
 * @option fix_
 * @value fix_
 *
 * @param Old Focus
 * @desc 古いバージョンの追跡なしのフォーカスを使用します。
 * Default: false (ON: true / OFF: false)
 * @default false
 * @type boolean
 *
 * @param Easing Function
 * @desc アニメーションのイージング式。
 * 引数 t (0.00～1.00) 戻り値 数値(0.00～1.00) Default: t
 * @default t
 * @type string
 *
 * @help
 * ============================================================================
 * About
 * ============================================================================
 * 各種座標処理に拡大率の計算を反映し
 * マップシーンの拡大率を制御します。
 * また、指定したイベントをカメラが追うように指定します。
 * 標準のフォーカス対象は先頭のプレイヤーとなります。
 *
 * ============================================================================
 * Knowing issue
 * ============================================================================
 * 巨大なマップにおいて拡大率をあまりに小さくすると
 * canvasモードで処理落ち、webglモードでマップ欠けの問題が発生します。
 * これはPIXIライブラリの限界であり、解決方法は調査中です
 *
 * ============================================================================
 * How To Use
 * ============================================================================
 * ◆ マップメモ欄
 *
 * <zoomScale:0.5>
 * などと記述すると、マップごとに基準になる拡大率を指定することが出来ます。
 *
 * <camTarget: 3>
 * 等と記述すると、イベントID n番のイベントが画面中央になった状態にできます。
 * フォーカスはイベントの移動に画面が追従します。
 *
 * ◆ プラグインコマンド
 *
 * (1)ズーム機能
 * dpZoom {倍率} {変更にかけるフレーム数} {対象イベントID / this / player}
 * 指定したイベントにフォーカスを合わせつつ画面の拡大率を変更できます。
 * 第3引数に何も指定しない場合、画面中央に向かって拡大します。
 *
 * 例:
 * プラグインコマンドにおいて対象イベントの部分に
 * 「this」もしくは「このイベント」と指定すると、
 * イベント実行中のオブジェクトを指定します。
 * dpZoom 2 360 this
 * たとえば上記はそのイベントが中心になるように6秒かけて2倍の拡大率に変化します。
 * <非推奨> mapSetZoom は利用できますが、非推奨とします。
 *
 * (2)フォーカス機能
 * dpFocus {対象イベントID / this / player} {変更にかけるフレーム数}
 * 画面の拡大率を変更せずに指定したイベントにフォーカスを合わせます。
 *
 * ============================================================================
 * Settings
 * ============================================================================
 * Base Scale
 * ゲーム開始時の拡大倍率を指定します。
 * 倍率には0以上を指定してください。
 *
 * Encount Effect
 * エンカウントエフェクトを置き換えるかどうかを指定します。
 * オリジナルのエフェクトで置き換えている場合はこちらをfalseにしてください。
 * しかしその場合、画面の拡大率をそれぞれ反映できるように調整する必要があります。
 *
 * Camera Controll
 * falseの場合はイベントを指定した拡大を含む拡大中のカメラ制御は動作しません。
 * 別プラグインでカメラ制御を行う場合にご利用ください。
 *
 * Weather Patch
 * trueの場合、天候スプライトの生成範囲に関する修正を行い、
 * 拡大率変更後も天候スプライトをまんべんなく分布させます
 * 別プラグインで天候演出の制御を行っている場合等はfalseにしてください。
 *
 * Picture Size Fixation
 * trueの場合、ピクチャを拡大処理から除外します。
 *
 * Old Focus
 * trueの場合、古いDP_MapZoom.jsと同様のフォーカス処理を行います。
 * このフォーカス処理は対象イベントまでの座標のずれを基準にしているため、
 * イベントの移動を追尾しません。
 *
 * Easing Function
 * ズーム時のイージングを主に0から1の間で戻す式を設定できます。
 * 引数 t にズームの進捗が0から1で入ります。JavaScript。
 *
 * ============================================================================
 * Technical information
 * ============================================================================
 * 現在の画面の拡大率は$gameScreen.zoomScale()で取得できます。
 * これはプラグインの利用に関わらず元から存在する関数です。
 * 他のプラグインで利用する「screenX」や「screenY」がずれる場合は、
 * 「screenX」や「screenY」にそれぞれ$gameScreen.zoomScale()を掛けて下さい。
 *
 * このプラグインは$gameScreenを制御します。
 *
 * 指定された拡大率設定は$gameMap._dp_scaleが保持します。
 * シーン離脱時のスクロール量は$gameMap._dp_panが保持します。
 * マップのフォーカスイベントは$gameMap._dp_targetが保持します。
 *
 */
(function () {
  "use strict";
  var user_map_marginright = 0;
  var user_map_marginbottom = 0;

  var parameters = PluginManager.parameters("DP_MapZoom");
  var user_scale = Number(parameters["Base Scale"] || 1);
  var user_fix_encount = Boolean(
    parameters["Encount Effect"] === "true" || false
  );
  var user_use_camera = Boolean(
    parameters["Camera Controll"] === "true" || false
  );
  var user_use_camera_transfer = Boolean(
    parameters["Camera Controll"] === "minimum" || false
  );
  var user_fix_weather = Boolean(
    parameters["Weather Patch"] === "true" || false
  );
  var user_fix_picture = parameters["Picture Size Fixation"];
  var user_use_oldfocus = Boolean(parameters["Old Focus"] === "true" || false);
  var user_easing_function = parameters["Easing Function"];

  /*
    Main Functions
    =============================================================================
    実際の拡大処理
    */
  var camera = {};

  /*
    dp_renderSize
    タイル拡大率を保持および仮想的なレンダリング範囲を算出します。
    */
  var dp_renderSize = {
    _scale: undefined,
    width: undefined,
    height: undefined,

    /**
     * 拡大率からレンダリングするべきオブジェクトのサイズを設定します。
     * @param {number} scale
     */
    onChange: function (_scale) {
      if (!("_scene" in SceneManager)) return;
      if (!("_spriteset" in SceneManager._scene)) return;
      var scale = _scale || this._scale;
      var spriteset = SceneManager._scene._spriteset;

      //マップサイズ変更
      spriteset._tilemap.width =
        Math.ceil(Graphics.width / scale) + spriteset._tilemap._margin * 2;
      spriteset._tilemap.height =
        Math.ceil(Graphics.height / scale) + spriteset._tilemap._margin * 2;

      //パララックスサイズ変更
      spriteset._parallax.move(
        0,
        0,
        Math.round(Graphics.width / scale),
        Math.round(Graphics.height / scale)
      );

      // Foreground.js対応
      if (
        spriteset._foreground &&
        spriteset._foreground instanceof TilingSprite
      ) {
        spriteset._foreground.move(
          0,
          0,
          Math.round(Graphics.width / scale),
          Math.round(Graphics.height / scale)
        );
      }

      spriteset._tilemap.refresh();
      spriteset._tilemap._needsRepaint = true;
      spriteset._tilemap.updateTransform();
    },

    /**
     * scaleをリセットします
     */
    reset: function () {
      this.scale = 1;
    },
  };

  Object.defineProperty(dp_renderSize, "scale", {
    get: function () {
      return this._scale;
    },
    set: function (val) {
      if (val != this._scale) {
        this._scale = Number(val);
        this.width = Math.ceil(Graphics.boxWidth / this._scale);
        this.height = Math.ceil(Graphics.boxHeight / this._scale);
        this.onChange();
      }
    },
  });

  /**
   * ズームすべき座標を算出
   * @return {object} Point
   */
  var dp_getZoomPos = function () {
    return new Point(
      camera.target.screenX(),
      camera.target.screenY() - $gameMap.tileHeight() / 2
    );
  };

  /**
   * マップのレンダリング原点と表示位置のずれを取得します。
   * @return {object} Point
   */
  var dp_getVisiblePos = function () {
    var scale = $gameScreen.zoomScale();
    return new Point(
      Math.round($gameScreen.zoomX() * (scale - dp_renderSize.scale)),
      Math.round($gameScreen.zoomY() * (scale - dp_renderSize.scale))
    );
  };

  /**
   * フォーカスされているキャラクターから画面の中心がどれだけずれているか取得します
   * @return {object} Point
   */
  var dp_getpan = function () {
    var centerPosX = ($gameMap.screenTileX() - 1) / 2;
    var centerPosY = ($gameMap.screenTileY() - 1) / 2;

    var pan_x = $gameMap.displayX() + centerPosX - camera.target._realX;
    var pan_y = $gameMap.displayY() + centerPosY - camera.target._realY;

    return new Point(
      $gameMap.screenTileX() >= $dataMap.width ? 0 : pan_x,
      $gameMap.screenTileY() >= $dataMap.height ? 0 : pan_y
    );
  };

  /**
   * 画面の拡大率を設定します。
   * @param {number} scale
   */
  var dp_setZoom = function (scale) {
    dp_renderSize.scale = scale;
    $gameMap._dp_scale = scale;

    $gameScreen.setZoom(0, 0, scale);
    camera.center();
  };

  /**
   * 指定されたイベントIDをイベントインスタンスにして返却
   * @param {any} event イベントIDもしくはイベントオブジェクトもしくはプレイヤー
   * @return {object} Game_CharacterBase
   */
  var dp_getEvent = function (event) {
    var _target;
    if (typeof event === "object") {
      if ("_eventId" in event) _target = $gameMap.event(event._eventId);
    }

    if (typeof event === "number") {
      _target = $gameMap.event(event);
    }

    if (!(_target instanceof Game_CharacterBase)) {
      _target = $gamePlayer;
    }

    return _target;
  };

  /**
   * カメラターゲットから目標イベントまでのマップ上のズレ(x,y)を取得
   * @param {any} event イベントIDもしくはイベントオブジェクトもしくはプレイヤー
   * @return {object} Point
   */
  var dp_targetPan = function (event) {
    var _target = dp_getEvent(event);

    return new Point(
      _target._realX - camera.target._realX,
      _target._realY - camera.target._realY
    );
  };

  /**
   * 文字列をイージング用関数として評価した関数を返します
   * @param {String|Function} txt_func
   * @return {Function} イージング用関数、引数は float t
   */
  var dp_txtToEasing = function (txt_func) {
    var basic_func = function (t) {
      return t;
    };
    if (typeof txt_func === "function") return txt_func;
    if (typeof txt_func !== "string") return basic_func;
    if (txt_func == "") return basic_func;

    try {
      return new Function("t", "return " + txt_func + ";");
    } catch (e) {
      console.error("DP_MapZoom: Easing Function", e, txt_func);
    }
    return basic_func;
  };

  /**
   * 線形補完
   * @param {Number} p 入力進捗率
   * @param {Number} from 開始数値
   * @param {Number} to 目標数値
   * @return {Number} 結果進捗率
   */
  var dp_lerp = function (p, from, to) {
    return from + (to - from) * p;
  };

  /*
    Camera Object
    ===================================================================================
    */

  /**
   * カメラのアニメーションを制御するオブジェクト
   */
  camera.animation = (function () {
    //private
    var _active = false;
    var _count, _duration, _easing;
    var _start_pan, _start_scale, _end_pan, _end_scale;

    //public
    var r = {
      /**
       * アニメーションのスタート
       * @param {Number} scale 目標とする拡大率
       * @param {Point} pos 目標とする座標のズレ
       * @param {Number} dulation 変化にかけるフレーム
       */
      start: function (scale, pos, duration) {
        var is_zoomout = $gameScreen.zoomScale() > scale ? true : false;

        _count = 0;
        _duration = duration || 0;
        _end_scale = scale || $gameScreen.zoomScale();
        _end_pan = pos || new Point();

        _start_pan = dp_getpan();
        _start_scale = $gameScreen.zoomScale();

        if (is_zoomout) {
          dp_renderSize.scale = scale;
          camera.center(_start_pan.x, _start_pan.y);
        }

        _active = true;
      },
      /**
       * アニメーションのアップデート
       * camera.animation.update
       */
      update: function () {
        if (!_active) return;

        var p = _count / _duration;
        _count++;

        if (p > 1) {
          r.end();
          return;
        }

        if (_count % 2 === 0) return;

        var ease = _easing(p);
        var x = dp_lerp(ease, _start_pan.x, _end_pan.x);
        var y = dp_lerp(ease, _start_pan.y, _end_pan.y);
        var z = dp_lerp(ease, _start_scale, _end_scale);

        $gameScreen.setZoom(0, 0, z);
        camera.center(x, y);
      },
      /**
       * アニメーションの終了
       */
      end: function () {
        if (!_active) return;
        _active = false;

        $gameMap._dp_pan = _end_pan;
        dp_setZoom(_end_scale);
      },
    };

    Object.defineProperty(r, "easing", {
      get: function () {
        return _easing;
      },
      set: function (val) {
        _easing = dp_txtToEasing(val);
      },
    });

    r.easing = user_easing_function;

    return r;
  })();

  /**
   * カメラのズームを開始する関数
   * @param {number} ratio 拡大率
   * @param {number} duration 変化にかけるフレーム
   * @param {any} target フォーカスするイベントIDもしくはゲームイベントオブジェクト
   */
  camera.zoom = function (ratio, duration, target) {
    if (typeof ratio !== "number" || ratio < 0) {
      ratio = dp_renderSize.scale;
    }

    var target_pan = dp_getpan();
    if (typeof target !== "undefined") {
      if (user_use_oldfocus) {
        target_pan = dp_targetPan(target);
      } else {
        camera.target = target;
        target_pan = new Point();
      }
    }

    if (duration > 0) {
      camera.animation.start(ratio, target_pan, duration);
    } else {
      $gameMap._dp_pan = target_pan;
      dp_setZoom(ratio);
    }
  };

  /**
   * フォーカスしたターゲットをカメラ中央に配置
   * @param {number} panX 画面をずらすマスの数。横。
   * @param {number} panY 画面をずらすマスの数。縦。
   * @param {boolean} force_center カメラ制御無効でも実行
   */
  camera.center = function (panX, panY, force_center) {
    if (!user_use_camera && !force_center) return;
    var px = Number(panX || $gameMap._dp_pan.x);
    var py = Number(panY || $gameMap._dp_pan.y);
    camera.target.center(camera.target._realX + px, camera.target._realY + py);
  };

  /**
   * カメラがフォーカスする対象
   * @param {any} event イベントIDもしくはゲームイベントもしくはプレイヤー
   * @return {object} ゲームイベントもしくはプレイヤー
   */
  Object.defineProperty(camera, "target", {
    get: function () {
      if ($gameMap._dp_target === 0) return $gamePlayer;
      return $gameMap.event($gameMap._dp_target);
    },
    set: function (event) {
      var _target = dp_getEvent(event);

      $gameMap._dp_target = 0;
      if (typeof _target === "object") {
        if ("_eventId" in _target) $gameMap._dp_target = _target._eventId;
      }
    },
  });

  //公開
  drowsepost.camera = camera;
  drowsepost.rendersize = dp_renderSize;

  /*
    Command Entry
    ===================================================================================
    @param {array} args スペース区切りで指定したプラグインコマンドの引数(array<string>)
    */
  drowsepost.fn = drowsepost.fn || {};

  /**
   * 拡大率を変更せずにフォーカス変更
   * {target} {frame}
   */
  var _p_dpfocus =
    "dpFocus" in drowsepost.fn ? drowsepost.fn.dpFocus : function () {};
  drowsepost.fn.dpFocus = function (_a) {
    _p_dpfocus.call(this, _a);

    var _s = this;
    var _target;

    if (_a.length < 1) _a.push("player");

    if (_a[0] === "this" || _a[0] === "このイベント") _target = _s;
    else if (_a[0] === "player" || _a[0] === "プレイヤー")
      _target = $gamePlayer;
    else _target = parseInt(_a[0]);

    camera.zoom(dp_renderSize.scale, parseInt(_a[1]), _target);
  };

  /**
   * 画面拡大率を変更
   * 第三引数にターゲット指定でフォーカスも変更
   * {zoom} {frame} {target}
   */
  var _p_dpzoom =
    "dpZoom" in drowsepost.fn ? drowsepost.fn.dpZoom : function () {};
  drowsepost.fn.mapSetZoom = drowsepost.fn.dpZoom = function (_a) {
    _p_dpzoom.call(this, _a);

    var _s = this;
    var _target;

    if (_a.length > 2) {
      if (_a[2] === "this" || _a[2] === "このイベント") _target = _s;
      else if (_a[2] === "player" || _a[2] === "プレイヤー")
        _target = $gamePlayer;
      else _target = parseInt(_a[2]);
    }

    camera.zoom(parseFloat(_a[0]), parseInt(_a[1]), _target);
  };

  /*
    Game_Interpreter
    ===================================================================================
    コマンドパーサーの追加
    */
  (function () {
    //@override
    var _parent_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function (command, args) {
      _parent_pluginCommand.call(this, command, args);

      if ("DP_Basics" in Imported) return;
      if (!(command in drowsepost.fn)) return;
      if (typeof drowsepost.fn[command] === "function") {
        drowsepost.fn[command].call(this, args);
      }
    };
  })();

  /*
    Game Map
    =============================================================================
    拡大率($gameScreen.zoomScale())の反映
    */
  (function () {
    //@override
    var _parent_initialize = Game_Map.prototype.initialize;
    Game_Map.prototype.initialize = function () {
      _parent_initialize.call(this);

      //保存用変数エントリー
      this._dp_scale = user_scale;
      this._dp_pan = new Point();
      this._dp_target = 0;
    };

    //@override
    Game_Map.prototype.screenTileX = function () {
      return (
        (Graphics.width - user_map_marginright) /
        (this.tileWidth() * $gameScreen.zoomScale())
      );
    };

    //@override
    Game_Map.prototype.screenTileY = function () {
      return (
        (Graphics.height - user_map_marginbottom) /
        (this.tileHeight() * $gameScreen.zoomScale())
      );
    };

    //@override
    Game_Map.prototype.canvasToMapX = function (x) {
      var tileWidth = this.tileWidth() * $gameScreen.zoomScale();
      var originX = this._displayX * tileWidth;
      var mapX = Math.floor((originX + x) / tileWidth);
      return this.roundX(mapX);
    };

    //@override
    Game_Map.prototype.canvasToMapY = function (y) {
      var tileHeight = this.tileHeight() * $gameScreen.zoomScale();
      var originY = this._displayY * tileHeight;
      var mapY = Math.floor((originY + y) / tileHeight);
      return this.roundY(mapY);
    };
  })();

  /*
    Game Character
    =============================================================================
    Game Characterに注視する場合の処理を追加
    */
  (function () {
    Game_Character.prototype.centerX = function () {
      return ($gameMap.screenTileX() - 1) / 2.0;
    };

    Game_Character.prototype.centerY = function () {
      return ($gameMap.screenTileY() - 1) / 2.0;
    };

    Game_Character.prototype.center = function (x, y) {
      return $gameMap.setDisplayPos(x - this.centerX(), y - this.centerY());
    };

    Game_Character.prototype.updateScroll = function (
      lastScrolledX,
      lastScrolledY
    ) {
      var x1 = lastScrolledX;
      var y1 = lastScrolledY;
      var x2 = this.scrolledX();
      var y2 = this.scrolledY();
      if (y2 > y1 && y2 > this.centerY()) {
        $gameMap.scrollDown(y2 - y1);
      }
      if (x2 < x1 && x2 < this.centerX()) {
        $gameMap.scrollLeft(x1 - x2);
      }
      if (x2 > x1 && x2 > this.centerX()) {
        $gameMap.scrollRight(x2 - x1);
      }
      if (y2 < y1 && y2 < this.centerY()) {
        $gameMap.scrollUp(y1 - y2);
      }
    };
  })();

  /*
    Game Player
    =============================================================================
    拡大率の反映
    */
  (function () {
    //@override
    Game_Player.prototype.centerX = function () {
      return ($gameMap.screenTileX() - 1) / 2.0;
    };

    //@override
    Game_Player.prototype.centerY = function () {
      return ($gameMap.screenTileY() - 1) / 2.0;
    };

    //@override
    var _parent_updateScroll = Game_Player.prototype.updateScroll;
    Game_Player.prototype.updateScroll = function (
      lastScrolledX,
      lastScrolledY
    ) {
      if (typeof $gameMap !== "object") return;
      if ($gameMap._dp_target !== 0) return;
      _parent_updateScroll.call(this, lastScrolledX, lastScrolledY);
    };
  })();

  /*
    Game Event
    =============================================================================
    Game Eventに注視する場合の処理を追加
    */
  (function () {
    //@override
    var _parent_update = Game_Event.prototype.update;
    Game_Event.prototype.update = function () {
      var lastScrolledX = this.scrolledX();
      var lastScrolledY = this.scrolledY();

      _parent_update.call(this);

      this.updateScroll(lastScrolledX, lastScrolledY);
    };

    Game_Event.prototype.updateScroll = function (
      lastScrolledX,
      lastScrolledY
    ) {
      if (typeof $gameMap !== "object") return;
      if ($gameMap._dp_target !== this._eventId) return;
      Game_Character.prototype.updateScroll.call(
        this,
        lastScrolledX,
        lastScrolledY
      );
    };
  })();

  /*
    Weather
    =============================================================================
    描画反映変更機能の追加
    */
  (function () {
    //天候スプライトの生成範囲をGraphic基準ではなく実際の描画範囲に合わせる
    if (!user_fix_weather) return;
    //@override
    var _parent_rebornSprite = Weather.prototype._rebornSprite;
    Weather.prototype._rebornSprite = function (sprite) {
      _parent_rebornSprite.call(this, sprite);
      sprite.ax =
        Math.randomInt(dp_renderSize.width + 100) - 50 + this.origin.x;
      sprite.ay =
        Math.randomInt(dp_renderSize.height + 200) - 100 + this.origin.y;
      sprite.opacity = 160 + Math.randomInt(60);
    };
  })();

  /*
    Sprite_Picture
    =============================================================================
    ピクチャdot by dot配置機能の追加
    */
  (function () {
    //ピクチャの配置と拡大率を、スクリーンの拡大率で打ち消す
    if (!user_fix_picture) return;
    if (user_fix_picture === "false") return;

    //@override
    var _parent_loadBitmap = Sprite_Picture.prototype.loadBitmap;
    Sprite_Picture.prototype.loadBitmap = function () {
      _parent_loadBitmap.call(this);

      if (user_fix_picture === "true") {
        this._dp_fix = true;
      } else if (!this._pictureName.indexOf(user_fix_picture)) {
        this._dp_fix = true;
      } else {
        this._dp_fix = false;
      }
    };

    //@override
    var _parent_updateScale = Sprite_Picture.prototype.updateScale;
    Sprite_Picture.prototype.updateScale = function () {
      _parent_updateScale.call(this);
      if (!this._dp_fix) return;

      var picture = this.picture();
      this.scale.x = (1 / $gameScreen.zoomScale()) * (picture.scaleX() / 100);
      this.scale.y = (1 / $gameScreen.zoomScale()) * (picture.scaleY() / 100);
    };

    //@override
    var _parent_updatePosition = Sprite_Picture.prototype.updatePosition;
    Sprite_Picture.prototype.updatePosition = function () {
      _parent_updatePosition.call(this);
      if (!this._dp_fix) return;

      var picture = this.picture();
      var map_s = dp_getVisiblePos();
      this.x = (picture.x() + map_s.x) * (1 / $gameScreen.zoomScale());
      this.y = (picture.y() + map_s.y) * (1 / $gameScreen.zoomScale());
    };
  })();

  /*
    Sprite_Timer
    =============================================================================
    タイマーの配置とサイズを調整
    */
  (function () {
    //@override
    var _parent_updatePosition = Sprite_Timer.prototype.updatePosition;
    Sprite_Timer.prototype.updatePosition = function () {
      _parent_updatePosition.call(this);

      var _zoom = 1 / $gameScreen.zoomScale();

      this.x = this.x * _zoom;
      this.y = this.y * _zoom;
      this.scale.x = _zoom;
      this.scale.y = _zoom;
    };
  })();

  /*
    Spriteset_Base
    =============================================================================
    拡大座標の調整
    */
  (function () {
    //@override
    var _parent_updatePosition = Spriteset_Base.prototype.updatePosition;
    Spriteset_Base.prototype.updatePosition = function () {
      _parent_updatePosition.call(this);

      var map_s = dp_getVisiblePos();
      this.x = map_s.x * -1;
      this.y = map_s.y * -1;

      this.x += Math.round($gameScreen.shake());
    };
  })();

  /*
    Scene_Map
    =============================================================================
    拡大率の引継ぎ
    */
  (function () {
    /*
        マップシーンの開始
        */
    //@override
    var _parent_start = Scene_Map.prototype.start;
    Scene_Map.prototype.start = function () {
      _parent_start.call(this);

      //移動後処理
      if (this._transfer) {
        //マップ設定情報で拡大率変更
        //イベントエディタからのテスト実行では$gameMap.metaが定義されない。
        $gameMap._dp_scale =
          "meta" in $dataMap
            ? Number($dataMap.meta.zoomScale || $gameMap._dp_scale)
            : $gameMap._dp_scale;

        //カメラターゲット
        //イベントエディタからのテスト実行では$gameMap.metaが定義されない。
        $gameMap._dp_target =
          "meta" in $dataMap ? Number($dataMap.meta.camTarget || 0) : 0;

        //パン
        $gameMap._dp_pan = new Point();
      }

      //標準レンダリングサイズにリセット
      dp_renderSize.reset();

      //カメラターゲット設定
      camera.target = $gameMap._dp_target;

      //マップシーン開始時に拡大率変更をフック。
      dp_setZoom($gameMap._dp_scale);

      //画面中心を強制設定する
      if (!user_use_camera && user_use_camera_transfer)
        camera.center(null, null, true);
    };

    /*
        マップシーンの終了
        */
    //@override
    var _parent_terminate = Scene_Map.prototype.terminate;
    Scene_Map.prototype.terminate = function () {
      //マップシーン終了時に拡大率情報を保存。
      camera.animation.end();

      var zoomPos = dp_getZoomPos();
      $gameScreen.setZoom(zoomPos.x, zoomPos.y, dp_renderSize.scale);
      $gameMap._dp_pan = dp_getpan();

      _parent_terminate.call(this);
    };

    /*
        エンカウントエフェクト
        */
    if (!user_fix_encount) return;
    //@override
    Scene_Map.prototype.updateEncounterEffect = function () {
      if (this._encounterEffectDuration > 0) {
        this._encounterEffectDuration--;
        var speed = this.encounterEffectSpeed();
        var n = speed - this._encounterEffectDuration;
        var p = n / speed;
        var q = ((p - 1) * 20 * p + 5) * p + 1;
        var zoomPos = dp_getZoomPos();

        if (n === 2) {
          $gameScreen.setZoom(zoomPos.x, zoomPos.y, dp_renderSize.scale);
          this.snapForBattleBackground();
          this.startFlashForEncounter(speed / 2);
        }

        $gameScreen.setZoom(zoomPos.x, zoomPos.y, q * dp_renderSize.scale);
        if (n === Math.floor(speed / 6)) {
          this.startFlashForEncounter(speed / 2);
        }
        if (n === Math.floor(speed / 2)) {
          BattleManager.playBattleBgm();
          this.startFadeOut(this.fadeSpeed());
        }
      }
    };
    //エンカウントエフェクトここまで
  })();

  /*
    Tilemap
    =============================================================================
    Canvasモード時の軽量化、拡大率の反映
    */
  (function () {
    //@override
    var _Tilemap_createLayers = Tilemap.prototype._createLayers;
    Tilemap.prototype._createLayers = function () {
      if (this._lowerLayer instanceof Sprite) {
        this._lowerLayer.destroy();
      }
      if (this._upperLayer instanceof Sprite) {
        this._upperLayer.destroy();
      }

      _Tilemap_createLayers.call(this);
    };
  })();

  /*
    Game_Screen
    =============================================================================
    アニメーション処理のフック
    */
  (function () {
    //@override
    var _parent_update = Game_Screen.prototype.update;
    Game_Screen.prototype.update = function () {
      _parent_update.call(this);
      camera.animation.update();
    };

    //@override
    var _parent_initialize = Game_Screen.prototype.initialize;
    Game_Screen.prototype.initialize = function () {
      _parent_initialize.call(this);
      dp_renderSize.reset();
    };
  })();
})();


code:
//=============================================================================
// DTextPicture.js
// ----------------------------------------------------------------------------
// (C) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.19.0 2020/04/09 フレームウィンドウに余白を指定できる機能を追加
// 1.18.0 2020/04/05 制御文字\v[n, m]で埋められる文字をパラメータから指定できる機能を追加
// 1.17.0 2020/02/07 背景ウィンドウのスキンを変更できる機能を追加し、ウィンドウビルダーに対応
// 1.16.0 2020/02/01 複数行表示した場合の行間を指定できる機能を追加
// 1.15.1 2019/12/29 YEP_PluginCmdSwVar.jsと併用したとき、変数のリアルタイム変換が効かなくなる競合を修正
// 1.15.0 2019/10/21 カーソルのアクティブ状態を変更できるコマンドを追加
//                   アイテム表示の制御文字でアイコン表示可否を変更できる設定を追加
// 1.14.0 2019/01/13 背景ウィンドウにカーソル表示できる機能を追加
// 1.13.0 2018/11/25 背景色のグラデーションを設定できる機能を追加
// 1.12.0 2018/11/08 背景ウィンドウの透明度と文字列ピクチャの透明度を連動させるよう仕様変更
// 1.11.1 2018/10/20 プラグイン等でGame_Variables.prototype.setValueを呼んだとき、変数の添え字に文字列型の数値を渡した場合も変数のリアルタイム表示が効くよう修正
// 1.11.0 2018/10/13 公式プラグイン「TextDecoration.js」の設定を動的文字列に適用できる機能を追加
// 1.10.1 2018/05/30 アウトラインカラー取得で0およびその他の文字列を指定したときに正しく色が設定されない問題を修正(by奏ねこまさん)
// 1.10.0 2017/02/12 アウトラインカラーをウィンドウカラー番号から指定できる機能を追加
// 1.9.0 2017/08/20 ウィンドウつきピクチャが重なったときにウィンドウがピクチャの下に表示される問題を修正
// 1.8.6 2017/06/28 フォント変更機能のヘルプが抜けていたので追加
// 1.8.5 2017/06/12 変数がマイナス値のときのゼロ埋め表示が正しく表示されない問題を修正
// 1.8.4 2017/05/10 プラグインを未適用のデータを読み込んだとき、最初の一回のみ動的文字列ピクチャが作成されない問題を修正
// 1.8.3 2017/04/19 自動翻訳プラグインに一部対応
// 1.8.2 2017/04/05 ピクチャの消去時にエラーが発生していた問題を修正
// 1.8.1 2017/03/30 拡大率と原点に対応していなかった問題を修正
// 1.8.0 2017/03/30 背景にウィンドウを表示できる機能を追加
// 1.7.1 2017/03/20 1.7.0で末尾がイタリック体の場合に、傾き部分が見切れてしまう問題を修正
// 1.7.0 2017/03/20 動的文字列を太字とイタリックにできる機能を追加
//                  複数行表示かつ制御文字でアイコンを指定した場合に高さが余分に計算されてしまう問題の修正
// 1.6.2 2016/12/13 動的ピクチャに対して、ピクチャの表示とピクチャの色調変更を同フレームで行うと画像が消える問題の修正
// 1.6.1 2016/11/03 一通りの競合対策
// 1.6.0 2016/11/03 インストールされているフォントをピクチャのフォントとして利用できる機能を追加
// 1.5.1 2016/10/27 1.5.0でアウトラインカラーを指定するとエラーになっていた現象を修正
// 1.5.0 2016/10/23 制御文字で表示した変数の内容をリアルタイム更新できる機能を追加
// 1.4.2 2016/07/02 スクリプトからダイレクトで実行した場合も制御文字が反映されるよう修正（ただし余分にエスケープする必要あり）
// 1.4.1 2016/06/29 制御文字「\{」で文字サイズを大きくした際、元のサイズに戻さないと正しいサイズで表示されない問題を修正
// 1.4.0 2016/06/28 D_TEXT実行後に画像を指定してピクチャを表示した場合は画像を優先表示するよう仕様変更
// 1.3.1 2016/06/07 描画文字が半角英数字のみかつフォントを未指定の場合に文字が描画されない不具合を修正
// 1.3.0 2016/06/03 制御文字\oc[c] \ow[n]に対応
// 1.2.2 2016/03/28 データベース情報を簡単に出力する制御文字を追加
// 1.2.1 2016/01/29 コマンド「D_TEXT_SETTING」の実装が「D_TEST_SETTING」になっていたので修正（笑）
// 1.2.0 2016/01/27 複数行表示に対応
//                  文字列の揃えと背景色を設定する機能を追加
//                  変数をゼロ埋めして表示する機能を追加
// 1.1.3 2015/12/10 戦闘画面でもピクチャを使用できるよう修正
//                  描画後にデバッグ画面等を開いて変数を修正した場合、再描画で変更が反映されてしまう問題を修正
// 1.1.2 2015/11/07 描画文字列に半角スペースが含まれていた場合も問題なく実行できるよう修正
// 1.1.0 2015/11/07 制御文字\C[n] \I[n] \{ \} に対応（\$と表示スピード制御系以外全部）
// 1.0.1 2015/11/07 RPGツクールMV（日本語版）に合わせてコメントの表記を変更
// 1.0.0 2015/11/06 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc 動的文字列ピクチャ生成プラグイン
 * @author トリアコンタン
 *
 * @param itemIconSwitchId
 * @text アイテムアイコンスイッチID
 * @desc 指定した番号のスイッチがONのとき\ITEM[n]でアイコンが表示されます。指定しない場合、常に表示されます。
 * @default 0
 * @type switch
 *
 * @param lineSpacingVariableId
 * @text 行間補正変数ID
 * @desc 複数行表示の際の行間に、指定した変数の値の分だけ補正が掛かります。大きすぎる値を設定すると見切れる場合があります。
 * @default 0
 * @type variable
 *
 * @param frameWindowSkin
 * @text フレームウィンドウスキン
 * @desc フレームウィンドウのスキンファイル名です。ウィンドウビルダーを使っている場合は、指定する必要があります。
 * @default
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param frameWindowPadding
 * @text フレームウィンドウ余白
 * @desc フレームウィンドウの余白です。
 * @default 18
 * @type number
 *
 * @param padCharacter
 * @text 埋め文字
 * @desc 数値描画時、指定桁数に満たないときに埋められる文字です。半角で1文字だけ指定してください。
 * @default 0
 *
 * @help 指定した文字列でピクチャを動的に生成するコマンドを提供します。
 * 文字列には各種制御文字（\v[n]等）も使用可能で、制御文字で表示した変数の値が
 * 変更されたときにリアルタイムでピクチャの内容を更新できます。
 *
 * 以下の手順で表示します。
 *  1 : プラグインコマンド[D_TEXT]で描画したい文字列と引数を指定（下記の例参照）
 *  2 : プラグインコマンド[D_TEXT_SETTING]で背景色や揃えを指定（任意）
 *  3 : イベントコマンド「ピクチャの表示」で「画像」を未選択に指定。
 * ※ 1の時点ではピクチャは表示されないので必ずセットで呼び出してください。
 * ※ ピクチャ表示前にD_TEXTを複数回実行すると、複数行表示できます。
 *
 * ※ ver1.4.0より、[D_TEXT]実行後に「ピクチャの表示」で「画像」を指定した場合は
 *    動的文字列ピクチャ生成を保留として通常通り「画像」ピクチャが表示される
 *    ように挙動が変更になりました。
 *
 * プラグインコマンド詳細
 *   イベントコマンド「プラグインコマンド」から実行。
 *   （引数の間は半角スペースで区切る）
 *
 *  D_TEXT [描画文字列] [文字サイズ] : 動的文字列ピクチャ生成の準備
 *  例：D_TEXT テスト文字列 32
 *
 * 表示後は通常のピクチャと同様に移動や回転、消去ができます。
 * また、変数やアクターの表示など制御文字にも対応しています。
 *
 *  D_TEXT_SETTING ALIGN [揃え] : 揃え（左揃え、中央揃え、右揃え）の設定
 *  0:左揃え 1:中央揃え 2:右揃え
 *
 *  例：D_TEXT_SETTING ALIGN 0
 *      D_TEXT_SETTING ALIGN CENTER
 *
 * ※ 揃えの設定は複数行を指定したときに最も横幅の大きい行に合わせられます。
 * 　 よって単一行しか描画しないときは、この設定は機能しません。
 *
 *  D_TEXT_SETTING BG_COLOR [背景色] : 背景色の設定(CSSの色指定と同様の書式)
 *
 *  例：D_TEXT_SETTING BG_COLOR black
 *      D_TEXT_SETTING BG_COLOR #336699
 *      D_TEXT_SETTING BG_COLOR rgba(255,255,255,0.5)
 *
 *  背景色のグラデーションをピクセル数で指定できます。
 *  D_TEXT_SETTING BG_GRADATION_RIGHT [ピクセル数]
 *  D_TEXT_SETTING BG_GRADATION_LEFT [ピクセル数]
 *
 *  例：D_TEXT_SETTING BG_GRADATION_RIGHT 50
 *  　　D_TEXT_SETTING BG_GRADATION_LEFT 50
 *
 *  D_TEXT_SETTING REAL_TIME ON : 制御文字で表示した変数のリアルタイム表示
 *
 *  例：D_TEXT_SETTING REAL_TIME ON
 *
 *  リアルタイム表示を有効にしておくと、ピクチャの表示後に変数の値が変化したとき
 *  自動でピクチャの内容も更新されます。
 *
 *  D_TEXT_SETTING WINDOW ON : 背景にウィンドウを表示する
 *  例：D_TEXT_SETTING WINDOW ON
 *
 *  D_TEXT_SETTING FONT [フォント名] : 描画で使用するフォントを指定した名称に変更
 *  例：D_TEXT_SETTING FONT ＭＳ Ｐ明朝
 *
 * これらの設定はD_TEXTと同様、ピクチャを表示する前に行ってください。
 *
 * 対応制御文字一覧（イベントコマンド「文章の表示」と同一です）
 * \V[n]
 * \N[n]
 * \P[n]
 * \G
 * \C[n]
 * \I[n]
 * \{
 * \}
 *
 * 専用制御文字
 * \V[n,m](m桁分のパラメータで指定した文字で埋めた変数の値)
 * \item[n]   n 番のアイテム情報（アイコン＋名称）
 * \weapon[n] n 番の武器情報（アイコン＋名称）
 * \armor[n]  n 番の防具情報（アイコン＋名称）
 * \skill[n]  n 番のスキル情報（アイコン＋名称）
 * \state[n]  n 番のステート情報（アイコン＋名称）
 * \oc[c] アウトラインカラーを「c」に設定(※1)
 * \ow[n] アウトライン幅を「n」に設定(例:\ow[5])
 * \f[b] フォントの太字化
 * \f[i] フォントのイタリック化
 * \f[n] フォントの太字とイタリックを通常に戻す
 *
 * ※1 アウトラインカラーの指定方法
 * \oc[red]  色名で指定
 * \oc[rgb(0,255,0)] カラーコードで指定
 * \oc[2] 文字色番号\c[n]と同様のもので指定
 *
 * 背景にウィンドウを表示しているときにカーソルを表示します。
 * このコマンドは動的文字列ピクチャを表示後に実行してください。
 *  D_TEXT_WINDOW_CURSOR 1 ON  # ピクチャ[1]にウィンドウカーソルを表示
 *  D_TEXT_WINDOW_CURSOR 2 OFF # ピクチャ[2]にウィンドウカーソルを消去
 *
 * カーソルのアクティブ状態を変更するコマンドは以下の通りです。
 *  D_TEXT_WINDOW_CURSOR_ACTIVE 2 ON  # ピクチャ[1]のカーソルをアクティブ
 *  D_TEXT_WINDOW_CURSOR_ACTIVE 1 OFF # ピクチャ[1]のカーソルをストップ
 *
 * カーソル矩形の座標を指定する場合は以下の通りです。
 *  D_TEXT_WINDOW_CURSOR 1 ON 0 0 100 100  # ピクチャ[1]に[0,0,100,100]のサイズの
 *                                         # ウィンドウカーソルを表示
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
(function () {
  "use strict";

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

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

  var getArgString = function (arg, upperFlg) {
    arg = convertEscapeCharacters(arg);
    return upperFlg ? arg.toUpperCase() : arg;
  };

  var getArgBoolean = function (arg) {
    return (arg || "").toUpperCase() === "ON";
  };

  var connectArgs = function (args, startIndex, endIndex) {
    if (arguments.length < 2) startIndex = 0;
    if (arguments.length < 3) endIndex = args.length;
    var text = "";
    for (var i = startIndex; i < endIndex; i++) {
      text += args[i];
      if (i < endIndex - 1) text += " ";
    }
    return text;
  };

  var convertEscapeCharacters = function (text) {
    if (text === undefined || text === null) text = "";
    var window = SceneManager.getHiddenWindow();
    return window ? window.convertEscapeCharacters(text) : text;
  };

  var getUsingVariables = function (text) {
    var usingVariables = [];

    text = text.replace(/\\/g, "\x1b");
    text = text.replace(/\x1b\x1b/g, "\\");
    text = text.replace(
      /\x1bV\[(\d+),\s*(\d+)]/gi,
      function () {
        var number = parseInt(arguments[1], 10);
        usingVariables.push(number);
        return $gameVariables.value(number);
      }.bind(this)
    );
    text = text.replace(
      /\x1bV\[(\d+)]/gi,
      function () {
        var number = parseInt(arguments[1], 10);
        usingVariables.push(number);
        return $gameVariables.value(number);
      }.bind(this)
    );
    text = text.replace(
      /\x1bV\[(\d+)]/gi,
      function () {
        var number = parseInt(arguments[1], 10);
        usingVariables.push(number);
        return $gameVariables.value(number);
      }.bind(this)
    );
    return usingVariables;
  };

  /**
   * Create plugin parameter. param[paramName] ex. param.commandPrefix
   * @param pluginName plugin name(EncounterSwitchConditions)
   * @returns {Object} Created parameter
   */
  var createPluginParameter = function (pluginName) {
    var paramReplacer = function (key, value) {
      if (value === "null") {
        return value;
      }
      if (value[0] === '"' && value[value.length - 1] === '"') {
        return value;
      }
      try {
        return JSON.parse(value);
      } catch (e) {
        return value;
      }
    };
    var parameter = JSON.parse(
      JSON.stringify(PluginManager.parameters(pluginName), paramReplacer)
    );
    PluginManager.setParameters(pluginName, parameter);
    return parameter;
  };
  var textDecParam = createPluginParameter("TextDecoration");
  var param = createPluginParameter("DTextPicture");

  //=============================================================================
  // Game_Interpreter
  //  プラグインコマンド[D_TEXT]を追加定義します。
  //=============================================================================
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.apply(this, arguments);
    this.pluginCommandDTextPicture(command, args);
  };

  // Resolve conflict for YEP_PluginCmdSwVar.js
  var _Game_Interpreter_processPluginCommandSwitchVariables =
    Game_Interpreter.prototype.processPluginCommandSwitchVariables;
  Game_Interpreter.prototype.processPluginCommandSwitchVariables = function () {
    if (this._params[0].toUpperCase().indexOf("D_TEXT") >= 0) {
      return;
    }
    _Game_Interpreter_processPluginCommandSwitchVariables.apply(
      this,
      arguments
    );
  };

  Game_Interpreter.textAlignMapper = {
    LEFT: 0,
    CENTER: 1,
    RIGHT: 2,
    左: 0,
    中央: 1,
    右: 2,
  };

  Game_Interpreter.prototype.pluginCommandDTextPicture = function (
    command,
    args
  ) {
    switch (getCommandName(command)) {
      case "D_TEXT":
        if (isNaN(args[args.length - 1]) || args.length === 1)
          args.push($gameScreen.dTextSize || 28);
        var fontSize = getArgNumber(args.pop());
        $gameScreen.setDTextPicture(connectArgs(args).replace(/_/g, ' '), fontSize);
        break;
      case "D_TEXT_SETTING":
        switch (getCommandName(args[0])) {
          case "ALIGN":
            $gameScreen.dTextAlign = isNaN(args[1])
              ? Game_Interpreter.textAlignMapper[getArgString(args[1], true)]
              : getArgNumber(args[1], 0, 2);
            break;
          case "BG_COLOR":
            $gameScreen.dTextBackColor = getArgString(connectArgs(args, 1));
            break;
          case "BG_GRADATION_LEFT":
            $gameScreen.dTextGradationLeft = getArgNumber(args[1], 0);
            break;
          case "BG_GRADATION_RIGHT":
            $gameScreen.dTextGradationRight = getArgNumber(args[1], 0);
            break;
          case "FONT":
            args.shift();
            $gameScreen.setDtextFont(getArgString(connectArgs(args)));
            break;
          case "REAL_TIME":
            $gameScreen.dTextRealTime = getArgBoolean(args[1]);
            break;
          case "WINDOW":
            $gameScreen.dWindowFrame = getArgBoolean(args[1]);
            break;
        }
        break;
      case "D_TEXT_WINDOW_CURSOR":
        var windowRect = null;
        if (getArgBoolean(args[1])) {
          windowRect = {
            x: getArgNumber(args[3] || "", 0),
            y: getArgNumber(args[4] || "", 0),
            width: getArgNumber(args[5] || "", 0),
            height: getArgNumber(args[6] || "", 0),
          };
        }
        $gameScreen.setDTextWindowCursor(getArgNumber(args[0], 0), windowRect);
        break;
      case "D_TEXT_WINDOW_CURSOR_ACTIVE":
        $gameScreen.setDTextWindowCursorActive(
          getArgNumber(args[0], 0),
          getArgBoolean(args[1])
        );
        break;
    }
  };

  //=============================================================================
  // Game_Variables
  //  値を変更した変数の履歴を取得します。
  //=============================================================================
  var _Game_Variables_setValue = Game_Variables.prototype.setValue;
  Game_Variables.prototype.setValue = function (variableId, value) {
    variableId = parseInt(variableId);
    if (this.value(variableId) !== value) {
      this._changedVariables = this.getChangedVariables();
      if (!this._changedVariables.contains(variableId)) {
        this._changedVariables.push(variableId);
      }
    }
    _Game_Variables_setValue.apply(this, arguments);
  };

  Game_Variables.prototype.getChangedVariables = function () {
    return this._changedVariables || [];
  };

  Game_Variables.prototype.clearChangedVariables = function () {
    return (this._changedVariables = []);
  };

  //=============================================================================
  // Game_Screen
  //  動的ピクチャ用のプロパティを追加定義します。
  //=============================================================================
  var _Game_Screen_clear = Game_Screen.prototype.clear;
  Game_Screen.prototype.clear = function () {
    _Game_Screen_clear.call(this);
    this.clearDTextPicture();
  };

  Game_Screen.prototype.clearDTextPicture = function () {
    this.dTextValue = null;
    this.dTextOriginal = null;
    this.dTextRealTime = null;
    this.dTextSize = 0;
    this.dTextAlign = 0;
    this.dTextBackColor = null;
    this.dTextFont = null;
    this.dUsingVariables = null;
    this.dWindowFrame = null;
    this.dTextGradationRight = 0;
    this.dTextGradationLeft = 0;
  };

  Game_Screen.prototype.setDTextPicture = function (value, size) {
    if (typeof TranslationManager !== "undefined") {
      TranslationManager.translateIfNeed(value, function (translatedText) {
        value = translatedText;
      });
    }
    this.dUsingVariables = (this.dUsingVariables || []).concat(
      getUsingVariables(value)
    );
    this.dTextValue =
      (this.dTextValue || "") + getArgString(value, false) + "\n";
    this.dTextOriginal = (this.dTextOriginal || "") + value + "\n";
    this.dTextSize = size;
  };

  Game_Screen.prototype.setDTextWindowCursor = function (pictureId, rect) {
    var picture = this.picture(pictureId);
    if (picture) {
      picture.setWindowCursor(rect);
      picture.setWindowCursorActive(true);
    }
  };

  Game_Screen.prototype.setDTextWindowCursorActive = function (
    pictureId,
    value
  ) {
    var picture = this.picture(pictureId);
    if (picture) {
      picture.setWindowCursorActive(value);
    }
  };

  Game_Screen.prototype.getDTextPictureInfo = function () {
    return {
      value: this.dTextValue,
      size: this.dTextSize || 0,
      align: this.dTextAlign || 0,
      color: this.dTextBackColor,
      font: this.dTextFont,
      usingVariables: this.dUsingVariables,
      realTime: this.dTextRealTime,
      originalValue: this.dTextOriginal,
      windowFrame: this.dWindowFrame,
      gradationLeft: this.dTextGradationLeft,
      gradationRight: this.dTextGradationRight,
    };
  };

  Game_Screen.prototype.isSettingDText = function () {
    return !!this.dTextValue;
  };

  Game_Screen.prototype.setDtextFont = function (name) {
    this.dTextFont = name;
  };

  var _Game_Screen_updatePictures = Game_Screen.prototype.updatePictures;
  Game_Screen.prototype.updatePictures = function () {
    _Game_Screen_updatePictures.apply(this, arguments);
    $gameVariables.clearChangedVariables();
  };

  //=============================================================================
  // Game_Picture
  //  動的ピクチャ用のプロパティを追加定義し、表示処理を動的ピクチャ対応に変更します。
  //=============================================================================
  var _Game_Picture_initBasic = Game_Picture.prototype.initBasic;
  Game_Picture.prototype.initBasic = function () {
    _Game_Picture_initBasic.call(this);
    this.dTextValue = null;
    this.dTextInfo = null;
  };

  var _Game_Picture_show = Game_Picture.prototype.show;
  Game_Picture.prototype.show = function (
    name,
    origin,
    x,
    y,
    scaleX,
    scaleY,
    opacity,
    blendMode
  ) {
    if ($gameScreen.isSettingDText() && !name) {
      arguments[0] = Date.now().toString();
      this.dTextInfo = $gameScreen.getDTextPictureInfo();
      $gameScreen.clearDTextPicture();
    } else {
      this.dTextInfo = null;
    }
    _Game_Picture_show.apply(this, arguments);
  };

  var _Game_Picture_update = Game_Picture.prototype.update;
  Game_Picture.prototype.update = function () {
    _Game_Picture_update.apply(this, arguments);
    if (this.dTextInfo && this.dTextInfo.realTime) {
      this.updateDTextVariable();
    }
  };

  Game_Picture.prototype.updateDTextVariable = function () {
    $gameVariables.getChangedVariables().forEach(function (variableId) {
      if (this.dTextInfo.usingVariables.contains(variableId)) {
        this._name = Date.now().toString();
        this.dTextInfo.value = getArgString(
          this.dTextInfo.originalValue,
          false
        );
      }
    }, this);
  };

  Game_Picture.prototype.setWindowCursor = function (rect) {
    this._windowCursor = rect;
  };

  Game_Picture.prototype.getWindowCursor = function () {
    return this._windowCursor;
  };

  Game_Picture.prototype.setWindowCursorActive = function (value) {
    this._windowCursorActive = value;
  };

  Game_Picture.prototype.getWindowCursorActive = function () {
    return this._windowCursorActive;
  };

  //=============================================================================
  // SceneManager
  //  文字描画用の隠しウィンドウを取得します。
  //=============================================================================
  SceneManager.getHiddenWindow = function () {
    if (!this._hiddenWindow) {
      this._hiddenWindow = new Window_Hidden(1, 1, 1, 1);
    }
    return this._hiddenWindow;
  };

  SceneManager.getSpriteset = function () {
    return this._scene._spriteset;
  };

  //=============================================================================
  // Window_Base
  //  文字列変換処理に追加制御文字を設定します。
  //=============================================================================
  var _Window_Base_convertEscapeCharacters =
    Window_Base.prototype.convertEscapeCharacters;
  Window_Base.prototype.convertEscapeCharacters = function (text) {
    text = _Window_Base_convertEscapeCharacters.call(this, text);
    text = text.replace(
      /\x1bV\[(\d+),\s*(\d+)]/gi,
      function () {
        return this.getVariablePadCharacter(
          $gameVariables.value(parseInt(arguments[1], 10)),
          arguments[2]
        );
      }.bind(this)
    );
    text = text.replace(
      /\x1bITEM\[(\d+)]/gi,
      function () {
        var item = $dataItems[getArgNumber(arguments[1], 1, $dataItems.length)];
        return this.getItemInfoText(item);
      }.bind(this)
    );
    text = text.replace(
      /\x1bWEAPON\[(\d+)]/gi,
      function () {
        var item =
          $dataWeapons[getArgNumber(arguments[1], 1, $dataWeapons.length)];
        return this.getItemInfoText(item);
      }.bind(this)
    );
    text = text.replace(
      /\x1bARMOR\[(\d+)]/gi,
      function () {
        var item =
          $dataArmors[getArgNumber(arguments[1], 1, $dataArmors.length)];
        return this.getItemInfoText(item);
      }.bind(this)
    );
    text = text.replace(
      /\x1bSKILL\[(\d+)]/gi,
      function () {
        var item =
          $dataSkills[getArgNumber(arguments[1], 1, $dataSkills.length)];
        return this.getItemInfoText(item);
      }.bind(this)
    );
    text = text.replace(
      /\x1bSTATE\[(\d+)]/gi,
      function () {
        var item =
          $dataStates[getArgNumber(arguments[1], 1, $dataStates.length)];
        return this.getItemInfoText(item);
      }.bind(this)
    );
    return text;
  };

  Window_Base.prototype.getItemInfoText = function (item) {
    if (!item) {
      return "";
    }
    return (
      (this.isValidDTextIconSwitch() ? "\x1bi[" + item.iconIndex + "]" : "") +
      item.name
    );
  };

  Window_Base.prototype.isValidDTextIconSwitch = function () {
    return (
      !param.itemIconSwitchId || $gameSwitches.value(param.itemIconSwitchId)
    );
  };

  Window_Base.prototype.getVariablePadCharacter = function (value, digit) {
    var numText = String(Math.abs(value));
    var pad = String(param.padCharacter) || "0";
    while (numText.length < digit) {
      numText = pad + numText;
    }
    return (value < 0 ? "-" : "") + numText;
  };

  //=============================================================================
  // Sprite_Picture
  //  画像の動的生成を追加定義します。
  //=============================================================================
  var _Sprite_Picture_update = Sprite_Picture.prototype.update;
  Sprite_Picture.prototype.update = function () {
    _Sprite_Picture_update.apply(this, arguments);
    if (this._frameWindow) {
      this.updateFrameWindow();
    }
  };

  Sprite_Picture.prototype.updateFrameWindow = function () {
    var padding = this._frameWindow.standardPadding();
    this._frameWindow.x =
      this.x - this.anchor.x * this.width * this.scale.x - padding;
    this._frameWindow.y =
      this.y - this.anchor.y * this.height * this.scale.y - padding;
    this._frameWindow.opacity = this.opacity;
    if (!this.visible) {
      this.removeFrameWindow();
      return;
    }
    if (!this._addFrameWindow) {
      this.addFrameWindow();
    }
    if (Graphics.frameCount % 2 === 0) {
      this.adjustScaleFrameWindow();
    }
    this.updateFrameWindowCursor();
  };

  Sprite_Picture.prototype.updateFrameWindowCursor = function () {
    var picture = this.picture();
    if (!picture) {
      return;
    }
    var rect = picture.getWindowCursor();
    if (rect) {
      var width = rect.width || this._frameWindow.contentsWidth();
      var height = rect.width || this._frameWindow.contentsHeight();
      this._frameWindow.setCursorRect(0, 0, width, height);
      this._frameWindow.active = picture.getWindowCursorActive();
    } else {
      this._frameWindow.setCursorRect(0, 0, 0, 0);
    }
  };

  Sprite_Picture.prototype.adjustScaleFrameWindow = function () {
    var padding = this._frameWindow.standardPadding();
    var newFrameWidth = Math.floor(this.width * this.scale.x + padding * 2);
    var newFrameHeight = Math.floor(this.height * this.scale.x + padding * 2);
    if (
      this._frameWindow.width !== newFrameWidth ||
      this._frameWindow.height !== newFrameHeight
    ) {
      this._frameWindow.move(
        this._frameWindow.x,
        this._frameWindow.y,
        newFrameWidth,
        newFrameHeight
      );
    }
  };

  Sprite_Picture.prototype.addFrameWindow = function () {
    var parent = this.parent;
    if (parent) {
      var index = parent.getChildIndex(this);
      parent.addChildAt(this._frameWindow, index);
      this._addFrameWindow = true;
    }
  };

  Sprite_Picture.prototype.removeFrameWindow = function () {
    var parent = this.parent;
    if (parent) {
      parent.removeChild(this._frameWindow);
      this._frameWindow = null;
      this._addFrameWindow = false;
    }
  };

  var _Sprite_Picture_loadBitmap = Sprite_Picture.prototype.loadBitmap;
  Sprite_Picture.prototype.loadBitmap = function () {
    this.dTextInfo = this.picture().dTextInfo;
    if (this.dTextInfo) {
      this.makeDynamicBitmap();
    } else {
      _Sprite_Picture_loadBitmap.apply(this, arguments);
    }
  };

  Sprite_Picture.prototype.makeDynamicBitmap = function () {
    this.textWidths = [];
    this.hiddenWindow = SceneManager.getHiddenWindow();
    this.hiddenWindow.resetFontSettings(this.dTextInfo);
    var bitmapVirtual = new Bitmap_Virtual();
    this._processText(bitmapVirtual);
    this.hiddenWindow.resetFontSettings(this.dTextInfo);
    this.bitmap = new Bitmap(bitmapVirtual.width, bitmapVirtual.height);
    this.applyTextDecoration();
    this.bitmap.fontFace = this.hiddenWindow.contents.fontFace;
    if (this.dTextInfo.color) {
      this.bitmap.fillAll(this.dTextInfo.color);
      var h = this.bitmap.height;
      var w = this.bitmap.width;
      var gradationLeft = this.dTextInfo.gradationLeft;
      if (gradationLeft > 0) {
        this.bitmap.clearRect(0, 0, gradationLeft, h);
        this.bitmap.gradientFillRect(
          0,
          0,
          gradationLeft,
          h,
          "rgba(0, 0, 0, 0)",
          this.dTextInfo.color,
          false
        );
      }
      var gradationRight = this.dTextInfo.gradationRight;
      if (gradationRight > 0) {
        this.bitmap.clearRect(w - gradationRight, 0, gradationRight, h);
        this.bitmap.gradientFillRect(
          w - gradationRight,
          0,
          gradationRight,
          h,
          this.dTextInfo.color,
          "rgba(0, 0, 0, 0)",
          false
        );
      }
    }
    this._processText(this.bitmap);
    this._colorTone = [0, 0, 0, 0];
    if (this._frameWindow) {
      this.removeFrameWindow();
    }
    if (this.dTextInfo.windowFrame) {
      var scaleX = this.picture().scaleX() / 100;
      var scaleY = this.picture().scaleY() / 100;
      this.makeFrameWindow(
        bitmapVirtual.width * scaleX,
        bitmapVirtual.height * scaleY
      );
    }
    this.hiddenWindow = null;
  };

  Sprite_Picture.prototype.applyTextDecoration = function () {
    if (textDecParam.Mode >= 0) {
      this.bitmap.outlineColor = "rgba(%1,%2,%3,%4)".format(
        textDecParam.Red,
        textDecParam.Green,
        textDecParam.Blue,
        textDecParam.Alpha / 255
      );
      this.bitmap.decorationMode = textDecParam.Mode;
    }
  };

  Sprite_Picture.prototype.makeFrameWindow = function (width, height) {
    var padding = this.hiddenWindow.standardPadding();
    this._frameWindow = new Window_BackFrame(
      0,
      0,
      width + padding * 2,
      height + padding * 2
    );
    if (param.frameWindowSkin) {
      this._frameWindow.windowskin = ImageManager.loadSystem(
        param.frameWindowSkin
      );
    }
  };

  Sprite_Picture.prototype._processText = function (bitmap) {
    var textState = {
      index: 0,
      x: 0,
      y: 0,
      text: this.dTextInfo.value,
      left: 0,
      line: -1,
      height: 0,
    };
    this._processNewLine(textState, bitmap);
    textState.height = this.hiddenWindow.calcTextHeight(textState, false);
    textState.index = 0;
    while (textState.text[textState.index]) {
      this._processCharacter(textState, bitmap);
    }
  };

  Sprite_Picture.prototype._processCharacter = function (textState, bitmap) {
    if (textState.text[textState.index] === "\x1b") {
      var code = this.hiddenWindow.obtainEscapeCode(textState);
      switch (code) {
        case "C":
          bitmap.textColor = this.hiddenWindow.textColor(
            this.hiddenWindow.obtainEscapeParam(textState)
          );
          break;
        case "I":
          this._processDrawIcon(
            this.hiddenWindow.obtainEscapeParam(textState),
            textState,
            bitmap
          );
          break;
        case "{":
          this.hiddenWindow.makeFontBigger();
          break;
        case "}":
          this.hiddenWindow.makeFontSmaller();
          break;
        case "F":
          switch (
            this.hiddenWindow.obtainEscapeParamString(textState).toUpperCase()
          ) {
            case "I":
              bitmap.fontItalic = true;
              break;
            case "B":
              bitmap.fontBoldFotDtext = true;
              break;
            case "/":
            case "N":
              bitmap.fontItalic = false;
              bitmap.fontBoldFotDtext = false;
              break;
          }
          break;
        case "OC":
          var colorCode = this.hiddenWindow.obtainEscapeParamString(textState);
          var colorIndex = Number(colorCode);
          if (!isNaN(colorIndex)) {
            bitmap.outlineColor = this.hiddenWindow.textColor(colorIndex);
          } else {
            bitmap.outlineColor = colorCode;
          }
          break;
        case "OW":
          bitmap.outlineWidth = this.hiddenWindow.obtainEscapeParam(textState);
          break;
      }
    } else if (textState.text[textState.index] === "\n") {
      this._processNewLine(textState, bitmap);
    } else {
      var c = textState.text[textState.index++];
      var w = this.hiddenWindow.textWidth(c);

      bitmap.fontSize = this.hiddenWindow.contents.fontSize;
      bitmap.drawText(
        c,
        textState.x,
        textState.y,
        w * 2,
        textState.height,
        "left"
      );
      textState.x += w;
    }
  };

  Sprite_Picture.prototype._processNewLine = function (textState, bitmap) {
    if (bitmap instanceof Bitmap_Virtual)
      this.textWidths[textState.line] = textState.x;
    this.hiddenWindow.processNewLine(textState);
    textState.line++;
    if (bitmap instanceof Bitmap)
      textState.x =
        ((bitmap.width - this.textWidths[textState.line]) / 2) *
        this.dTextInfo.align;
  };

  Sprite_Picture.prototype._processDrawIcon = function (
    iconIndex,
    textState,
    bitmap
  ) {
    var iconBitmap = ImageManager.loadSystem("IconSet");
    var pw = Window_Base._iconWidth;
    var ph = Window_Base._iconHeight;
    var sx = (iconIndex % 16) * pw;
    var sy = Math.floor(iconIndex / 16) * ph;
    bitmap.blt(
      iconBitmap,
      sx,
      sy,
      pw,
      ph,
      textState.x + 2,
      textState.y + (textState.height - ph) / 2
    );
    textState.x += Window_Base._iconWidth + 4;
  };

  //=============================================================================
  // Bitmap_Virtual
  //  サイズを計算するための仮想ビットマップクラス
  //=============================================================================
  function Bitmap_Virtual() {
    this.initialize.apply(this, arguments);
  }

  Bitmap_Virtual.prototype.initialize = function () {
    this.window = SceneManager.getHiddenWindow();
    this.width = 0;
    this.height = 0;
  };

  Bitmap_Virtual.prototype.drawText = function (text, x, y) {
    var baseWidth = this.window.textWidth(text);
    var fontSize = this.window.contents.fontSize;
    if (this.fontItalic) {
      baseWidth += Math.floor(fontSize / 6);
    }
    if (this.fontBoldFotDtext) {
      baseWidth += 2;
    }
    this.width = Math.max(x + baseWidth, this.width);
    this.height = Math.max(y + fontSize + 8, this.height);
  };

  Bitmap_Virtual.prototype.blt = function (
    source,
    sx,
    sy,
    sw,
    sh,
    dx,
    dy,
    dw,
    dh
  ) {
    this.width = Math.max(dx + (dw || sw), this.width);
    this.height = Math.max(dy + (dh || sh), this.height);
  };

  //=============================================================================
  // Window_BackFrame
  //  バックフレームウィンドウ
  //=============================================================================
  function Window_BackFrame() {
    this.initialize.apply(this, arguments);
  }

  Window_BackFrame.prototype.backOpacity = null;

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

  Window_BackFrame.prototype.standardPadding = function () {
    return param.frameWindowPadding;
  };

  //=============================================================================
  // Window_Hidden
  //  文字描画用の隠しウィンドウ
  //=============================================================================
  function Window_Hidden() {
    this.initialize.apply(this, arguments);
  }

  Window_Hidden.prototype.backOpacity = null;

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

  Window_Hidden.prototype._createAllParts = function () {
    this._windowBackSprite = {};
    this._windowSpriteContainer = {};
    this._windowContentsSprite = new Sprite();
    this.addChild(this._windowContentsSprite);
  };

  Window_Hidden.prototype._refreshAllParts = function () {};

  Window_Hidden.prototype._refreshBack = function () {};

  Window_Hidden.prototype._refreshFrame = function () {};

  Window_Hidden.prototype._refreshCursor = function () {};

  Window_Hidden.prototype._refreshArrows = function () {};

  Window_Hidden.prototype._refreshPauseSign = function () {};

  Window_Hidden.prototype.updateTransform = function () {};

  Window_Hidden.prototype.resetFontSettings = function (dTextInfo) {
    if (dTextInfo) {
      var customFont = dTextInfo.font ? dTextInfo.font + "," : "";
      this.contents.fontFace = customFont + this.standardFontFace();
      this.contents.fontSize = dTextInfo.size || this.standardFontSize();
    } else {
      Window_Base.prototype.resetFontSettings.apply(this, arguments);
    }
  };

  Window_Hidden.prototype.obtainEscapeParamString = function (textState) {
    var arr = /^\[.+?]/.exec(textState.text.slice(textState.index));
    if (arr) {
      textState.index += arr[0].length;
      return arr[0].substring(1, arr[0].length - 1);
    } else {
      return "";
    }
  };

  var _Window_Hidden_calcTextHeight = Window_Hidden.prototype.calcTextHeight;
  Window_Hidden.prototype.calcTextHeight = function (textState, all) {
    var result = _Window_Hidden_calcTextHeight.apply(this, arguments);
    if (param.lineSpacingVariableId) {
      result += $gameVariables.value(param.lineSpacingVariableId);
    }
    return result;
  };

  //=============================================================================
  // Bitmap
  //  太字対応
  //=============================================================================
  var _Bitmap__makeFontNameText = Bitmap.prototype._makeFontNameText;
  Bitmap.prototype._makeFontNameText = function () {
    return (
      (this.fontBoldFotDtext ? "bold " : "") +
      _Bitmap__makeFontNameText.apply(this, arguments)
    );
  };
})();


code:
// DarkPlasma_SkipCommandPersonal
// Copyright (c) 2020 DarkPlasma
// This software is released under the MIT license.
// http://opensource.org/licenses/mit-license.php

/**
 * 2020/03/10 1.1.0 パーティメンバーが一人の場合のみ有効にするパラメータを追加
 *                  メニューや戦闘におけるアイテム/スキルの使用対象選択をスキップする機能を追加
 * 2020/03/09 1.0.0 公開
 */

/*:
 * @plugindesc キャラクター選択をスキップするプラグイン
 * @author DarkPlasma
 * @license MIT
 *
 * @param Enable Only When Solo Party
 * @desc パーティメンバーが一人の場合のみ有効にする
 * @text ソロ時のみ有効
 * @type boolean
 * @default true
 *
 * @param Skip Select Item And Skill Target In Menu
 * @desc メニューでのアイテム/スキルの使用対象選択をスキップする
 * @text メニューアイテム対象選択省略
 * @type boolean
 * @default true
 *
 * @param Skip Select Item And SKill Target For Friend In Battle
 * @desc 戦闘での味方に対するアイテム/スキルの使用対象選択をスキップする
 * @text 戦闘時アイテム対象選択省略
 * @type boolean
 * @default true
 *
 * @help
 * このプラグインを導入すると、メニュー画面などでのキャラクター選択をスキップし、
 * 強制的に先頭のキャラクターを選択します。
 *
 * プラグインパラメータの設定により、
 * アイテムやスキルの使用対象選択をスキップできます。
 */

(function () {
  "use strict";
  const pluginName = document.currentScript.src.replace(
    /^.*\/(.*).js$/,
    function () {
      return arguments[1];
    }
  );
  const pluginParameters = PluginManager.parameters(pluginName);

  const settings = {
    enableOnlyWhenSolo:
      String(pluginParameters["Enable Only When Solo Party"] || "true") ===
      "true",
    skipSelectTargetInMenu:
      String(
        pluginParameters["Skip Select Item And Skill Target In Menu"] || "true"
      ) === "true",
    skipSelectTargetInBattle:
      String(
        pluginParameters[
          "Skip Select Item And SKill Target For Friend In Battle"
        ]
      ) === "true",
  };

  Game_Party.prototype.isSoloParty = function () {
    return this.members().length === 1;
  };

  Scene_Menu.prototype.skipCommandPersonal = function () {
    return !settings.enableOnlyWhenSolo || $gameParty.isSoloParty();
  };

  const _Scene_Menu_commandPersonal = Scene_Menu.prototype.commandPersonal;
  Scene_Menu.prototype.commandPersonal = function () {
    if (this.skipCommandPersonal()) {
      $gameParty.setTargetActor($gameParty.leader());
      this.onPersonalOk();
    } else {
      _Scene_Menu_commandPersonal.call(this);
    }
  };

  Scene_ItemBase.prototype.skipSelectTarget = function () {
    return (
      settings.skipSelectTargetInMenu &&
      (!settings.enableOnlyWhenSolo || $gameParty.isSoloParty())
    );
  };

  const _Scene_ItemBase_determineItem = Scene_ItemBase.prototype.determineItem;
  Scene_ItemBase.prototype.determineItem = function () {
    if (this.skipSelectTarget()) {
      let action = new Game_Action(this.user());
      action.setItemObject(this.item());
      if (action.isForFriend()) {
        this._actorWindow.select(0);
        this.onActorOk();
        this.activateItemWindow();
      } else {
        _Scene_ItemBase_determineItem.call(this);
      }
    } else {
      _Scene_ItemBase_determineItem.call(this);
    }
  };

  Scene_Battle.prototype.skipSelectTarget = function () {
    return (
      settings.skipSelectTargetInBattle &&
      (!settings.enableOnlyWhenSolo || $gameParty.isSoloParty())
    );
  };

  const _Scene_Battle_selectActorSelection =
    Scene_Battle.prototype.selectActorSelection;
  Scene_Battle.prototype.selectActorSelection = function () {
    if (this.skipSelectTarget()) {
      this._actorWindow.select(0);
      this.onActorOk();
    } else {
      _Scene_Battle_selectActorSelection.call(this);
    }
  };
})();