code:
//=============================================================================
// ConfusionExtend.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015-2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.4.0 2017/10/07 混乱スキルのターゲット選択方法にラストターゲット(直前に選択した対象)を追加しました。
// 1.3.0 2017/06/10 制約「敵を攻撃」の場合に味方対象スキルを実行した場合、対象を味方にするよう修正
//                  使用可能スキルに除外設定を追加
// 1.2.0 2017/05/02 使用可能なスキルの中からランダムで使用する機能を追加
// 1.1.0 2016/11/12 裏切り機能と味方対象スキルの対象を反転させる機能を追加
// 1.0.0 2016/08/13 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc Confusion Extend Plugin
 * @author triacontane
 *
 * @param TargetFriendSkill
 * @desc ONにすると行動制約が「味方を攻撃」のときに味方対象のスキルを使用すると、敵を対象にします。
 * @default OFF
 *
 * @help 混乱系（行動制約のプルダウンの選択値が「1」～「3」）ステートの
 * 指定内容を以下の通り拡張します。
 * ・通常攻撃ではなく指定したスキル（複数指定可能）を勝手に使用する。
 * ・スキルが全て使用できない場合に使用する予備スキルも指定可能。
 * ・バトラーが元々持っているスキルを勝手に使用する。
 *
 * 誰をターゲットにするかは、ステートの行動制約の種類と使用スキルの効果範囲
 * およびメモ欄で設定した値によって決まります。
 *
 * ・スキルの効果範囲が「使用者」の場合
 * 行動制約の種類とは無関係に、対象は必ず「使用者」になります。
 *
 * ・行動制約が「敵を攻撃」の場合
 * 対象は「敵単体」(メモ欄指定対象もしくはランダム)か「敵全体」になります。
 *
 * ・行動制約が「誰かを攻撃」の場合
 * 対象は「敵単体」(メモ欄指定対象もしくはランダム)か「敵全体」もしくは
 * 「味方単体」(メモ欄指定対象もしくはランダム)か「味方全体」になります。
 *
 * ・行動制約が「味方を攻撃」の場合
 * 対象は「味方単体」(メモ欄指定対象もしくはランダム)か「味方全体」になります。
 *
 * 1. ステートのデータベースで行動制作のプルダウンを指定してください。
 * ・敵を攻撃
 * ・誰かを攻撃
 * ・味方を攻撃
 *
 * 2. ステートのメモ欄を以下の通り指定してください。
 * <CEスキル1:3>      # 通常攻撃の代わりにID[3..5]のスキルが使用されます。
 * <CEスキル2:4>      # 4番目以降も同様に指定可能です。
 * <CEスキル3:5>      #
 * <CE使用可能スキル> # 使用可能なスキルが全て候補になります。
 * <CE予備スキル:6>   # 指定されたスキルがMP不足等の理由ですべて
 *                      使用できない場合、ID[6]のスキルが使用されます。
 * <CEターゲット:0>   # 単体スキルの対象を[0]番目のキャラクターに指定します。
 *                      メモ欄の指定がない場合はランダムで決定されます。
 *                      -1を指定するとラストターゲットになります。
 *
 * 使用可能スキルを指定する際、使わせたくないスキルを別途指定できます。
 * <CE使用可能スキル:1,2,3> # 使用可能スキルのうち[1][2][3]を候補から外します。
 *
 * ・追加機能
 * 裏切り機能を有効にすると対象のステートが有効になっているバトラーが
 * 敵や混乱スキルの攻撃対象から外れ、さらにそのバトラー以外が戦闘不能になると
 * 全滅扱いになります。
 *
 * 特徴を有するデータベースのメモ欄に、以下の通り記述してください。
 * <CE裏切り>    # 対象バトラーが一時的に味方から外れます。
 * <CEBetrayal>  # 同上
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc 混乱ステート拡張プラグイン
 * @author トリアコンタン
 *
 * @param 味方対象スキルの対象
 * @desc ONにすると行動制約が「味方を攻撃」のときに味方対象のスキルを使用すると、敵を対象にします。
 * @default OFF
 *
 * @help 混乱系（行動制約のプルダウンの選択値が「1」～「3」）ステートの
 * 指定内容を拡張し、通常攻撃ではなくスキル（複数指定可能）を指定したり
 * さらにそれらのスキルがすべて使用できない場合に使用する予備スキルも
 * 指定できます。
 *
 * 誰をターゲットにするかは、ステートの行動制約の種類と使用スキルの効果範囲
 * およびメモ欄で設定した値によって決まります。
 *
 * ・スキルの効果範囲が「使用者」の場合
 * 行動制約の種類とは無関係に、対象は必ず「使用者」になります。
 *
 * ・行動制約が「敵を攻撃」の場合
 * 対象は「敵単体」(メモ欄指定対象もしくはランダム)か「敵全体」になります。
 *
 * ・行動制約が「誰かを攻撃」の場合
 * 対象は「敵単体」(メモ欄指定対象もしくはランダム)か「敵全体」もしくは
 * 「味方単体」(メモ欄指定対象もしくはランダム)か「味方全体」になります。
 *
 * ・行動制約が「味方を攻撃」の場合
 * 対象は「味方単体」(メモ欄指定対象もしくはランダム)か「味方全体」になります。
 *
 * 1. ステートのデータベースで行動制作のプルダウンを指定してください。
 * ・敵を攻撃
 * ・誰かを攻撃
 * ・味方を攻撃
 *
 * 2. ステートのメモ欄を以下の通り指定してください。
 * <CEスキル1:3>      # 通常攻撃の代わりにID[3..5]のスキルが使用されます。
 * <CEスキル2:4>      # 4番目以降も同様に指定可能です。
 * <CEスキル3:5>      #
 * <CE使用可能スキル> # 使用可能なスキルが全て候補になります。
 * <CE予備スキル:6>   # 指定されたスキルがMP不足等の理由ですべて
 *                      使用できない場合、ID[6]のスキルが使用されます。
 * <CEターゲット:0>   # 単体スキルの対象を[0]番目のキャラクターに指定します。
 *                      メモ欄の指定がない場合はランダムで決定されます。
 *                      -1を指定するとラストターゲットになります。
 *
 * 使用可能スキルを指定する際、使わせたくないスキルを別途指定できます。
 * <CE使用可能スキル:1,2,3> # 使用可能スキルのうち[1][2][3]を候補から外します。
 *
 * ・追加機能
 * 裏切り機能を有効にすると対象のステートが有効になっているバトラーが
 * 敵や混乱スキルの攻撃対象から外れ、さらにそのバトラー以外が戦闘不能になると
 * 全滅扱いになります。
 *
 * 特徴を有するデータベースのメモ欄に、以下の通り記述してください。
 * <CE裏切り>    # 対象バトラーが一時的に味方から外れます。
 * <CEBetrayal>  # 同上
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";
  var pluginName = "ConfusionExtend";
  var metaTagPrefix = "CE";

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

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

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

  var getArgArrayNumber = function (args, min, max) {
    var values = getArgArrayString(args, false);
    if (arguments.length < 2) min = -Infinity;
    if (arguments.length < 3) max = Infinity;
    for (var i = 0; i < values.length; i++) {
      values[i] = (parseFloat(values[i], 10) || 0).clamp(min, max);
    }
    return values;
  };

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

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

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

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

  //=============================================================================
  // パラメータの取得と整形
  //=============================================================================
  var paramTargetFriendSkill = getParamBoolean([
    "TargetFriendSkill",
    "味方対象スキルの対象",
  ]);

  //=============================================================================
  // Game_BattlerBase
  //  行動制約が有効なステートデータを取得します。
  //=============================================================================
  Game_BattlerBase.prototype.getRestrictStates = function () {
    var restriction = this.restriction();
    if (restriction === 0 || restriction >= 4) return [];
    return this.states().filter(function (state) {
      return state.restriction === restriction;
    });
  };

  Game_BattlerBase.prototype.getRestrictState = function () {
    return this.getRestrictStates().sort(
      this.compareOrderStatePriority.bind(this)
    )[0];
  };

  Game_BattlerBase.prototype.compareOrderStatePriority = function (
    stateA,
    stateB
  ) {
    return stateA.priority - stateB.priority;
  };

  Game_BattlerBase.prototype.isBetrayer = function () {
    return this.traitObjects().some(function (traitObject) {
      return getMetaValues(traitObject, ["裏切り", "Betrayal"]);
    });
  };

  Game_BattlerBase.prototype.getUsableSkillIdList = function () {
    return [this.attackSkillId(), this.guardSkillId()];
  };

  //=============================================================================
  // Game_Battler
  //  ラストターゲットを取得します。
  //=============================================================================
  /**
   * ラストターゲットを取得します。
   * @returns {number} ラストターゲット
   */
  Game_Battler.prototype.getLastTargetIndex = function () {
    return this._lastTargetIndex;
  };

  //=============================================================================
  // Game_Actor
  //  使用可能なスキル一覧を取得します。
  //=============================================================================
  Game_Actor.prototype.getUsableSkillIdList = function () {
    var skillIds = this.usableSkills().map(function (skill) {
      return skill.id;
    });
    return Game_BattlerBase.prototype.getUsableSkillIdList
      .call(this)
      .concat(skillIds);
  };

  //=============================================================================
  // Game_Enemy
  //  使用可能なスキル一覧を取得します。
  //=============================================================================
  Game_Enemy.prototype.getUsableSkillIdList = function () {
    var actionList = this.enemy().actions.filter(function (a) {
      return this.isActionValid(a);
    }, this);
    return actionList.map(function (action) {
      return action.skillId;
    });
  };

  //=============================================================================
  // Game_Unit
  //  裏切り機能を追加します。
  //=============================================================================
  var _Game_Unit_aliveMembers = Game_Unit.prototype.aliveMembers;
  Game_Unit.prototype.aliveMembers = function () {
    var members = _Game_Unit_aliveMembers.apply(this, arguments);
    return members.filter(function (member) {
      return !member.isBetrayer();
    });
  };

  //=============================================================================
  // Game_Action
  //  混乱時のスキルを別途設定します。
  //=============================================================================
  var _Game_Action_setConfusion = Game_Action.prototype.setConfusion;
  Game_Action.prototype.setConfusion = function () {
    _Game_Action_setConfusion.apply(this, arguments);
    var skillIds = this.getConfusionSkills();
    if (!skillIds) return;
    skillIds = skillIds.filter(
      function (skillId) {
        return this.subject().canUse($dataSkills[skillId]);
      }.bind(this)
    );
    if (skillIds.length > 0) {
      this.setConfusionSkill(skillIds);
    } else {
      this.setConfusionSpareSkill();
    }
  };

  Game_Action.prototype.getConfusionSkills = function () {
    var state = this.getRestrictState();
    if (!state) return null;
    var skillIds = [],
      i = 1;
    while (i) {
      var metaValue = getMetaValues(state, ["スキル" + i, "Skill" + i]);
      if (metaValue) {
        skillIds.push(getArgNumber(metaValue, 1));
        i++;
      } else {
        i = i > 10 ? null : i + 1;
      }
    }
    return skillIds.concat(this.getConfusionUsableSkills(state));
  };

  Game_Action.prototype.getConfusionUsableSkills = function (state) {
    var usableSkillInclude = getMetaValues(state, [
      "使用可能スキル",
      "UsableSkill",
    ]);
    var skillList = [];
    if (usableSkillInclude) {
      skillList = this.subject().getUsableSkillIdList();
      if (usableSkillInclude !== true) {
        skillList = this.filterConfusionUsableSkills(
          skillList,
          usableSkillInclude
        );
      }
    }
    return skillList;
  };

  Game_Action.prototype.filterConfusionUsableSkills = function (
    skillList,
    usableSkillInclude
  ) {
    var filterList = getArgArrayNumber(usableSkillInclude);
    skillList = skillList.filter(function (skillId) {
      return !filterList.contains(skillId);
    });
    return skillList;
  };

  Game_Action.prototype.getRestrictState = function () {
    return this.subject().getRestrictState();
  };

  Game_Action.prototype.isExistConfusionSkill = function () {
    var skillIds = this.getConfusionSkills();
    return skillIds && skillIds.length > 0;
  };

  Game_Action.prototype.setConfusionSkill = function (skillIds) {
    var skillId = skillIds[Math.randomInt(skillIds.length)];
    this.setSkill(skillId);
  };

  Game_Action.prototype.setConfusionSpareSkill = function () {
    var state = this.getRestrictState();
    var value = getMetaValues(state, ["予備スキル", "SpareSkill"]);
    if (value) {
      var skillId = getArgNumber(value, 1);
      if (this.subject().canUse($dataSkills[skillId])) {
        this.setSkill(skillId);
      }
    }
  };

  var _Game_Action_repeatTargets = Game_Action.prototype.repeatTargets;
  Game_Action.prototype.repeatTargets = function (targets) {
    if (Array.isArray(targets[0])) arguments[0] = targets[0];
    return _Game_Action_repeatTargets.apply(this, arguments);
  };

  var _Game_Action_confusionTarget = Game_Action.prototype.confusionTarget;
  Game_Action.prototype.confusionTarget = function () {
    var target = _Game_Action_confusionTarget.apply(this, arguments);
    if (this.isExistConfusionSkill()) {
      target = this.confusionSkillTarget();
    }
    return target;
  };

  Game_Action.prototype.confusionSkillTarget = function () {
    var state = this.getRestrictState();
    var value = getMetaValues(state, ["ターゲット", "Target"]);
    if (value) {
      var index = getArgNumber(value, -1);
      this._targetIndex =
        index === -1 ? this.subject().getLastTargetIndex() : index;
    }
    if (this.isForUser()) {
      return this.subject();
    }
    return this.isConfusionSkillTargetForFriend()
      ? this.targetsForFriends()
      : this.targetsForOpponents();
  };

  Game_Action.prototype.isConfusionSkillTargetForFriend = function () {
    switch (this.subject().confusionLevel()) {
      case 1:
        return this.isForFriend();
      case 2:
        return Math.randomInt(2) === 0;
      case 3:
        return !this.isConfusionSkillTargetReverse();
    }
    return false;
  };

  Game_Action.prototype.isConfusionSkillTargetReverse = function () {
    return paramTargetFriendSkill && this.isForFriend();
  };
})();


code:
//=============================================================================
// CustomizeConfigDefault.js
// ----------------------------------------------------------------------------
// (C)2015 Triacontane
// This plugin is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.1 2020/09/13 Mano_InputConfig.jsと併用したとき、Option項目を消していると表示不整合が発生する競合を修正
// 1.1.0 2016/08/01 項目自体を非表示にする機能を追加しました。
// 1.0.3 2016/06/22 多言語対応
// 1.0.2 2016/01/17 競合対策
// 1.0.1 2015/11/01 既存コードの再定義方法を修正（内容に変化なし）
// 1.0.0 2015/11/01 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc Setting default value for Options
 * @author triacontane
 *
 * @param AlwaysDash
 * @desc Always dash(ON/OFF)
 * @default OFF
 *
 * @param CommandRemember
 * @desc Command remember(ON/OFF)
 * @default OFF
 *
 * @param BgmVolume
 * @desc BGM Volume(0-100)
 * @default 100
 *
 * @param BgsVolume
 * @desc BGS Volume(0-100)
 * @default 100
 *
 * @param MeVolume
 * @desc ME Volume(0-100)
 * @default 100
 *
 * @param SeVolume
 * @desc SE Volume(0-100)
 * @default 100
 *
 * @param EraseAlwaysDash
 * @desc Erase AlwaysDash Option(ON/OFF)
 * @default OFF
 *
 * @param EraseCommandRemember
 * @desc Erase CommandRemember Option(ON/OFF)
 * @default OFF
 *
 * @param EraseBgmVolume
 * @desc Erase BgmVolume Option(ON/OFF)
 * @default OFF
 *
 * @param EraseBgsVolume
 * @desc Erase BgsVolume Option(ON/OFF)
 * @default OFF
 *
 * @param EraseMeVolume
 * @desc Erase MeVolume Option(ON/OFF)
 * @default OFF
 *
 * @param EraseSeVolume
 * @desc Erase SeVolume Option(ON/OFF)
 * @default OFF
 *
 * @help Setting default value for Options.
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc オプションデフォルト値設定プラグイン
 * @author トリアコンタン
 *
 * @param 常時ダッシュ
 * @desc 常にダッシュする。（Shiftキーを押している場合のみ歩行）(ON/OFF)
 * @default OFF
 *
 * @param コマンド記憶
 * @desc 選択したコマンドを記憶する。(ON/OFF)
 * @default OFF
 *
 * @param BGM音量
 * @desc BGMの音量。0-100
 * @default 100
 *
 * @param BGS音量
 * @desc BGSの音量。0-100
 * @default 100
 *
 * @param ME音量
 * @desc MEの音量。0-100
 * @default 100
 *
 * @param SE音量
 * @desc SEの音量。0-100
 * @default 100
 *
 * @param 常時ダッシュ消去
 * @desc 常時ダッシュの項目を非表示にする。(ON/OFF)
 * @default OFF
 *
 * @param コマンド記憶消去
 * @desc コマンド記憶の項目を非表示にする。(ON/OFF)
 * @default OFF
 *
 * @param BGM音量消去
 * @desc BGM音量の項目を非表示にする。(ON/OFF)
 * @default OFF
 *
 * @param BGS音量消去
 * @desc BGS音量の項目を非表示にする。(ON/OFF)
 * @default OFF
 *
 * @param ME音量消去
 * @desc ME音量の項目を非表示にする。(ON/OFF)
 * @default OFF
 *
 * @param SE音量消去
 * @desc SE音量の項目を非表示にする。(ON/OFF)
 * @default OFF
 *
 * @help オプション画面で設定可能な項目のデフォルト値を指定した値に変更します。
 * 例えば、初回から常時ダッシュをONにしておけば
 * プレイヤーが設定を変更する手間を省くことができます。
 * この処理はconfig.rpgsaveが未作成の場合にのみ実行されます。
 *
 * また、項目そのものを消去することもできます。
 * 例えば、戦闘がないゲームでは「コマンド記憶」等は不要なので消去できます。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
(function () {
  "use strict";
  var pluginName = "CustomizeConfigDefault";

  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 getParamBoolean = function (paramNames) {
    var value = getParamOther(paramNames);
    return (value || "").toUpperCase() === "ON";
  };

  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 paramAlwaysDash = getParamBoolean(["AlwaysDash", "常時ダッシュ"]);
  var paramCommandRemember = getParamBoolean([
    "CommandRemember",
    "コマンド記憶",
  ]);
  var paramBgmVolume = getParamNumber(["BgmVolume", "BGM音量"], 0, 100);
  var paramBgsVolume = getParamNumber(["BgsVolume", "BGS音量"], 0, 100);
  var paramMeVolume = getParamNumber(["MeVolume", "ME音量"], 0, 100);
  var paramSeVolume = getParamNumber(["SeVolume", "SE音量"], 0, 100);
  var paramEraseAlwaysDash = getParamBoolean([
    "EraseAlwaysDash",
    "常時ダッシュ消去",
  ]);
  var paramEraseCommandRemember = getParamBoolean([
    "EraseCommandRemember",
    "コマンド記憶消去",
  ]);
  var paramEraseBgmVolume = getParamBoolean(["EraseBgmVolume", "BGM音量消去"]);
  var paramEraseBgsVolume = getParamBoolean(["EraseBgsVolume", "BGS音量消去"]);
  var paramEraseMeVolume = getParamBoolean(["EraseMeVolume", "ME音量消去"]);
  var paramEraseSeVolume = getParamBoolean(["EraseSeVolume", "SE音量消去"]);

  //=============================================================================
  // ConfigManager
  //  それぞれの項目に初期値を与えます。
  //=============================================================================
  var _ConfigManagerApplyData = ConfigManager.applyData;
  ConfigManager.applyData = function (config) {
    _ConfigManagerApplyData.apply(this, arguments);
    if (config.alwaysDash == null) this.alwaysDash = paramAlwaysDash;
    if (config.commandRemember == null)
      this.commandRemember = paramCommandRemember;
    if (config.bgmVolume == null) this.bgmVolume = paramBgmVolume;
    if (config.bgsVolume == null) this.bgsVolume = paramBgsVolume;
    if (config.meVolume == null) this.meVolume = paramMeVolume;
    if (config.seVolume == null) this.seVolume = paramSeVolume;
  };

  //=============================================================================
  // Window_Options
  //  パラメータを空白にした項目を除去します。
  //=============================================================================
  var _Window_Options_makeCommandList =
    Window_Options.prototype.makeCommandList;
  Window_Options.prototype.makeCommandList = function () {
    _Window_Options_makeCommandList.apply(this, arguments);
    if (paramEraseAlwaysDash) this.eraseOption("alwaysDash");
    if (paramEraseCommandRemember) this.eraseOption("commandRemember");
    if (paramEraseBgmVolume) this.eraseOption("bgmVolume");
    if (paramEraseBgsVolume) this.eraseOption("bgsVolume");
    if (paramEraseMeVolume) this.eraseOption("meVolume");
    if (paramEraseSeVolume) this.eraseOption("seVolume");
  };

  Window_Options.prototype.eraseOption = function (symbol) {
    for (var i = 0; i < this._list.length; i++) {
      if (this._list[i].symbol === symbol) {
        this._list.splice(i, 1);
        // for Mano_InputConfig.js
        this.adjustIndexManoInputConfig(i);
        break;
      }
    }
  };

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

repo_name: dazed/translations

license: unknown


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


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

/**
 * 2019/09/23 1.0.1 strictモードが正しく効いていない不具合の修正
 * 2019/09/22 1.0.0 公開
 */

/*:
 * @license MIT
 * @author DarkPlasma
 * @plugindesc 特殊な通貨のショップを作ります
 *
 * @param Special Shop Switch
 * @text 特殊ショップスイッチ
 * @desc このスイッチがONのときにショップを起動すると特殊通貨ショップになります
 * @default 1
 * @type switch
 *
 * @param Default Currency Item
 * @text 通貨扱いのアイテム
 * @desc このアイテムを通貨として扱います
 * @default 1
 * @type item
 *
 * @param Currency Item Unit
 * @text アイテム数の単位
 * @desc アイテム数の単位（お金で言うG相当）を設定します
 * @default 個
 * @type string
 *
 * @param Currency Variable
 * @text 通貨扱いのアイテム変数
 * @desc この変数が1以上の場合、そのアイテムIDのアイテムを通貨として扱います
 * @default 0
 * @type variable
 *
 * @help
 *   プラグインパラメータで設定したスイッチをONにした状態でショップを開くと、設定したアイテムを通貨として扱うショップを開きます。
 */

(function () {
  "use strict";

  const pluginName = "DarkPlasma_SpecialCurrencyShop";
  const pluginParameters = PluginManager.parameters(pluginName);

  const settings = {
    specialShopSwitch: Number(pluginParameters["Special Shop Switch"] || 1),
    defaultCurrencyItem: Number(pluginParameters["Default Currency Item"] || 1),
    currencyItemUnit: String(pluginParameters["Currency Item Unit"]) || "個",
    currencyVariable: Number(pluginParameters["Currency Variable"] || 0),
  };

  var DarkPlasma_SpecialCurrencyShop = {};

  DarkPlasma_SpecialCurrencyShop.currencyItem = function () {
    if ($gameSwitches.value(settings.specialShopSwitch)) {
      const itemId =
        $gameVariables.value(settings.currencyVariable) > 0
          ? $gameVariables.value(settings.currencyVariable)
          : settings.defaultCurrencyItem;
      return $dataItems[itemId];
    }
    return null;
  };

  const _SceneShop_doBuy = Scene_Shop.prototype.doBuy;
  Scene_Shop.prototype.doBuy = function (number) {
    const currencyItem = this.currencyItem();
    if (currencyItem) {
      $gameParty.loseItem(currencyItem, number * this.buyingPrice());
      $gameParty.gainItem(this._item, number);
    } else {
      _SceneShop_doBuy.call(this, number);
    }
  };

  const _SceneShop_doSell = Scene_Shop.prototype.doSell;
  Scene_Shop.prototype.doSell = function (number) {
    const currencyItem = this.currencyItem();
    if (currencyItem) {
      $gameParty.gainItem(currencyItem, number * this.sellingPrice());
      $gameParty.loseItem(this._item, number);
    } else {
      _SceneShop_doSell.call(this, number);
    }
  };

  const _SceneShop_money = Scene_Shop.prototype.money;
  Scene_Shop.prototype.money = function () {
    const currencyItem = this.currencyItem();
    if (currencyItem) {
      return $gameParty.numItems(currencyItem);
    } else {
      return _SceneShop_money.call(this);
    }
  };

  Scene_Shop.prototype.currencyItem = function () {
    return DarkPlasma_SpecialCurrencyShop.currencyItem();
  };

  const _WindowGold_currencyUnit = Window_Gold.prototype.currencyUnit;
  Window_Gold.prototype.currencyUnit = function () {
    if (this.currencyItem()) {
      return settings.currencyItemUnit;
    } else {
      return _WindowGold_currencyUnit.call(this);
    }
  };

  const _WindowGold_value = Window_Gold.prototype.value;
  Window_Gold.prototype.value = function () {
    const currencyItem = this.currencyItem();
    if (currencyItem) {
      return $gameParty.numItems(currencyItem);
    } else {
      return _WindowGold_value.call(this);
    }
  };

  Window_Gold.prototype.currencyItem = function () {
    return DarkPlasma_SpecialCurrencyShop.currencyItem();
  };
})();


code:
//=============================================================================
// DatabaseConverter.js
// ----------------------------------------------------------------------------
// (C)2015-2018 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.2 2018/05/30 移動ルートの設定のコマンドをインポートした際、一部の数値がundefinedとなってしまう問題を修正
// 1.0.1 2018/05/20 オリジナルデータの作成方法をヘルプに追加
// 1.0.0 2018/05/20 正式版リファクタリング
// 0.3.0 2018/05/17 オートインポート機能がパラメータ設定に拘わらず有効になっていた問題を修正
//                  マップIDに歯抜けがあった場合、出力エラーになる問題を修正
//                  イベントテストの実行内容を出力する機能を追加
// 0.2.0 2018/05/14 ヘルプ修正
// 0.1.0 2018/05/13 テスト版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc データベース変換プラグイン
 * @author トリアコンタン
 *
 * @param excelDataPath
 * @text シートデータファイルパス
 * @desc シートデータファイルが出力されるパスです。相対パス、絶対パスが入力できます。
 * @default excelData
 *
 * @param ExportPrefix
 * @text 出力ファイル接頭辞
 * @desc エクスポートファイルに付与される接頭辞です。インポートファイルと分けて保持したい場合に指定してください。
 * @default
 *
 * @param targetDatabase
 * @text 対象データベース
 * @desc 入出力の対象になるデータベースの一覧です。独自に定義したデータファイルを追加できます。
 * @default ["{\"JsonName\":\"Actors\",\"VariableName\":\"\"}","{\"JsonName\":\"Classes\",\"VariableName\":\"\"}","{\"JsonName\":\"Skills\",\"VariableName\":\"\"}","{\"JsonName\":\"Items\",\"VariableName\":\"\"}","{\"JsonName\":\"Weapons\",\"VariableName\":\"\"}","{\"JsonName\":\"Armors\",\"VariableName\":\"\"}","{\"JsonName\":\"Enemies\",\"VariableName\":\"\"}","{\"JsonName\":\"Troops\",\"VariableName\":\"\"}","{\"JsonName\":\"States\",\"VariableName\":\"\"}","{\"JsonName\":\"MapInfos\",\"VariableName\":\"\"}"]
 * @type struct<DatabaseInfo>[]
 *
 * @param fileFormat
 * @text 出力ファイル形式
 * @desc 出力データのファイル形式です。
 * @default xlsx
 * @type select
 * @option xlsx : Excel 2007+ XML Format
 * @value xlsx
 * @option xlsm : Excel 2007+ Macro XML Format
 * @value xlsm
 * @option xlsb : Excel 2007+ Binary Format
 * @value xlsb
 * @option ods  : OpenDocument Spreadsheet
 * @value ods
 * @option fods : Flat OpenDocument Spreadsheet
 * @value fods
 * @option csv  : Comma Separated Values
 * @value csv
 * @option txt  : UTF-16 Unicode Text (TSV)
 * @value txt
 *
 * @param originalDataLoad
 * @text オリジナルデータ読み込み
 * @desc 作成済みのオリジナルJSONデータの読み込み処理を実行します。データファイルがないとエラーになります。
 * @default false
 * @type boolean
 *
 * @param autoImport
 * @text 自動インポート
 * @desc インポート処理を実行してからゲーム開始します。テストプレー時のみ有効です。
 * @default false
 * @type boolean
 *
 * @param exportEventTest
 * @text イベントテスト出力
 * @desc イベントテスト実行時に実行内容を出力します。ただし本プラグインのコマンドを実行した場合は出力されません。
 * @default true
 * @type boolean
 *
 * @param commandPrefix
 * @text メモ欄接頭辞
 * @desc 他のプラグインとメモ欄もしくはプラグインコマンドの名称が被ったときに指定する接頭辞です。通常は指定不要です。
 * @default
 *
 * @help DatabaseConverter.js
 * ツクールMVのデータベースをExcelなどのシートデータ（以下シートファイル）に
 * 書き出し、読み込みします。
 *
 * イベントテスト（イベントエディタ上で右クリック→テスト）から所定の
 * プラグインコマンド（後述）を実行すると書き出しおよび読み込みができます。
 *
 * --------------------------------------
 * 書き出し手順
 * --------------------------------------
 * 1. 本プラグインを管理画面からONにする。
 * 2.「プロジェクトの保存」を実行する。(初回実行時のみ)
 * 3. イベントテストから所定のプラグインコマンドを実行する。
 * 4. 所定のフォルダにシートファイルが出力される。
 *
 * --------------------------------------
 * 読み込み手順
 * --------------------------------------
 * 1.「プロジェクトの保存」を実行する。
 * 2. Dataフォルダをバックアップしておく。
 * 3. イベントテストから所定のプラグインコマンドを実行する。
 * 4.「プロジェクトを開く」を実行して、プロジェクトを開き直す。
 *   開き直すとき、プロジェクトの保存はしないでください。
 *
 * ※プラグインコマンドは1つずつ実行してください。
 * 　一度に複数のコマンドを実行することはできません。
 *
 * --------------------------------------
 * オリジナルデータベース作成手順(上級者向け)
 * --------------------------------------
 * 1. パラメータ「オリジナルデータ読み込み」をOFFにする。
 * 2. パラメータ「対象データベース」にオリジナルデータを追加
 * 3. データベースをエクスポート
 * 4. オリジナルデータのシートが追加されるので自由に編集
 * 5. データベースをインポート
 * 6. パラメータ「オリジナルデータ読み込み」をONにする。
 * 7. スクリプトからオリジナルデータの内容を参照できる。
 *
 * --------------------------------------
 * 出力対象データ
 * --------------------------------------
 * ・データベース
 * 既存のデータベースを入出力します。ファイル名は「Database」です。
 * 出力フォーマットに合わせた拡張子が付与されます。(以降も同様)
 * タイルセットおよびコモンイベントは対象外です。
 * さらに独自に定義したデータ（スクリプトから参照）も入出力可能です。
 *
 * ・コモンイベント
 * コモンイベントの実行内容を入出力します。ファイル名は「CommonEvents」です。
 * パラメータの詳細は以下のスプレッドシートが参考になります。
 * https://docs.google.com/spreadsheets/d/1rOIzDuhLC6IqJPEFciYOmXWL_O7X9-hMValMs7DpWCk/edit#gid=1266374350
 *
 * ・マップイベント
 * マップイベントの実行内容を入出力します。ファイル名は「MapXXX」です。
 * シート名に「イベントID」および「イベントページ」が出力されます。
 *
 * ・イベントテスト
 * イベントテストで選択した実行内容を出力します。
 * ファイル名は「Test_Event」です。出力のみに対応しています。
 *
 * --------------------------------------
 * 出力対象フォーマット
 * --------------------------------------
 * Excelファイル以外にもCSVやOpenDocument Spreadsheetなど
 * 以下のフォーマットに対応しています。プラグインパラメータから変更可能です。
 *
 * xlsx : Excel2007以降の一般的な形式です。
 * xlsm : Excel2007以降のマクロ付き形式です。
 * xlsb : Excel2007以降のバイナリ形式です。容量や速度面で優れています。
 * ods  : 特定のベンダに依存しないオープンなファイル形式です。
 * fods : 特定のベンダに依存しないオープンなXMLテキストファイル形式です。
 * csv  : カンマ区切りのテキストファイル形式です。
 * txt  : タブ区切りのテキストファイル形式です。
 *
 * --------------------------------------
 * 出力ファイル詳細
 * --------------------------------------
 * 1. 出力時に同名のファイルが存在した場合は上書きされます。(※1)
 * 2. シート名にはデータ種別が出力されるので編集しないでください。
 * 3. 出力ファイルの1行目には入出力に必須な情報(プロパティ名)が出力されます。
 *    ここも編集しないでください。
 * 4. 2行目には項目の日本語名が出力されます。読み込み時は無視されます。
 * 5. 配列項目（特徴など）は一部除きjson文字列で出力されます。編集は非推奨です。
 * 6. 数値や文字列は編集できますが、整合性のない値の入力には注意してください。
 * 7. Excel計算式は計算結果がデータベースの値として読み込まれます。
 * 8. 書式設定や行列の設定、マクロの追加などは自由です。
 * 9. データベースは読み込み時にID列でソートされます。重複はエラーになります。
 *
 * ※1 同名ファイルを開いているとエラーになるのでファイルを閉じてください。
 * --------------------------------------
 * 注意事項
 * --------------------------------------
 * 当プラグインの機能を使用する前にプロジェクト以下の「data」フォルダの
 * バックアップを「必ず」取得してください。
 *
 * 「data」フォルダの内容を自動でバックアップするプラグインも配布しています。
 * こちらのご利用もご検討ください。
 * https://raw.githubusercontent.com/triacontane/RPGMakerMV/master/BackUpDatabase.js
 *
 * いかなる場合も破損したプロジェクトの復元には応じられませんのでご注意ください。
 *
 * エクスポートしたExcelファイルを開いたときに何らかのエラーメッセージが
 * 表示された場合は、そのまま編集およびインポートしないでください。
 *
 * 本プラグインの機能は「イベントテスト」から実行した場合のみ有効です。
 * 通常のテストプレーおよび製品版には影響を与えません。
 * （独自データの読み込み機能は例外）
 *
 * --------------------------------------
 * プラグインコマンド詳細
 * --------------------------------------
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * EXPORT_DATABASE
 *  データベースの内容を指定したフォーマットで出力します。
 *
 * IMPORT_DATABASE
 *  シートファイルを読み込んでデータベースファイルを書き換えます。
 *  エディタに反映させるためには、プロジェクトを開き直す必要があります。
 *
 * EXPORT_COMMON_EVENT 2
 *  ID[2]のコモンイベントの実行内容を出力します。IDは複数指定可能です。
 *  IDを指定しなかった場合は全てのコモンイベントを出力します。
 *
 * IMPORT_COMMON_EVENT 3
 *  シートファイルを読み込んでID[3]のコモンイベントを書き換えます。
 *  IDを指定しなかった場合は全てのコモンイベントを書き換えます。
 *
 * EXPORT_MAP_EVENT 6 20
 *  ID[6]のマップにあるID[20]のイベントの実行内容を出力します。
 *  イベントIDは複数指定可能で省略した場合、全イベントを出力します。
 *  マップIDは省略できません。
 *
 * IMPORT_MAP_EVENT 6 20
 *  シートファイルを読み込んでID[6]のマップにあるID[20]のイベントの
 *  実行内容を書き換えます。
 *  イベントIDは複数指定可能で省略した場合、全イベントを書き換えます。
 *  マップIDは省略できません。
 *
 * --------------------------------------
 * 使用ライブラリ
 * --------------------------------------
 * Excelデータの解析にはSheetJSのCommunity Editionを使用しています。
 * http://sheetjs.com/
 * Copyright (C) 2012-present   SheetJS LLC
 * Licensed under the Apache License, Version 2.0
 *
 * SheetJSはCDNを通じて提供されるため、プラグイン利用者は別途ライブラリを
 * 導入する必要はありませんが、オフラインで作業する場合やダウンロードできない
 * 場合は、以下の手順に従ってダウンロードしプラグインとして適用してください。
 *
 * 1. 以下のサイトのdist/xlsx.full.min.jsをダウンロードする。
 * https://github.com/sheetjs/js-xlsx
 *
 * 2. ファイル名を任意の英字に変更する。
 * （ファイル名に「.」が含まれているとプラグインとして取り込めないため）
 *
 * 3. プラグイン管理画面から有効にする。
 *
 * ExcelはMicrosoftの登録商標です。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~DatabaseInfo:
 *
 * @param JsonName
 * @text データファイル名称
 * @desc データベースファイルのJSON名称です。(拡張子不要) 独自に定義したJSONファイルを読み込む場合は直接入力してください。
 * @default
 * @type combo
 * @option Actors
 * @option Classes
 * @option Skills
 * @option Items
 * @option Weapons
 * @option Armors
 * @option Enemies
 * @option Troops
 * @option States
 * @option MapInfos
 *
 * @param VariableName
 * @text グローバル変数名称
 * @desc データベースが格納されるグローバル変数の名称です。既存データベースの場合は入力不要です。
 * @default
 */

/**
 * ConverterManager
 * コンバータを管理します。
 * @constructor
 */
function ConverterManager() {
  this.initialize.apply(this, arguments);
}

(function () {
  "use strict";

  let param = {};
  const pluginCommandMap = new Map();

  const paramReplacer = function (key, value) {
    if (value === "null" || value === null) {
      return value;
    }
    if (value[0] === '"' && value[value.length - 1] === '"') {
      return value;
    }
    if (value === String(value)) {
      if (value.toLowerCase() === "true") {
        return true;
      }
      if (value.toLowerCase() === "false") {
        return false;
      }
    }
    try {
      return JSON.parse(value);
    } catch (e) {
      return value;
    }
  };

  if (typeof Utils !== "undefined" && Utils.RPGMAKER_NAME === "MV") {
    /**
     * Convert escape characters.(require any window object)
     * @param text Target text
     * @returns {String} Converted text
     */
    const convertEscapeCharacters = function (text) {
      const windowLayer = SceneManager._scene._windowLayer;
      return windowLayer
        ? windowLayer.children[0].convertEscapeCharacters(text.toString())
        : text;
    };

    /**
     * Convert escape characters.(for text array)
     * @param texts Target text array
     * @returns {Array<String>} Converted text array
     */
    const convertEscapeCharactersAll = function (texts) {
      return texts.map(function (text) {
        return convertEscapeCharacters(text);
      });
    };

    /**
     * Set plugin command to method
     * @param commandName plugin command name
     * @param methodName execute method(Game_Interpreter)
     */
    const setPluginCommand = function (commandName, methodName) {
      pluginCommandMap.set(param.commandPrefix + commandName, methodName);
    };

    /**
     * Create plugin parameter. param[paramName] ex. param.commandPrefix
     * @param pluginName plugin name(ExcelDataConverter)
     * @returns {Object} Created parameter
     */
    const createPluginParameter = function (pluginName) {
      const parameter = JSON.parse(
        JSON.stringify(PluginManager.parameters(pluginName), paramReplacer)
      );
      PluginManager.setParameters(pluginName, parameter);
      return parameter;
    };
    param = createPluginParameter("DatabaseConverter");

    if (param.originalDataLoad && !DataManager.isEventTest()) {
      param.targetDatabase.forEach(function (databaseInfo) {
        const srcName = `${databaseInfo.JsonName}.json`;
        const exist = DataManager._databaseFiles.some(function (fileInfo) {
          return fileInfo.src === srcName;
        });
        if (!exist) {
          DataManager._databaseFiles.push({
            name: databaseInfo.VariableName,
            src: srcName,
          });
        }
      });
    }

    if (!Utils.isOptionValid("test") && !DataManager.isEventTest()) {
      return;
    }

    setPluginCommand("EXPORT_DATABASE", "exportDatabase");
    setPluginCommand("IMPORT_DATABASE", "importDatabase");
    setPluginCommand("EXPORT_COMMON_EVENT", "exportCommonEvent");
    setPluginCommand("IMPORT_COMMON_EVENT", "importCommonEvent");
    setPluginCommand("EXPORT_MAP_EVENT", "exportMapEvent");
    setPluginCommand("IMPORT_MAP_EVENT", "importMapEvent");

    //=============================================================================
    // Game_Interpreter
    //=============================================================================
    const _Game_Interpreter_pluginCommand =
      Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function (command, args) {
      _Game_Interpreter_pluginCommand.apply(this, arguments);
      const pluginCommandMethod = pluginCommandMap.get(command.toUpperCase());
      if (pluginCommandMethod) {
        this[pluginCommandMethod](convertEscapeCharactersAll(args));
      }
    };

    Game_Interpreter.prototype.exportDatabase = function () {
      ConverterManager.executeDataExport(new ConvertTargetDatabase(false));
    };

    Game_Interpreter.prototype.importDatabase = function () {
      ConverterManager.executeDataImport(new ConvertTargetDatabase(false));
    };

    Game_Interpreter.prototype.exportCommonEvent = function (args) {
      ConverterManager.executeDataExport(new ConvertTargetCommonEvent(args));
    };

    Game_Interpreter.prototype.importCommonEvent = function (args) {
      ConverterManager.executeDataImport(new ConvertTargetCommonEvent(args));
    };

    Game_Interpreter.prototype.exportMapEvent = function (args) {
      const mapId = parseInt(args.shift());
      ConverterManager.executeDataExport(
        new ConvertTargetMapEvent(args, mapId)
      );
    };

    Game_Interpreter.prototype.importMapEvent = function (args) {
      const mapId = parseInt(args.shift());
      ConverterManager.executeDataImport(
        new ConvertTargetMapEvent(args, mapId)
      );
    };

    const _Game_Interpreter_terminate = Game_Interpreter.prototype.terminate;
    Game_Interpreter.prototype.terminate = function () {
      _Game_Interpreter_terminate.apply(this, arguments);
      if (
        DataManager.isEventTest() &&
        this._depth === 0 &&
        param.exportEventTest
      ) {
        ConverterManager.executeDataExport(new ConvertTargetTestEvent());
      }
    };

    //=============================================================================
    // SceneManager
    //  コンバータマネージャーを追加定義します。
    //=============================================================================
    const _SceneManager_initialize = SceneManager.initialize;
    SceneManager.initialize = function () {
      _SceneManager_initialize.apply(this, arguments);
      ConverterManager.initialize();
    };

    //=============================================================================
    // DataManager
    //  起動時の自動読み込みを追加します。
    //=============================================================================
    var _DataManager_loadDatabase = DataManager.loadDatabase;
    DataManager.loadDatabase = function () {
      if (!this.isEventTest() && !this._databaseImport && param.autoImport) {
        ConverterManager.executeDataImportSync(
          function () {
            _DataManager_loadDatabase.apply(this, arguments);
          }.bind(this)
        );
        this._databaseImport = true;
      } else {
        _DataManager_loadDatabase.apply(this, arguments);
      }
    };

    //=============================================================================
    // Scene_Boot
    //  変換オブジェクトの準備完了を待ちます。
    //=============================================================================
    const _Scene_Boot_isReady = Scene_Boot.prototype.isReady;
    Scene_Boot.prototype.isReady = function () {
      return (
        _Scene_Boot_isReady.apply(this, arguments) &&
        ConverterManager.isSheetDataConverterReady()
      );
    };
  }

  //=============================================================================
  // ConverterManager
  //  シート変換オブジェクトを生成、管理します。
  //=============================================================================
  ConverterManager.initialize = function () {
    this._sheetDataConverter = AbstractSheetConverter.getInstance(
      param.fileFormat
    );
    this._sheetJs = new SheetJsCreator();
  };

  ConverterManager.isSheetDataConverterReady = function () {
    return this._sheetJs.isReady() && this._sheetDataConverter.isReady();
  };

  ConverterManager.executeDataImportSync = function (callBack) {
    this._sheetJs.addLoadListener(
      function () {
        this._sheetDataConverter.executeImport(new ConvertTargetDatabase(true));
        callBack();
      }.bind(this)
    );
  };

  ConverterManager.executeDataExport = function (target) {
    this._executeDataConvert("executeExport", target);
  };

  ConverterManager.executeDataImport = function (target) {
    this._executeDataConvert("executeImport", target);
  };

  ConverterManager._executeDataConvert = function (process, target) {
    if (!this.isSheetDataConverterReady()) {
      return;
    }
    var nwWin = require("nw.gui").Window.get();
    nwWin.showDevTools();
    console.log(`----- ${process} Process Start -----`);
    this._sheetDataConverter[process](target);
    console.log(`----- ${process} Process End   -----`);
    setTimeout(function () {
      nwWin.focus();
    }, 500);
    this._pause();
  };

  ConverterManager._pause = function () {
    console.log("Press or Click any key to shutdown....");
    setInterval(function () {
      if (Object.keys(Input._currentState).length > 0 || TouchInput.isPressed())
        SceneManager.terminate();
    }, 10);
  };

  ConverterManager.getDatabasePath = function () {
    return this.getRelativePath("data/");
  };

  ConverterManager.getRelativePath = function (subPath) {
    const path = require("path");
    const base = path.dirname(process.mainModule.filename);
    return path.join(base, subPath);
  };

  ConverterManager.setParameter = function (name, value) {
    param[name] = value;
  };

  /**
   * SheetJsCreator
   * SheetJsライブラリをダウンロードして保持します。
   */
  class SheetJsCreator {
    constructor() {
      this._loaded = false;
      this._loadListener = [];
      this._urlIndex = 0;
      this._loadSheetJs();
    }

    isReady() {
      return this._loaded;
    }

    addLoadListener(callBack) {
      if (this._loaded) {
        callBack();
      } else {
        this._loadListener.push(callBack);
      }
    }

    _loadSheetJs() {
      if (typeof XLSX !== "undefined") {
        this._onLoadScript();
        return;
      }
      const script = document.createElement("script");
      script.type = "text/javascript";
      script.src = this._getSheetJsUrl();
      script.onerror = this._onLoadScriptError.bind(this);
      script.onload = this._onLoadScript.bind(this);
      document.body.appendChild(script);
    }

    _getSheetJsUrl() {
      return AbstractSheetConverter.CDN_SERVER_URL_LIST[this._urlIndex];
    }

    _onLoadScript() {
      if (typeof XLSX === "undefined") {
        this._onLoadScriptError();
        return;
      }
      this._loaded = true;
      this._loadListener.forEach(function (callBack) {
        callBack();
      });
      this._loadListener = null;
    }

    _onLoadScriptError() {
      this._urlIndex++;
      if (this._getSheetJsUrl()) {
        this._loadSheetJs();
      } else {
        throw new Error(
          "CDNサーバからのライブラリダウンロードに失敗しました。マニュアルダウンロードをお試しください。"
        );
      }
    }
  }

  /**
   * ConverterStorage
   * データファイルのロード・セーブを行います。
   */
  class ConverterStorage {
    loadDataBaseFileSync(fileName) {
      try {
        const filePath = this.getDatabaseFullPath(fileName);
        return JSON.parse(
          require("fs").readFileSync(filePath, { encoding: "utf8" })
        );
      } catch (e) {
        console.error("Fail to Load " + fileName);
        return [null, { id: 1, name: " " }];
      }
    }

    saveDataBaseFile(fileName, data, sync) {
      try {
        const filePath = this.getDatabaseFullPath(fileName);
        const fs = require("fs");
        const writeFunc = sync ? fs.writeFileSync : fs.writeFile;
        writeFunc(filePath, JSON.stringify(data), { encoding: "utf8" });
      } catch (e) {
        console.error("Fail to Save " + fileName);
        throw e;
      }
    }

    getDatabaseFullPath(fileName) {
      return ConverterManager.getDatabasePath() + fileName + ".json";
    }
  }

  /**
   * AbstractSheetConverter
   * データベースとシートファイルの相互変換を行う抽象クラスです。
   */
  class AbstractSheetConverter {
    constructor(format) {
      const directory = this._getTargetDirectory();
      if (!this._makeSheetDirectoryIfNeed(directory)) {
        throw new Error(
          `シート出力ディレクトリ[${directory}]が見付かりませんでした。`
        );
      }
      this._format = format;
      this._directory = directory;
      this._serializer = null;
      this._target = null;
    }

    _makeSheetDirectoryIfNeed(filePath) {
      const fs = require("fs");
      if (!fs.existsSync(filePath)) {
        try {
          fs.mkdirSync(filePath);
        } catch (e) {
          console.error(e);
          return false;
        }
      }
      return fs.existsSync(filePath);
    }

    isReady() {
      return !this._serializer;
    }

    executeExport(target) {
      this._target = target;
      this._workBook = this._createWorkBook();
      this._serializer = new DataSerializer(target);
      this._target.execute(this._exportItem.bind(this));
      this.writeAllWorkbook();
    }

    _createWorkBook() {
      return { SheetNames: [], Sheets: {} };
    }

    _exportItem(dataName) {
      console.log("Export " + dataName);
      const data = this._target.load(dataName);
      if (!data) {
        return;
      }
      this._workBook.SheetNames.push(dataName);
      this._workBook.Sheets[dataName] = this._serializer.serializeData(data);
    }

    /**
     * writeAllWorkbook
     * @abstract
     */
    writeAllWorkbook() {}

    writeWorkbookFile(dataBaseName, workbookData) {
      const writeOption = { bookType: this._format };
      const path = this._getTargetFilePath(
        this._target.getFileName() + param.ExportPrefix,
        dataBaseName
      );
      try {
        XLSX.writeFile(workbookData, path, writeOption);
      } catch (e) {
        if (e.code === "EBUSY") {
          throw new Error(
            `ファイル[${path}]の書き出しに失敗しました。ファイルを開いている可能性があります。`
          );
        } else {
          throw e;
        }
      }
    }

    executeImport(target) {
      this._target = target;
      this._workBook = this.readAllWorkbook();
      this._serializer = new DataSerializer(target);
      this._target.execute(this._importItem.bind(this));
    }

    _importItem(dataName) {
      const sheetData = this._workBook.Sheets[dataName];
      if (!sheetData) {
        console.warn("Skip Import " + dataName);
        return;
      } else {
        console.log("Import " + dataName);
      }
      const data = this._serializer.deserializeData(sheetData);
      this._target.save(dataName, data);
    }

    /**
     * readAllWorkbook
     * @abstract
     */
    readAllWorkbook() {}

    readWorkbookFile(dataBaseName) {
      const readOption = {};
      const path = this._getTargetFilePath(
        this._target.getFileName(),
        dataBaseName
      );
      try {
        return XLSX.readFile(path, readOption);
      } catch (e) {
        if (e.code === "ENOENT") {
          throw new Error(`ファイル[${path}]が見付かりませんでした。`);
        } else {
          throw e;
        }
      }
    }

    _getTargetDirectory() {
      const path = param.excelDataPath;
      return !path.match(/^[A-Z]:/)
        ? ConverterManager.getRelativePath(path)
        : path;
    }

    _getTargetFilePath(baseName, dataName) {
      return `${this._directory}/${baseName}${dataName}.${this._format}`;
    }

    static getInstance(format) {
      if (AbstractSheetConverter.SINGLE_FORMATS.contains(format)) {
        return new SingleSheetConverter(format);
      } else {
        return new MultiSheetConverter(format);
      }
    }

    static get SINGLE_FORMATS() {
      return ["csv", "txt"];
    }

    static get CDN_SERVER_URL_LIST() {
      return [
        "https://unpkg.com/xlsx/dist/xlsx.full.min.js",
        "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.11.19/xlsx.full.min.js",
        "https://cdn.jsdelivr.net/npm/xlsx@0.11.19/dist/xlsx.full.min.js",
      ];
    }
  }

  /**
   * MultiSheetConverter
   * マルチチート用の変換クラスです。
   */
  class MultiSheetConverter extends AbstractSheetConverter {
    writeAllWorkbook() {
      this.writeWorkbookFile("", this._workBook);
    }

    readAllWorkbook() {
      return this.readWorkbookFile("");
    }
  }

  /**
   * SingleSheetConverter
   * シングルシート用の変換クラスです。
   */
  class SingleSheetConverter extends AbstractSheetConverter {
    writeAllWorkbook() {
      this._target.execute(
        function (databaseName) {
          var workbook = this._createWorkBook();
          workbook.SheetNames.push(databaseName);
          workbook.Sheets[databaseName] = this._workBook.Sheets[databaseName];
          this.writeWorkbookFile(databaseName, workbook);
        }.bind(this)
      );
    }

    readAllWorkbook() {
      const workbook = this._createWorkBook();
      this._target.execute(
        function (databaseName) {
          const singleWork = this.readWorkbookFile(databaseName);
          if (singleWork) {
            workbook.SheetNames.push(databaseName);
            workbook.Sheets[databaseName] = singleWork.Sheets["Sheet1"];
          }
        }.bind(this)
      );
      return workbook;
    }
  }

  /**
   * InterfaceConvertTarget
   * 変換対象インタフェース
   */
  class InterfaceConvertTarget {
    static METHODS() {
      return [
        "execute",
        "getFileName",
        "load",
        "save",
        "getColumnDescriptions",
        "getArrayProperties",
        "appendData",
      ];
    }

    constructor() {
      InterfaceConvertTarget.METHODS().forEach(function (method) {
        if (!this[method] || typeof this[method] !== "function") {
          throw new Error(`Require method ${method} not found.`);
        }
      }, this);
    }
  }

  /**
   * ConvertTargetDatabase
   * データベース用の変換対象クラス
   */
  class ConvertTargetDatabase extends InterfaceConvertTarget {
    constructor(sync) {
      super();
      this._sync = sync;
      this._storage = new ConverterStorage();
    }

    execute(process) {
      param.targetDatabase
        .map(function (databaseInfo) {
          return databaseInfo.JsonName;
        })
        .forEach(process, this);
    }

    getFileName() {
      return "Database";
    }

    load(name) {
      const data = this._storage.loadDataBaseFileSync(name);
      data.shift(0);
      return data;
    }

    save(name, data) {
      data[0] = null;
      this._storage.saveDataBaseFile(name, data, this._sync);
    }

    appendData(database, dataItem) {
      if (database[dataItem.id]) {
        throw new Error(`データ内のID[${dataItem.id}]が重複しています。`);
      }
      if (!dataItem.hasOwnProperty("name")) {
        dataItem.name = "";
      }
      if (!dataItem.hasOwnProperty("note")) {
        dataItem.note = "";
      }
      database[dataItem.id] = dataItem;
    }

    getColumnDescriptions() {
      return ConvertTargetDatabase._commonDescriptions;
    }

    getArrayProperties() {
      return ConvertTargetDatabase._arrayProperties;
    }

    getSplitProperties() {
      return ConvertTargetDatabase._splitProperties;
    }

    getObjectProperties() {
      return ConvertTargetDatabase._objectProperties;
    }
  }
  ConvertTargetDatabase._commonDescriptions = {
    id: "ID",
    name: "名前",
    description: "説明",
    traits: "特徴",
    effects: "効果",
    note: "メモ",
    actions: "行動",
    dropItems: "ドロップアイテム",
    members: "メンバー",
    animationId: "アニメーション",
    hitType: "命中タイプ",
    iconIndex: "アイコン",
    occasion: "使用可能時",
    repeats: "連続回数",
    scope: "範囲",
    speed: "速度補正",
    successRate: "成功率",
    tpCost: "消費TP",
    tpGain: "得TP",
    mpCost: "消費MP",
    damage_elementId: "属性",
    damage_type: "タイプ",
    damage_variance: "分散度",
    damage_critical: "会心",
    damage_formula: "計算式",
    price: "価格",
    params0: "最大HP",
    params1: "最大MP",
    params2: "攻撃力",
    params3: "防御力",
    params4: "魔法力",
    params5: "魔法防御",
    params6: "敏捷性",
    params7: "運",
    stypeId: "スキルタイプ",
    requiredWtypeId1: "武器タイプ1",
    requiredWtypeId2: "武器タイプ2",
    itypeId: "アイテムタイプ",
    consumable: "消耗",
    wtypeId: "武器タイプ",
    atypeId: "防具タイプ",
    etypeId: "装備タイプ",
    battlerHue: "色相",
    exp: "経験値",
    gold: "所持金",
    autoRemovalTiming: "自動解除のタイミング",
    chanceByDamage: "ダメージで解除_ダメージ",
    maxTurns: "継続ターン数_最大",
    minTurns: "継続ターン数_最小",
    motion: "[SV] モーション",
    overlay: "[SV] 重ね合わせ",
    priority: "優先度",
    removeAtBattleEnd: "戦闘終了時に解除",
    removeByDamage: "ダメージで解除",
    removeByRestriction: "行動制約で解除",
    removeByWalking: "歩数で解除",
    restriction: "行動制約",
    stepsToRemove: "歩数で解除_歩数",
    battlerName: "[SV] 戦闘キャラ",
    characterIndex: "歩行キャラ_インデックス",
    characterName: "歩行キャラ_ファイル名",
    classId: "職業",
    equips: "装備",
    faceIndex: "顔_インデックス",
    faceName: "顔_ファイル名",
    initialLevel: "初期レベル",
    maxLevel: "最大レベル",
    nickname: "二つ名",
    profile: "プロフィール",
    expParams: "経験値曲線",
    learnings: "習得するスキル",
    damage: "ダメージ",
    message1: "メッセージ1",
    message2: "メッセージ2",
    pages: "バトルイベント",
    message3: "メッセージ3",
    message4: "メッセージ4",
    releaseByDamage: "ダメージで解除_チェック",
    flags: "マップデータ",
    mode: "モード",
    list: "実行内容",
    switchId: "スイッチ",
    trigger: "トリガー",
    tilesetNames: "画像",
    expanded: "展開状態",
    order: "並び順",
    parentId: "親マップID",
    scrollX: "スクロールX",
    scrollY: "スクロールY",
  };

  ConvertTargetDatabase._arrayProperties = [
    "equips",
    "traits",
    "expParams",
    "learnings",
    "effects",
    "actions",
    "dropItems",
    "members",
    "pages",
    "flags",
    "tilesetNames",
    "list",
  ];

  ConvertTargetDatabase._splitProperties = ["params"];

  ConvertTargetDatabase._objectProperties = {
    damage: ["critical", "elementId", "formula", "type", "variance"],
  };

  /**
   * AbstractConvertTargetEvent
   * イベント用の変換対象抽象クラス
   */
  class AbstractConvertTargetEvent extends InterfaceConvertTarget {
    constructor(eventIdList, mapId) {
      super();
      this._mapId = mapId;
      this._storage = new ConverterStorage();
      this.setup(eventIdList);
    }

    setup(eventIdList) {
      this._dataName = this.getFileName();
      this._database = this._storage.loadDataBaseFileSync(this._dataName);
      this.setupTargetList(eventIdList);
    }

    execute(process) {
      this._targetList.forEach(process);
    }

    appendData(database, dataItem) {
      database.push(dataItem);
    }

    load(name) {
      return this.getList(name).map(function (item) {
        item.codeName = AbstractConvertTargetEvent._eventNamesMap[item.code];
        return item;
      });
    }

    save(name, data) {
      const list = data.map(function (item) {
        delete item.codeName;
        return item;
      });
      this.setList(name, list);
      if (this._targetList.indexOf(name) === this._targetList.length - 1) {
        this._storage.saveDataBaseFile(this._dataName, this._database, false);
      }
    }

    getColumnDescriptions() {
      return AbstractConvertTargetEvent._commonDescriptions;
    }

    getArrayProperties() {
      return AbstractConvertTargetEvent._arrayProperties;
    }

    getSplitProperties() {
      return AbstractConvertTargetEvent._splitProperties;
    }

    getObjectProperties() {
      return AbstractConvertTargetEvent._objectProperties;
    }
  }
  AbstractConvertTargetEvent._commonDescriptions = {
    code: "イベントコード",
    indent: "インデント",
    codeName: "イベント内容",
    parameters0: "パラメータリスト",
  };

  AbstractConvertTargetEvent._arrayProperties = [];

  AbstractConvertTargetEvent._splitProperties = ["parameters"];

  AbstractConvertTargetEvent._objectProperties = {};

  AbstractConvertTargetEvent._eventNamesMap = {
    0: "空行",
    101: "文章の表示(設定)",
    102: "選択肢の表示",
    103: "数値入力の処理",
    104: "アイテム選択の処理",
    401: "文章の表示",
    402: "選択肢の表示(**のとき)",
    403: "選択肢の表示(キャンセルのとき)",
    404: "選択肢の表示(分岐終了)",
    105: "文章のスクロール表示",
    405: "文章のスクロール表示(メッセージ内容)",
    108: "注釈",
    111: "条件分岐",
    411: "条件分岐(それ以外の場合)",
    412: "条件分岐(分岐終了)",
    112: "ループ",
    413: "ループ(以上繰り返し)",
    113: "ループの中断",
    115: "イベント処理の中断",
    117: "コモンイベント",
    118: "ラベル",
    119: "ラベルジャンプ",
    121: "スイッチの操作",
    122: "変数の操作",
    123: "セルフスイッチの操作",
    124: "タイマーの操作",
    125: "所持金の増減",
    126: "アイテムの増減",
    127: "武器の増減",
    128: "防具の増減",
    129: "メンバーの入れ替え",
    132: "戦闘BGMの変更",
    133: "勝利MEの変更",
    134: "セーブ禁止の変更",
    135: "メニュー禁止の変更",
    136: "エンカウント禁止の変更",
    137: "並べ替え禁止の変更",
    138: "ウィンドウカラーの変更",
    139: "敗北MEの変更",
    140: "乗り物BGMの変更",
    201: "場所移動",
    202: "乗り物位置の設定",
    203: "イベント位置の設定",
    204: "マップのスクロール",
    205: "移動ルートの設定",
    505: "移動ルートの設定(空行)",
    206: "乗り物の乗降",
    211: "透明状態の変更",
    212: "アニメーションの表示",
    213: "フキダシアイコンの表示",
    214: "イベントの一時消去",
    216: "隊列歩行の変更",
    217: "隊列メンバーの集合",
    221: "画面のフェードアウト",
    222: "画面のフェードイン",
    223: "画面の色調変更",
    224: "画面のフラッシュ",
    225: "画面のシェイク",
    230: "ウェイト",
    231: "ピクチャの表示",
    232: "ピクチャの移動",
    233: "ピクチャの回転",
    234: "ピクチャの色調変更",
    235: "ピクチャの消去",
    236: "天候の設定",
    241: "BGMの設定",
    242: "BGMのフェードアウト",
    243: "BGMの保存",
    244: "BGMの再開",
    245: "BGSの演奏",
    246: "BGSのフェードアウト",
    249: "MEの演奏",
    250: "SEの演奏",
    251: "SEの停止",
    261: "ムービーの再生",
    281: "マップ名表示の変更",
    282: "タイルセットの変更",
    283: "戦闘背景の変更",
    284: "遠景の変更",
    285: "指定位置の情報取得",
    301: "戦闘の処理",
    601: "戦闘の処理(勝ったとき)",
    602: "戦闘の処理(逃げたとき)",
    603: "戦闘の処理(負けたとき)",
    302: "ショップの処理",
    303: "名前入力の処理",
    311: "HPの増減",
    312: "MPの増減",
    326: "TPの増減",
    313: "ステートの変更",
    314: "全回復",
    315: "経験値の増減",
    316: "レベルの増減",
    317: "能力値の増減",
    318: "スキルの増減",
    319: "装備の変更",
    320: "名前の変更",
    321: "職業の変更",
    322: "アクター画像の変更",
    323: "乗り物画像の変更",
    324: "二つ名の変更",
    325: "プロフィールの変更",
    331: "敵キャラのHP増減",
    332: "敵キャラのMP増減",
    342: "敵キャラのTP増減",
    333: "敵キャラのステート変更",
    334: "敵キャラの全回復",
    335: "敵キャラの出現",
    336: "敵キャラの変身",
    337: "戦闘アニメーションの表示",
    339: "戦闘行動の強制",
    340: "バトルの中断",
    351: "メニュー画面を開く",
    352: "セーブ画面を開く",
    353: "ゲームオーバー",
    354: "タイトル画面に戻す",
    355: "スクリプト",
    655: "スクリプト(2行目以降)",
    356: "プラグインコマンド",
  };

  /**
   * ConvertTargetCommonEvent
   * コモンイベント用の変換対象クラス
   */
  class ConvertTargetCommonEvent extends AbstractConvertTargetEvent {
    setupTargetList(eventIdList) {
      if (eventIdList.length > 0) {
        this._targetList = eventIdList;
      } else {
        this._targetList = this._database.map(function (commonEvent) {
          return commonEvent ? String(commonEvent.id) : null;
        });
        this._targetList.shift();
      }
    }

    getFileName() {
      return "CommonEvents";
    }

    getList(name) {
      return this._database[parseInt(name)].list;
    }

    setList(name, list) {
      this._database[parseInt(name)].list = list;
    }
  }

  /**
   * ConvertTargetMapEvent
   * マップイベント用の変換対象クラス
   */
  class ConvertTargetMapEvent extends AbstractConvertTargetEvent {
    setupTargetList(eventIdList) {
      if (eventIdList.length === 0) {
        eventIdList = this._database.events
          .map(function (event) {
            return event ? String(event.id) : null;
          })
          .filter(function (event) {
            return !!event;
          });
      }
      this._targetList = eventIdList.reduce(
        function (prevData, eventId) {
          this._database.events[eventId].pages.forEach(function (page, index) {
            prevData.push(this._joinName(eventId, index));
          }, this);
          return prevData;
        }.bind(this),
        []
      );
    }

    getFileName() {
      return "Map%1".format(this._mapId.padZero(3));
    }

    getList(name) {
      return this._getEventPage(name).list;
    }

    setList(name, list) {
      this._getEventPage(name).list = list;
    }

    _getEventPage(name) {
      const names = this._splitName(name);
      return this._database.events[names[0]].pages[names[1] - 1];
    }

    _splitName(name) {
      return name.split("_").map(function (data) {
        return parseInt(data);
      });
    }

    _joinName(eventId, pageIndex) {
      return `${eventId}_${pageIndex + 1}`;
    }
  }

  /**
   * ConvertTargetTestEvent
   * イベントテスト用の変換対象クラス
   */
  class ConvertTargetTestEvent extends AbstractConvertTargetEvent {
    setupTargetList() {
      this._targetList = ["EventTest"];
    }

    getFileName() {
      return "Test_Event";
    }

    getList() {
      return this._database;
    }

    setList() {
      this._database = arguments[1];
    }
  }

  /**
   * DataSerializer
   *  Game_SheetConverterAbstract内部で使用されるデータ変換クラスです。
   */
  class DataSerializer {
    constructor(target) {
      this._utils = XLSX.utils;
      this._target = target;
    }

    serializeData(dataList) {
      dataList = dataList.filter(function (dataItem) {
        return !!dataItem;
      });
      dataList.forEach(this._parseForSerialize, this);
      this._addColumnDescriptions(dataList);
      return this._utils.json_to_sheet(dataList);
    }

    _parseForSerialize(dataItem) {
      this._target.getArrayProperties().forEach(function (property) {
        if (dataItem.hasOwnProperty(property)) {
          dataItem[property] = JSON.stringify(dataItem[property]);
        }
      });
      this._target.getSplitProperties().forEach(function (property) {
        this._parseArrayForSerialize(property, dataItem);
      }, this);
      Object.keys(this._target.getObjectProperties()).forEach(function (
        property
      ) {
        this._parseObjectForSerialize(property, dataItem);
      },
      this);
    }

    _parseArrayForSerialize(propName, dataItem) {
      if (
        !dataItem.hasOwnProperty(propName) ||
        !Array.isArray(dataItem[propName])
      ) {
        return;
      }
      dataItem[propName].forEach(function (param, index) {
        if (Array.isArray(param) || this._isObject(param)) {
          param = JSON.stringify(param);
        }
        dataItem[propName + index] = param;
      }, this);
      delete dataItem[propName];
    }

    _parseObjectForSerialize(propName, dataItem) {
      if (!this._isObject(dataItem) || !dataItem.hasOwnProperty(propName)) {
        return;
      }
      Object.keys(dataItem[propName]).forEach(function (keyName) {
        dataItem[propName + "_" + keyName] = dataItem[propName][keyName];
      });
      delete dataItem[propName];
    }

    _isObject(param) {
      return (
        Object.prototype.toString.call(param).slice(8, -1).toLowerCase() ===
        "object"
      );
    }

    _addColumnDescriptions(data) {
      const descriptions = {};
      const allDescription = this._target.getColumnDescriptions();
      Object.keys(data[0]).forEach(function (keyName) {
        descriptions[keyName] = allDescription[keyName] || "";
      }, this);
      data.unshift(descriptions);
    }

    deserializeData(sheetData) {
      const convertData = JSON.parse(
        JSON.stringify(this._utils.sheet_to_json(sheetData)),
        paramReplacer
      );
      const database = [];
      convertData.shift();
      convertData.forEach(function (dataItem) {
        this._parseForDeserialize(dataItem);
        this._target.appendData(database, dataItem);
      }, this);
      return database;
    }

    _parseForDeserialize(dataItem) {
      this._target.getSplitProperties().forEach(function (property) {
        this._parseArrayForDeserialize(property, dataItem);
      }, this);
      Object.keys(this._target.getObjectProperties()).forEach(function (
        property
      ) {
        this._parseObjectForDeserialize(
          property,
          dataItem,
          this._target.getObjectProperties()[property]
        );
      },
      this);
    }

    _parseArrayForDeserialize(propName, dataItem) {
      if (!dataItem.hasOwnProperty(`${propName}0`)) {
        return;
      }
      dataItem[propName] = [];
      let index = 0;
      while (dataItem.hasOwnProperty(`${propName}${index}`)) {
        const property = `${propName}${index}`;
        dataItem[propName][index] = dataItem[property];
        delete dataItem[property];
        index++;
      }
    }

    _parseObjectForDeserialize(propName, dataItem, properties) {
      if (!dataItem.hasOwnProperty(`${propName}_${properties[0]}`)) {
        return;
      }
      dataItem.damage = {};
      properties.forEach(function (keyName) {
        const property = `${propName}_${keyName}`;
        dataItem.damage[keyName] = dataItem[property];
        delete dataItem[property];
      });
    }
  }
})();


code:
//=============================================================================
// DisableFastForward.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.0 2016/02/22 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc イベント高速化禁止プラグイン
 * @author トリアコンタン
 *
 * @help 決定ボタンやマウスをクリックし続けた場合のイベントの
 * 高速スキップを無効化できます。
 * プラグインコマンドから禁止/許可の設定ができます。
 * 設定値はセーブデータに保存されます。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 *  イベント高速化禁止 or DISABLE_FAST_FORWARD
 *   イベントの高速スキップを禁止します。
 *
 *  イベント高速化許可 or ENABLE_FAST_FORWARD
 *   イベントの高速スキップを許可します。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";

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

  //=============================================================================
  // Game_Interpreter
  //  プラグインコマンドを追加定義します。
  //=============================================================================
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.apply(this, arguments);
    try {
      this.pluginCommandDisableFastForward(command, args);
    } catch (e) {
      if ($gameTemp.isPlaytest() && Utils.isNwjs()) {
        var window = require("nw.gui").Window.get();
        if (!window.isDevToolsOpen()) {
          var devTool = window.showDevTools();
          devTool.moveTo(0, 0);
          devTool.resizeTo(Graphics.width, Graphics.height);
          window.focus();
        }
      }
      console.log("プラグインコマンドの実行中にエラーが発生しました。");
      console.log("- コマンド名 　: " + command);
      console.log("- コマンド引数 : " + args);
      console.log("- エラー原因   : " + e.toString());
    }
  };

  Game_Interpreter.prototype.pluginCommandDisableFastForward = function (
    command,
    args
  ) {
    switch (getCommandName(command)) {
      case "イベント高速化禁止":
      case "DISABLE_FAST_FORWARD":
        $gameSystem.disableFastForward = true;
        break;
      case "イベント高速化許可":
      case "ENABLE_FAST_FORWARD":
        $gameSystem.disableFastForward = false;
        break;
    }
  };

  var _Game_System_initialize = Game_System.prototype.initialize;
  Game_System.prototype.initialize = function () {
    _Game_System_initialize.apply(this, arguments);
    this.disableFastForward = false;
  };

  var _Scene_Map_isFastForward = Scene_Map.prototype.isFastForward;
  Scene_Map.prototype.isFastForward = function () {
    return (
      !$gameSystem.disableFastForward &&
      _Scene_Map_isFastForward.apply(this, arguments)
    );
  };
})();