code:
//=============================================================================
// NYA_InfoMenuWindow2.js
//
// Version
// 2.2.0 2018/09/25 プラグインパラメータで位置や幅などが調整可能になりました。
// 2.1.0 2018/08/01 AltWindowFrameに対応しました。
// 2.0.0 2018/08/31 マップ名とプレイ時間とでウィンドウを分けてみた＆ウィンドウ背景を透明化しました。
// 1.0.0 2018/08/31 試作版完成
//=============================================================================

/*:
 * @plugindesc メニュー画面にマップ名とプレイ時間を追加します。
 * @author Nyatama
 *
 *
 * @param MapName
 * @text マップ名ウィンドウ
 * @default ================================
 *
 * @param InfoVisible_MapName
 * @text 表示する
 * @desc マップ名のウィンドウを表示します
 * @type boolean
 * @on 表示する
 * @off 表示しない
 * @default true
 * @parent MapName
 *
 * @param PosX_MapName
 * @text X軸
 * @desc マップ名のウィンドウのX位置を指定します
 * @type number
 * @default 0
 * @parent MapName
 *
 * @param PosY_MapName
 * @text Y軸
 * @desc マップ名のウィンドウのY位置を指定します
 * @type number
 * @default 462
 * @parent MapName
 *
 * @param Width_MapName
 * @text 幅
 * @desc マップ名のウィンドウの幅を指定します
 * @type number
 * @default 240
 * @parent MapName
 *
 * @param Align_MapName
 * @text 行揃え
 * @desc マップ名の行揃えを指定します
 * @type combo
 * @option right
 * @option center
 * @option left
 * @default center
 * @parent MapName
 *
 * @param Title_MapName
 * @text タイトル
 * @desc マップ名のタイトルを指定します
 * @type string
 * @default ＭＡＰ
 * @parent MapName
 *
 * @param TitleColor_MapName
 * @text タイトルカラー
 * @desc マップ名のタイトルカラーを指定します
 * 例：rgb(132, 170, 255)  #84aaff  white  system
 * @type string
 * @default system
 * @parent MapName
 *
 * @param FrameOpacity_MapName
 * @text 枠の透明度
 * @desc マップ名の枠(背景画像)の透明度を指定します【255:不透明】
 * @type number
 * @min 0
 * @max 255
 * @default 255
 * @parent MapName
 *
 * @param FrameMado_MapName
 * @text MADOのファイル名
 * @desc マップ名のMADOのフレームのファイル名を指定します
 * 空欄の場合MADOが無効になります●オススメ:Window_Status
 * @type combo
 * @option Window_Talk
 * @option Window_Battle
 * @option Window_Status
 * @option Window_Other
 * @default
 * @parent MapName
 *
 * @param PlayTime
 * @text プレイ時間ウィンドウ
 * @default ================================
 *
 * @param InfoVisible_PlayTime
 * @text 表示する
 * @desc プレイ時間のウィンドウを表示します
 * @type boolean
 * @on 表示する
 * @off 表示しない
 * @default true
 * @parent PlayTime
 *
 * @param PosX_PlayTime
 * @text X軸
 * @desc プレイ時間のウィンドウのX位置を指定します
 * @type number
 * @default 0
 * @parent PlayTime
 *
 * @param PosY_PlayTime
 * @text Y軸
 * @desc プレイ時間のウィンドウのY位置を指定します
 * @type number
 * @default 507
 * @parent PlayTime
 *
 * @param Width_PlayTime
 * @text 幅
 * @desc プレイ時間のウィンドウの幅を指定します
 * @type number
 * @default 240
 * @parent PlayTime
 *
 * @param Align_PlayTime
 * @text 行揃え
 * @desc プレイ時間の行揃えを指定します
 * @type combo
 * @option right
 * @option center
 * @option left
 * @default center
 * @parent PlayTime
 *
 * @param Title_PlayTime
 * @text タイトル
 * @desc プレイ時間のタイトルを指定します
 * @type string
 * @default ＴＩＭＥ
 * @parent PlayTime
 *
 * @param TitleColor_PlayTime
 * @text タイトルカラー
 * @desc プレイ時間のタイトルカラーを指定します
 * 例：rgb(132, 170, 255)  #84aaff  white  system
 * @type string
 * @default system
 * @parent PlayTime
  *
 * @param FrameOpacity_PlayTime
 * @text 枠の透明度
 * @desc プレイ時間の枠(背景画像)の透明度を指定します【255:不透明】
 * @type number
 * @min 0
 * @max 255
 * @default 255
 * @parent PlayTime
 *
 * @param FrameMado_PlayTime
 * @text MADOのファイル名
 * @desc プレイ時間のMADOのフレームのファイル名を指定します
 * 空欄の場合MADOが無効になります●オススメ:Window_Status
 * @type combo
 * @option Window_Talk
 * @option Window_Battle
 * @option Window_Status
 * @option Window_Other
 * @default
 * @parent PlayTime
 *
 * @help このプラグインには、プラグインコマンドはありません。

 メニュー画面に、インフォメーションウィンドウを追加します。
 ・現在のマップ名
 ・現在のプレイ時間

 ※フォントサイズを変えたり細かな調整はソースコードを編集してください

 ※MADOを使用する場合AltWindowFrameを有効にする必要があります。
*/

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

(function () {
  var parameters = PluginManager.parameters("NYA_InfoMenuWindow2");
  var InfoVisible_MapName = eval(parameters["InfoVisible_MapName"]);
  var PosX_MapName = Number(parameters["PosX_MapName"]);
  var PosY_MapName = Number(parameters["PosY_MapName"]);
  var Width_MapName = Number(parameters["Width_MapName"]);
  var Align_MapName = String(parameters["Align_MapName"]);
  var Title_MapName = String(parameters["Title_MapName"]);
  var TitleColor_MapName = String(parameters["TitleColor_MapName"]);
  var FrameOpacity_MapName = Number(parameters["FrameOpacity_MapName"]);
  var FrameMado_MapName = String(parameters["FrameMado_MapName"]);

  var InfoVisible_PlayTime = eval(parameters["InfoVisible_PlayTime"]);
  var PosX_PlayTime = Number(parameters["PosX_PlayTime"]);
  var PosY_PlayTime = Number(parameters["PosY_PlayTime"]);
  var Width_PlayTime = Number(parameters["Width_PlayTime"]);
  var Align_PlayTime = String(parameters["Align_PlayTime"]);
  var Title_PlayTime = String(parameters["Title_PlayTime"]);
  var TitleColor_PlayTime = String(parameters["TitleColor_PlayTime"]);
  var FrameOpacity_PlayTime = Number(parameters["FrameOpacity_PlayTime"]);
  var FrameMado_PlayTime = String(parameters["FrameMado_PlayTime"]);

  var _Scene_Menu_create = Scene_Menu.prototype.create;
  Scene_Menu.prototype.create = function () {
    _Scene_Menu_create.call(this);
    // インフォメーションウィンドウの追加
    this.createInformationWindow();
  };

  Scene_Menu.prototype.createInformationWindow = function () {
    if (InfoVisible_MapName) {
      this._informationWindowMapName = new Window_InformationMapName();
      this._informationWindowMapName.padding = 0;
      this._informationWindowMapName.opacity = FrameOpacity_MapName;
      this.addWindow(this._informationWindowMapName);
    }

    if (InfoVisible_PlayTime) {
      this._informationWindowPlayTime = new Window_InformationPlayTime();
      this._informationWindowPlayTime.padding = 0;
      this._informationWindowPlayTime.opacity = FrameOpacity_PlayTime;
      this.addWindow(this._informationWindowPlayTime);
    }
  };

  var _Scene_Menu_update = Scene_Menu.prototype.update;
  Scene_Menu.prototype.update = function () {
    _Scene_Menu_update.call(this);
    // インフォメーションウィンドウの更新
    if (InfoVisible_MapName) this._informationWindowMapName.refresh();
    if (InfoVisible_PlayTime) this._informationWindowPlayTime.refresh();
  };

  //-----------------------------------------------------------------------------
  // Window_InformationMapName
  //

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

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

  Window_InformationMapName.prototype.initialize = function () {
    var pos_x = PosX_MapName; // X位置
    var pos_y = PosY_MapName; // Y位置
    var width = Width_MapName; // 幅
    var height = this.fittingHeight(1); // 高さ 表示が崩れる為48以上である必要あり
    Window_Base.prototype.initialize.call(this, pos_x, pos_y, width, height);
  };

  Window_InformationMapName.prototype.refresh = function () {
    this.contents.clear();
    // マップ名
    if (TitleColor_MapName.toUpperCase() == "SYSTEM") {
      this.changeTextColor(this.systemColor());
    } else {
      this.changeTextColor(TitleColor_MapName);
    }
    this.contents.fontSize = 10;
    this.drawText(
      Title_MapName,
      this.standardPadding() + this.textPadding(),
      -12,
      56,
      "left"
    );
    this.resetTextColor();
    this.contents.fontSize = 28;
    this.drawText(
      $gameMap.displayName(),
      this.standardPadding() + 5,
      this.standardPadding(),
      this._width - 20,
      Align_MapName
    );
  };

  //以下をコメントアウトすると余白をありにできます。つまり枠を追加できます。
  //余白を入れる場合、MADO(ウィンドウビルダー)によりウィンドウの見た目を変えることができます。
  Window_InformationMapName.prototype.standardPadding = function () {
    return 5;
  };
  //コメントアウトここまで

  //-----------------------------------------------------------------------------
  // Window_InformationPlayTime
  //

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

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

  Window_InformationPlayTime.prototype.initialize = function () {
    var pos_x = PosX_PlayTime; // X位置
    var pos_y = PosY_PlayTime; // Y位置
    var width = Width_PlayTime; // 幅
    var height = this.fittingHeight(1); // 高さ 表示が崩れる為48以上である必要あり
    Window_Base.prototype.initialize.call(this, pos_x, pos_y, width, height);
  };

  Window_InformationPlayTime.prototype.refresh = function () {
    this.contents.clear();
    // プレイ時間
    if (TitleColor_PlayTime.toUpperCase() == "SYSTEM") {
      this.changeTextColor(this.systemColor());
    } else {
      this.changeTextColor(TitleColor_PlayTime);
    }
    this.contents.fontSize = 10;
    this.drawText(
      Title_PlayTime,
      this.standardPadding() + this.textPadding(),
      -12,
      56,
      "left"
    );
    this.resetTextColor();
    this.contents.fontSize = 28;
    this.drawText(
      $gameSystem.playtimeText(),
      this.standardPadding() + 5,
      this.standardPadding(),
      this._width - 20,
      Align_PlayTime
    );
  };

  //以下をコメントアウトすると余白をありにできます。つまり枠を追加できます。
  //余白を入れる場合、MADO(ウィンドウビルダー)によりウィンドウの見た目を変えることができます。
  Window_InformationPlayTime.prototype.standardPadding = function () {
    return 5;
  };
  //コメントアウトここまで

  //-----------------------------------------------------------------------------
  // AltWindowFrame対応
  //
  var _Scene_Menu_Create = Scene_Menu.prototype.create;
  Scene_Menu.prototype.create = function () {
    _Scene_Menu_Create.call(this);

    if (FrameMado_MapName) {
      var _image = ImageManager.loadSystem(FrameMado_MapName);
      this._informationWindowMapName._windowskin = _image;
      this._informationWindowMapName._refreshAllParts();
    }
    if (FrameMado_PlayTime) {
      var _image = ImageManager.loadSystem(FrameMado_PlayTime);
      this._informationWindowPlayTime._windowskin = _image;
      this._informationWindowPlayTime._refreshAllParts();
    }
  };
})();


code:
// Generated by CoffeeScript 1.10.0

/*:
 * @plugindesc 特定アイテムの数量を表示しないようにする
 * @author queue
 *
 * @help
 * アイテムのメモに<数量表記なし>と記入されたアイテムは、
 * 数量が表示されなくなります。
 */

(function () {
  window.Imported = window.Imported || {};

  window.Imported.Queue_NoNumberItem = true;

  if (!window.Imported.Queue_Lib) {
    throw new Error("require QueueLib.js");
  }

  Window_ItemList.prototype.needsNumber = function (item) {
    if (item === void 0) {
      return true;
    }
    return item.note.indexOf("<数量表記なし>") === -1;
  };

  Window_ItemList.prototype.drawItemNumber = function (item, x, y, width) {
    if (this.needsNumber(item)) {
      this.drawText(":", x, y, width - this.textWidth("00"), "right");
      return this.drawText($gameParty.numItems(item), x, y, width, "right");
    }
  };
}).call(this);

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// NpcFollower.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.1 2019/11/02 1.1.0の修正でメンバーの入れ替えを実施すると表示が不正になる場合がある問題を修正
// 1.1.0 2019/01/27 通常のフォロワーを表示せず、NPCフォロワーのみを表示できる機能を追加
// 1.0.3 2018/08/06 コアスクリプトが1.6.0より古い場合にエラーになる記述を修正
// 1.0.2 2017/01/17 プラグインコマンドが小文字でも動作するよう修正（byこまちゃん先輩）
// 1.0.1 2016/07/17 セーブデータをロードした際のエラーになる現象の修正
// 1.0.0 2016/07/14 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc NPC Follower plugin
 * @author triacontane
 *
 * @param MaxNpcNumber
 * @desc 同時に隊列に存在できるNPCの最大数です。
 * @default 1
 *
 * @param HideNormalFollower
 * @desc 隊列歩行の設定にかかわらず通常のフォロワーを一切表示せず、NPCフォロワーのみを表示します。
 * @default false
 * @type boolean
 *
 * @help マップ上の隊列の好きな位置にパーティメンバー以外のNPCを追加します。
 * NPCはデータベース上はアクターで定義してプラグインコマンドから追加、削除します。
 * 戦闘員ではないので、メニュー画面や戦闘画面には影響を与えません。
 * また、隊列表示していない場合は何も表示されません。
 *
 * 同一IDのアクターを複数追加することもできます。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * NF_NPC追加 4 1 # アクターID[4]をNPCとしてパーティの[1]番目の後ろに追加
 * NF_ADD_NPC 5 3 # アクターID[5]をNPCとしてパーティの[3]番目の後ろに追加
 * NF_NPC削除 1   # [1]番目に追加したNPCを全て削除
 * NF_REM_NPC 3   # [3]番目に追加したNPCを全て削除
 *
 * インデックスの指定は追加したNPCとは関係なく、
 * パーティの並び順(1...バトルメンバー数)を指定してください。
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc NPCフォロワープラグイン
 * @author トリアコンタン
 *
 * @param 最大同時NPC数
 * @desc 同時に隊列に存在できるNPCの最大数です。
 * @default 1
 * @type number
 * @min 1
 *
 * @param 通常フォロワーを表示しない
 * @desc 隊列歩行の設定にかかわらず通常のフォロワーを一切表示せず、NPCフォロワーのみを表示します。
 * @default false
 * @type boolean
 *
 * @help マップ上の隊列の好きな位置にパーティメンバー以外のNPCを追加します。
 * NPCはデータベース上はアクターで定義してプラグインコマンドから追加、削除します。
 * 戦闘員ではないので、メニュー画面や戦闘画面には影響を与えません。
 * また、隊列表示していない場合は何も表示されません。
 *
 * 同一IDのアクターを複数追加することもできます。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * NF_NPC追加 4 1 # アクターID[4]をNPCとしてパーティの[1]番目の後ろに追加
 * NF_ADD_NPC 5 3 # アクターID[5]をNPCとしてパーティの[3]番目の後ろに追加
 * NF_NPC削除 1   # [1]番目に追加したNPCを全て削除
 * NF_REM_NPC 3   # [3]番目に追加したNPCを全て削除
 *
 * インデックスの指定は追加したNPCとは関係なく、
 * パーティの並び順(1...バトルメンバー数)を指定してください。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";
  var pluginName = "NpcFollower";
  var metaTagPrefix = "NF";

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

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

  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 getArgNumberWithEval = function (arg, min, max) {
    if (arguments.length < 2) min = -Infinity;
    if (arguments.length < 3) max = Infinity;
    return (parseInt(eval(convertEscapeCharacters(arg)), 10) || 0).clamp(
      min,
      max
    );
  };

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

  //=============================================================================
  // パラメータの取得と整形
  //=============================================================================
  var paramMaxNpcNumber = getParamNumber(["MaxNpcNumber", "最大同時NPC数"]);
  var paramHideNormalFollower = getParamBoolean([
    "HideNormalFollower",
    "通常フォロワーを表示しない",
  ]);

  //=============================================================================
  // Game_Interpreter
  //  プラグインコマンドを追加定義します。
  //=============================================================================
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.apply(this, arguments);
    this.pluginCommandNpcFollower(
      command.replace(new RegExp(metaTagPrefix, "i"), ""),
      args
    );
  };

  Game_Interpreter.prototype.pluginCommandNpcFollower = function (
    command,
    args
  ) {
    switch (getCommandName(command)) {
      case "_NPC追加":
      case "_ADD_NPC":
        var actorId = getArgNumberWithEval(args[0]);
        $gameParty.addNpc(actorId, getArgNumberWithEval(args[1], 1));
        break;
      case "_NPC削除":
      case "_REM_NPC":
        $gameParty.removeNpc(getArgNumberWithEval(args[0], 1));
        break;
    }
  };

  //=============================================================================
  // Game_Party
  //  NPCの追加と削除を追加定義します。
  //=============================================================================
  var _Game_Party_initialize = Game_Party.prototype.initialize;
  Game_Party.prototype.initialize = function () {
    _Game_Party_initialize.apply(this, arguments);
    this.initNpc();
  };

  Game_Party.prototype.initNpc = function () {
    this._npcs = [];
    this._npcIndexes = [];
  };

  Game_Party.prototype.isNpcInvalid = function () {
    return !this._npcs;
  };

  Game_Party.prototype.initNpcIfNeed = function () {
    if (this.isNpcInvalid()) {
      this.initNpc();
      $gamePlayer.followers().initNpc();
    }
  };

  Game_Party.prototype.addNpc = function (actorId, index) {
    if (this._npcs.length < paramMaxNpcNumber) {
      this._npcs.push(actorId);
      this._npcIndexes.push(index);
      $gamePlayer.refresh();
      $gameMap.requestRefresh();
    } else {
      throw new Error("登録可能な最大数を超えています。");
    }
  };

  Game_Party.prototype.removeNpc = function (index) {
    for (var i = 0, n = this._npcs.length; i < n; i++) {
      if (this._npcIndexes[i] === index) {
        this._npcs.splice(i, 1);
        this._npcIndexes.splice(i, 1);
        i--;
      }
    }
    $gamePlayer.refresh();
    $gameMap.requestRefresh();
  };

  Game_Party.prototype.npcMembers = function () {
    return this._npcs.map(function (id) {
      return $gameActors.actor(id);
    });
  };

  Game_Party.prototype.visibleMembers = function () {
    return this._visibleMembers;
  };

  Game_Party.prototype.makeVisibleMembers = function () {
    var battleMembers = this.battleMembers();
    var npcMembers = this.npcMembers();
    var visibleMembers = [];
    for (var i = 0, n = this.maxBattleMembers() + 1; i < n; i++) {
      for (var j = 0, m = npcMembers.length; j < m; j++) {
        if (this._npcIndexes[j] === i) {
          visibleMembers.push(npcMembers[j]);
        }
      }
      if (battleMembers.length > i && !paramHideNormalFollower) {
        visibleMembers.push(battleMembers[i]);
      }
    }
    this._visibleMembers = visibleMembers;
  };

  //=============================================================================
  // Game_Followers
  //  NPCの最大数ぶんだけ余分にGame_Followerを作成します。
  //=============================================================================
  var _Game_Followers_initialize = Game_Followers.prototype.initialize;
  Game_Followers.prototype.initialize = function () {
    _Game_Followers_initialize.apply(this, arguments);
    if (paramHideNormalFollower) {
      this._data = [];
    }
    this.initNpc();
  };

  Game_Followers.prototype.initNpc = function () {
    var memberLength = this._data.length > 0 ? this._data.length + 1 : 0;
    for (var i = 0; i < paramMaxNpcNumber; i++) {
      this._data.push(new Game_Follower(memberLength + i));
    }
  };

  //=============================================================================
  // Game_Follower
  //  NPC判定を追加定義します。
  //=============================================================================
  var _Game_Follower_actor = Game_Follower.prototype.actor;
  Game_Follower.prototype.actor = function () {
    _Game_Follower_actor.apply(this, arguments);
    return $gameParty.visibleMembers()[this._memberIndex];
  };

  //=============================================================================
  // Game_Player
  //  リフレッシュまえに表示メンバーを更新します。
  //=============================================================================
  var _Game_Player_refresh = Game_Player.prototype.refresh;
  Game_Player.prototype.refresh = function () {
    $gameParty.makeVisibleMembers();
    _Game_Player_refresh.apply(this, arguments);
  };

  //=============================================================================
  // DataManager
  //  プラグイン未適用のデータをロードした場合に必要なデータを初期化します。
  //=============================================================================
  var _DataManager_loadGame = DataManager.loadGame;
  DataManager.loadGame = function (saveFileId) {
    var result = _DataManager_loadGame.apply(this, arguments);
    $gameParty.initNpcIfNeed();
    return result;
  };
})();


code:
//=============================================================================
// - OmitTarget
// OmitTarget.js
//=============================================================================

//=============================================================================
/*:
 * @plugindesc 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
 * @author 名無し蛙 (著作権は放棄。クレジット表記は不要です)
 *
 * @help
 * 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
 *
 * ↓以下、merusaiaが追記
 *
 * ■更新履歴
 * 20160704: Version 0.:  名無し蛙さんの初版。
 * 20160704: Version 1.0: merusaiaがコメントと説明文のみ追加。
 *
 * 【使い方】
 * プラグインをONにすると、戦闘画面でターゲット選択時、対象が一つの場合は省略します。
 * ドラ◯エのように、敵が一人の時、わざわざターゲットを選ぶムダな処理がなくなるので、ムダな操作を削減できます。
 * 対象が味方一人の場合も省略しています。
 *
 * ボタンやキー押しっぱなし操作ができるキーボードやゲームパッド操作ではそこまで体感はないかもしれませんが、
 * 特にタップ／クリック数をかなり削減できて、スマホユーザにも優しい設計に出来ます。
 * スマホユーザ向けのRPGには、必須のプラグインかもです。
 *
 * 【プラグインコマンド】
 * このプラグインは、プラグインコマンドを含みません。
 *
 * 【競合について】
 *   以下のメソッドを追記（一度元のメソッドを別の名前にして、call(this)で呼び出し、その後に上書き）しています。
 *    → 上記メソッドを丸ごと上書きしているプラグインとの競合に注意してください。
 *　　　 競合をチェックするには、以下を「js」フォルダ内検索をして、丸ごと上書きしているメソッドがないか調べられます。
 *　　　・Scene_Battle.prototype.selectActorSelection = function()
 *　　　・Scene_Battle.prototype.selectEnemySelection = function()
 *
 * 【著作権フリーについて】
 * このプラグインは「地球の共有物（パブリックドメイン）」です。
 * 　　・無償・有償問わず、あらゆる作品に使用でき、また自由に改変・改良・二次配布できます。
 * 　　・著作表示のわずらわしさを回避するため、著作権は放棄します。事後報告、クレジット記載も不要です。
 * 　　・もちろんクローズドに使っていただいてもOKです。是非、自分好みに改造してお使いください。
 *
 */
//=============================================================================

(function () {
  var _Scene_Battle_selectActorSelection =
    Scene_Battle.prototype.selectActorSelection;
  Scene_Battle.prototype.selectActorSelection = function () {
    _Scene_Battle_selectActorSelection.call(this);
    if (this._actorWindow.maxItems() === 1) {
      // 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
      this._actorWindow.deactivate();
      this.onActorOk();
    }
  };

  var _Scene_Battle_selectEnemySelection =
    Scene_Battle.prototype.selectEnemySelection;
  Scene_Battle.prototype.selectEnemySelection = function () {
    _Scene_Battle_selectEnemySelection.call(this);
    if (this._enemyWindow.maxItems() === 1) {
      // 戦闘画面でターゲット選択時、対象が一つの場合は省略します。
      this._enemyWindow.deactivate();
      this.onEnemyOk();
    }
  };
})();

//=============================================================================
// End of File
//=============================================================================


code:
//=============================================================================
// PANDA_AdvancedEventMove.js
//=============================================================================
// [Update History]
// 2021-06-17 Ver.1.0.0 First Release for MV/MZ.
// 2021-06-23 Ver.1.1.0 fix for subfolder (MZ 1.3.0).
// 2021-07-05 Ver.1.1.1 revert fix for subfolder (MZ 1.3.2).

/*:
 * @target MV MZ
 * @plugindesc makes Random or Approach Autonomous Movement of events sophisticated.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210617230830.html
 *
 * @help Adjust random or approaching movement of events.
 *
 * 1. When "Move at Random" in Movement Route Setting,
 * the movement direction is randomly selected from the movable directions.
 * By default, events do not move if the selected direction is immovable,
 * but this plugin makes events always move by selecting from the movable
 * directions.
 *
 * 2. When "Random" in Autonomous Movement Type,
 * by default, it is not completely random to show the movement natural,
 * there is a 1/3 chance of random movement, a 1/2 chance of moving forward,
 * and a 1/6 chance of stopping.
 * You can set the probabilities of forward and stop with plugin parameters.
 *
 * 3. When "Approach" in Autonomous Movement Type,
 * by default, to give a little play, there is a 2/3 chance of approaching
 * the player, a 1/6 chance of random movement, a 1/6 chance of moving forward.
 * You can set the probabilities of random and forward with plugin parameters.
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param RandomForwardRate
 * @text Forward Rate in Random
 * @desc Specify the probability of moving forward when Autonomous Movement Type is Random in %. The default is 50%.
 * @type number
 * @decimals 0
 * @default 50
 * @max 100
 * @min 0
 *
 * @param RandomStopRate
 * @text Stop Rate in Random
 * @desc Specify the probability of stopping when Autonomous Movement Type is Random in %. The default is 17% (1/6).
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 * @param TowardRandomRate
 * @text Random Rate in Approach
 * @desc Specify the probability of moving random when Autonomous Movement Type is Approach in %. The default is 17% (1/6).
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 * @param TowardForwardRate
 * @text Forward Rate in Approach
 * @desc Specify the probability of moving forward when Autonomous Movement Type is Approach in %. The default is 17% (1/6).
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 */

/*:ja
 * @target MV MZ
 * @plugindesc イベントのランダム移動や近づく移動をより洗練された動きにします。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210617230830.html
 *
 * @help イベントの移動をより洗練された動きに調整します。
 *
 * 1. 移動ルートの設定で「ランダムに移動」の際、
 * 移動可能な方向の中からランダムで移動方向が選択されるようになります。
 * 標準では、ランダムに選ばれた方向が移動不可だと移動が発生しませんが、
 * このプラグインを使うと移動可能な方向の中から選ぶため、必ず移動が発生します。
 *
 * 2. 自律移動を「ランダム」に設定した場合、
 * 標準では、完全にランダム移動ではなく、自然な移動に見せるため、
 * 1/3の確率でランダム移動、1/2の確率で前進、1/6の確率でその場に停止します。
 * プラグインパラメータで、前進と停止の確率をそれぞれ調整できます。
 *
 * 3. 自律移動を「近づく」に設定した場合、
 * 標準では、少し遊びを設けるため、2/3の確率でプレイヤーに近づき、
 * 1/6の確率でランダム移動、1/6の確率で今向いている方向に前進します。
 * プラグインパラメータで、ランダム移動と前進の確率をそれぞれ調整できます。
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 * @param RandomForwardRate
 * @text ランダム時前進確率
 * @desc 自律移動が「ランダム」の時に前進する確率を%で指定します。デフォルトは50%です。
 * @type number
 * @decimals 0
 * @default 50
 * @max 100
 * @min 0
 *
 * @param RandomStopRate
 * @text ランダム時停止確率
 * @desc 自律移動が「ランダム」の時に停止する確率を%で指定します。デフォルトは17%(1/6)です。
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 * @param TowardRandomRate
 * @text 近づく時ランダム確率
 * @desc 自律移動が「近づく」の時にランダム移動する確率を%で指定します。デフォルトは17%(1/6)です。
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 * @param TowardForwardRate
 * @text 近づく時前進確率
 * @desc 自律移動が「近づく」の時に前進する確率を%で指定します。デフォルトは17%(1/6)です。
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 */

/*:ko
 * @target MV MZ
 * @plugindesc 이벤트의 랜덤 이동 및 접근 이동을 더 정교하게 만듭니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210617230830.html
 *
 * @help 이벤트의 이동을 더 정교하게 조정합니다.
 *
 * 1. 이동 루트 설정에서 "랜덤으로 이동" 시,
 * 이동 가능한 방향 중에서 랜덤으로 이동 방향이 선택됩니다.
 * 표준에서는 랜덤으로 선택된 방향이 이동 불가능하면 이동이 발생하지 않지만,
 * 이 플러그인을 사용하면 이동 가능한 방향에서만 선택되기 때문에
 * 반드시 이동이 발생합니다.
 *
 * 2. 자율 이동을 "랜덤"으로 설정했을 때,
 * 표준에서는 완전히 랜덤 이동이 아니라 움직임을 자연스럽게 보여주기 위해서
 * 1/3 확률로 랜덤 이동, 1/2 확률로 전진, 1/6 확률로 그 자리에 정지합니다.
 * 플러그인 매개 변수로 전진과 정지의 확률을 각각 조정할 수 있습니다.
 *
 * 3. 자율 이동을 "접근"으로 설정했을 때,
 * 표준에서는 조금 여유를 갖게 2/3 확률로 플레이어에게 접근하고,
 * 1/6 확률로 랜덤 이동, 1/6 확률로 현재 방향으로 전진합니다.
 * 플러그인 매개 변수로 랜덤 이동과 전진의 확률을 각각 조정할 수 있습니다.
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param RandomForwardRate
 * @text 랜덤시 전진 확률
 * @desc 자율 이동이 "랜덤"일 때, 전진할 확률을 %로 지정합니다. 표준은 50%입니다.
 * @type number
 * @decimals 0
 * @default 50
 * @max 100
 * @min 0
 *
 * @param RandomStopRate
 * @text 랜덤시 정지 확률
 * @desc 자율 이동이 "랜덤"일 때, 정지할 확률을 %로 지정합니다. 표준은 17%(1/6)입니다.
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 * @param TowardRandomRate
 * @text 접근시 랜덤 확률
 * @desc 자율 이동이 "접근"일 때, 랜덤 이동할 확률을 %로 지정합니다. 표준은 17%(1/6)입니다.
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 * @param TowardForwardRate
 * @text 접근시 전진 확률
 * @desc 자율 이동이 "접근"일 때, 전진할 확률을 %로 지정합니다. 표준은 17%(1/6)입니다.
 * @type number
 * @decimals 0
 * @default 17
 * @max 100
 * @min 0
 *
 */

(() => {
  "use strict";

  // This Plugin Name
  const pluginName = decodeURIComponent(document.currentScript.src).match(
    /([^\/]+)\.js$/
  )[1];

  // Parameters
  const parameters = PluginManager.parameters(pluginName);
  const RandomForwardRate = Number(parameters["RandomForwardRate"]) || 0;
  const RandomStopRate = Number(parameters["RandomStopRate"]) || 0;
  const TowardRandomRate = Number(parameters["TowardRandomRate"]) || 0;
  const TowardForwardRate = Number(parameters["TowardForwardRate"]) || 0;

  //--------------------------------------------------
  // Game_Character.moveRandom
  //  [Modifie Definition]
  //--------------------------------------------------
  const _Game_Character_moveRandom = Game_Character.prototype.moveRandom;
  Game_Character.prototype.moveRandom = function () {
    // direction list
    const dlist = [2, 4, 6, 8].filter((d) => this.canPass(this.x, this.y, d));
    if (dlist.length > 0) {
      const d = dlist[Math.randomInt(dlist.length)];
      this.moveStraight(d);
    }
  };

  //--------------------------------------------------
  // Game_Event.moveTypeRandom
  //  [Added Definition]
  //--------------------------------------------------
  const _Game_Event_moveTypeRandom = Game_Event.prototype.moveTypeRandom;
  Game_Event.prototype.moveTypeRandom = function () {
    // make rate
    const rate = Math.randomInt(100);
    if (rate < RandomForwardRate) {
      // move forward
      if (this.canPass(this.x, this.y, this.direction())) {
        this.moveForward();
      } else {
        this.moveRandom();
      }
    } else if (rate < RandomForwardRate + RandomStopRate) {
      // stop
      this.resetStopCount();
    } else {
      // move random
      this.moveRandom();
    }
  };

  //--------------------------------------------------
  // Game_Event.moveTypeTowardPlayer
  //  [Added Definition]
  //--------------------------------------------------
  const _Game_Event_moveTypeTowardPlayer =
    Game_Event.prototype.moveTypeTowardPlayer;
  Game_Event.prototype.moveTypeTowardPlayer = function () {
    if (this.isNearThePlayer()) {
      // make rate
      const rate = Math.randomInt(100);
      if (rate < TowardRandomRate) {
        // move random
        this.moveRandom();
      } else if (rate < TowardRandomRate + TowardForwardRate) {
        // move forward
        if (this.canPass(this.x, this.y, this.direction())) {
          this.moveForward();
        } else {
          this.moveRandom();
        }
      } else {
        // move toward player
        this.moveTowardPlayer();
      }
    } else {
      // Original Process
      _Game_Event_moveTypeTowardPlayer.call(this);
    }
  };
})();


code:
//=============================================================================
// PANDA_DisplayDropItemIcon.js
//=============================================================================
// [Update History]
// 2020-09-06 Ver.1.0.0 First Release for MV/MZ.
// 2021-06-23 Ver.1.1.0 delete pluginName (for MZ 1.3.0).

/*:
 * @target MV MZ
 * @plugindesc display an item icon in obtain items message at the end of the battle.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200906031415.html
 *
 * @help In obtain item message at the end of the battle,
 * you can display the item icon at the beginning of the item name.
 *
 * This plugin changes BattleManager.displayDropItems.
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 */

/*:ja
 * @target MV MZ
 * @plugindesc 戦闘終了時のアイテム獲得メッセージにアイコンを表示します。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200906031415.html
 *
 * @help 戦闘終了時のアイテム獲得メッセージで、
 * アイテム名の頭にそのアイテムのアイコンを表示させることができます。
 *
 * BattleManager.displayDropItemsを書き換えています。
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 */

/*:ko
 * @target MV MZ
 * @plugindesc 전투 종료시의 아이템 획득 메세지에 아이콘을 표시합니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200906031415.html
 *
 * @help 전투 종료시의 아이템 획득 메세지에서
 * 아이템명 앞에 그 아이템의 아이콘을 표시시킬 수 있습니다.
 *
 * BattleManager.displayDropItems를 새로 정의합니다.
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 */

(() => {
  "use strict";

  //--------------------------------------------------
  // BattleManager.displayDropItems
  //  [New Definition]
  //--------------------------------------------------
  BattleManager.displayDropItems = function () {
    const items = this._rewards.items;
    if (items.length > 0) {
      $gameMessage.newPage();
      for (const item of items) {
        let text = "\\I[" + item.iconIndex + "]" + item.name;
        $gameMessage.add(TextManager.obtainItem.format(text));
      }
    }
  };
})();


code:
//=============================================================================
// PANDA_MultiAction.js
//=============================================================================
// [Update History]
// 2021-06-01 Ver.1.0.0 First Release for MV/MZ.
// 2021-06-23 Ver.1.1.0 fix for subfolder (MZ 1.3.0) and bug fix for transformation.
// 2021-07-05 Ver.1.1.1 revert fix for subfolder (MZ 1.3.2).

/*:
 * @target MV MZ
 * @plugindesc set the detail action pattern of enemies who have multiple action.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210601210432.html
 *
 * @help [How to Use]
 * In the action pattern of the enemies who have multiple action,
 * you can make following actions by writing them in the note of the enemies.
 *
 * <MultiActionX:Action Pattern Numbers>
 *  Select the specified actions only for the Xth action of multiple action.
 * <LastAction:Action Pattern Numbers>
 *  Cancel the after actions when the specified actions are selected.
 * The Action Pattern Numbers specifies the order of the action pattern list
 * separated by commas(,).
 *
 * Example: When the action pattern is following:
 *   - Normal Attack
 *   - Fire Magic for single target
 *   - Fire Magic for all
 *   - Special Move for all
 *  <MultiAction1:4>   -> Special Move is selected only in the 1st action.
 *  <MultiAction2:2,3> -> Fire Magics are selected only in the 2nd action.
 *  <LastAction:4>     -> Cancel the after actions if Special Move is selected.
 *   * Normal Attack is selected in either 1st or 2nd action.
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param MaxMultiAction
 * @text Max number of actions
 * @desc Specifies the maximum number of actions enemies can take in the game.
 * @type number
 * @default 3
 * @decimals 0
 * @min 1
 *
 */

/*:ja
 * @target MV MZ
 * @plugindesc 敵キャラの複数回行動で単独行動や特定回のみ有効な行動を作ります。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210601210432.html
 *
 * @help ■ 使い方
 * 複数回行動する敵キャラの行動パターンにおいて、
 * 敵キャラのメモに記述することで、以下のような行動パターンを作成できます。
 *
 * <MultiActionX:行動パターン番号>
 *  指定した行動パターンは、複数回行動のうちX回目の行動でのみ選択されます。
 * <LastAction:行動パターン番号>
 *  指定した行動パターンを選択すると、以降の複数回行動は行わなくなります。
 * 行動パターン番号は、行動パターンリストの順番をカンマ(,)区切りで指定します。
 *
 * 例：行動パターンが以下で指定されている時
 *   ・通常攻撃
 *   ・単体炎魔法
 *   ・全体炎魔法
 *   ・全体必殺技
 *  <MultiAction1:4>   → 全体必殺技は1回目の行動でのみ選択
 *  <MultiAction2:2,3> → 単体炎魔法と全体炎魔法は2回目の行動でのみ選択
 *  <LastAction:4>     → 全体必殺技を選んだらそれ以降の行動はしない
 *   ※ 通常攻撃は1回目でも2回目でも選択
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 * @param MaxMultiAction
 * @text 複数回行動最大値
 * @desc ゲーム内で敵キャラが取り得る最大の行動回数を指定します。大きくしすぎると動作が重くなります。
 * @type number
 * @default 3
 * @decimals 0
 * @min 1
 *
 */

/*:ko
 * @target MV MZ
 * @plugindesc 적의 여러 번 행동에서 1회 행동이나 특정회에만 유효한 행동을 만듭니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210601210432.html
 *
 * @help [사용법]
 * 여러 번 행동하는 적 캐릭터의 행동 패턴에서
 * 적 캐릭터의 메모란에 기술함으로 다음과 같은 행동 패턴을 만들 수 있습니다.
 *
 * <MultiActionX:행동 패턴 번호>
 *  지정된 번호의 행동 패턴은 여러 번 행동중 X번째 행동에서만 선택됩니다.
 * <LastAction:행동 패턴 번호>
 *  지정된 번호의 행동 패턴이 선택되면 이후의 행동을 안 하게 됩니다.
 * 행동 패턴 번호는 행동 패턴 리스트의 순서를 쉼표(,)로 구분하여 지정합니다.
 *
 * 예) 행동 패턴이 다음과 같이 지정되어 있을 때
 *   - 일반 공격
 *   - 단독 화염 마법
 *   - 전체 화염 마법
 *   - 전체 필살기
 *  <MultiAction1:4>   -> 전체 필살기는 첫번째 행동에서만 선택됨
 *  <MultiAction2:2,3> -> 단독 및 전체 화염 마법은 두번째 행동에서만 선택됨
 *  <LastAction:4>     -> 전체 필살기가 선택되면 이후의 행동은 하지 않음
 *   * 일반 공격은 첫번째나 두번째나 선택됨
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param MaxMultiAction
 * @text 여러 번 행동 최대치
 * @desc 게임 내에서 적 캐릭터가 취할 수 있는 최대 행동 횟수를 지정합니다. 너무 크게 하면 동작이 무거워집니다.
 * @type number
 * @default 3
 * @decimals 0
 * @min 1
 *
 */

(() => {
  "use strict";

  // This Plugin Name
  const pluginName = decodeURIComponent(document.currentScript.src).match(
    /([^\/]+)\.js$/
  )[1];

  // Parameters
  const parameters = PluginManager.parameters(pluginName);
  const MaxMultiAction = Number(parameters["MaxMultiAction"]) || 3;

  //--------------------------------------------------
  // Game_Enemy.selectAllActions
  //  [Modified Definition]
  //--------------------------------------------------
  Game_Enemy.prototype.selectAllActions = function (actionList) {
    const ratingMax = Math.max(...actionList.map((a) => a.rating));
    const ratingZero = ratingMax - 3;
    actionList = actionList.filter((a) => a.rating > ratingZero);
    const action = this.selectAction(actionList, ratingZero);
    this.action(this._actionIndex).setEnemyAction(action);
    // delete next actions if last action
    if (this._lastActionList.indexOf(action) != -1) {
      this._actions.length = this._actionIndex + 1;
    }
  };

  //--------------------------------------------------
  // Game_Enemy.makeActions
  //  [Modified Definition]
  //--------------------------------------------------
  Game_Enemy.prototype.makeActions = function () {
    Game_Battler.prototype.makeActions.call(this);
    // make multi action list
    this.makeMultiActionList();
    for (let i = 0; i < this.numActions(); i++) {
      this._actionIndex = i;
      if (this._multiActionList[i]) {
        const actionList = this._multiActionList[i].filter((a) =>
          this.isActionValid(a)
        );
        if (actionList.length > 0) {
          this.selectAllActions(actionList);
        }
      }
    }
    this.setActionState("waiting");
  };

  //--------------------------------------------------
  // Game_Enemy.makeMultiActionList
  //  [New Definition]
  //--------------------------------------------------
  Game_Enemy.prototype.makeMultiActionList = function () {
    // make last action list
    this._lastActionList = this.parseActionList(
      this.enemy().meta.LastAction
    ).map((n) => this.enemy().actions[n - 1]);
    // get meta data and initialize multi action list
    this._multiActionList = [];
    const multiActions = [];
    for (let i = 1; i <= MaxMultiAction; i++) {
      multiActions.push(
        this.parseActionList(this.enemy().meta["MultiAction" + i])
      );
      this._multiActionList.push([]);
    }
    // make multi action list
    for (let a = 0; a < this.enemy().actions.length; a++) {
      let pushed = false;
      for (let i = 0; i < MaxMultiAction; i++) {
        if (multiActions[i].indexOf(a + 1) != -1) {
          this._multiActionList[i].push(this.enemy().actions[a]);
          pushed = true;
        }
      }
      if (!pushed) {
        // can always use
        for (let i = 0; i < MaxMultiAction; i++) {
          this._multiActionList[i].push(this.enemy().actions[a]);
        }
      }
    }
  };

  //--------------------------------------------------
  // Game_Enemy.parseActionList
  //  [New Definition]
  //--------------------------------------------------
  Game_Enemy.prototype.parseActionList = function (actionList) {
    if (actionList) {
      return actionList.split(",").map(Number);
    } else {
      return [];
    }
  };
})();


code:
//=============================================================================
// PANDA_NicknameAsClass.js
//=============================================================================
// [Update History]
// 2020-09-25 Ver.1.0.0 First Release for MV/MZ.
// 2020-09-26 Ver.1.0.1 Fixed getting parameters.
// 2021-06-23 Ver.1.1.0 fix for subfolder (MZ 1.3.0).
// 2021-07-05 Ver.1.1.1 revert fix for subfolder (MZ 1.3.2).

/*:
 * @target MV MZ
 * @plugindesc display the nickname instead of the class name on status.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200925200021.html
 *
 * @help On the status window, display the Nickname instead of the Class name.
 * Also display the Class name instead of the Nickname. (can be hidden)
 *
 * In a long RPG, when you want to change the position of the actors
 * according to the progress of the story,
 * you can do "Change Nickname" with the event command.
 * You need not to make the same classes with different names.
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param NicknameVisible
 * @text Display Nickname
 * @desc Whether to display the class name as nickname on the status screen. If Off, Nickname is not displayed.
 * @type boolean
 * @default true
 */

/*:ja
 * @target MV MZ
 * @plugindesc ステータス画面等で職業名の代わりに二つ名を表示します。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200925200021.html
 *
 * @help ステータス画面等において、職業名の代わりに二つ名を表示します。
 * また、二つ名の代わりに職業名を表示します（非表示も可）。
 *
 * 長編RPGなどでストーリーの進行に応じてアクターの立場を変更したい場合、
 * イベントコマンドで「二つ名の変更」をすればよくなります。
 * 名前だけが異なる職業を複数用意する必要がなくなります。
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 * @param NicknameVisible
 * @text 二つ名の表示
 * @desc ステータス画面で職業名を二つ名として表示するかどうか。OFFにすると二つ名を表示しません。
 * @type boolean
 * @default true
 */

/*:ko
 * @target MV MZ
 * @plugindesc 정보 화면 등에서 클래스명 대신 닉네임을 표시합니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200925200021.html
 *
 * @help 정보 화면 등에서 클래스명 대신 닉네임을 표시합니다.
 * 또 닉네임 대신 클래스명을 표시합니다. (비표시도 가능)
 *
 * 장편 RPG등에서 스토리의 진행에 따라 액터의 입장을 바꾸고 싶을 때,
 * 이벤트 명령에서 "닉네임 변경"을 하면 됩니다.
 * 명칭만 다른 클래스를 여러 준비할 필요가 없습니다.
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param NicknameVisible
 * @text 닉네임 표시
 * @desc 정보 화면에서 클래스명을 닉네임으로 표시하는지. OFF로 하면 닉네임을 표시하지 않습니다.
 * @type boolean
 * @default true
 */

(() => {
  "use strict";

  // This Plugin Name
  const pluginName = decodeURIComponent(document.currentScript.src).match(
    /([^\/]+)\.js$/
  )[1];

  // Parameters
  const parameters = PluginManager.parameters(pluginName);
  const NicknameVisible = parameters["NicknameVisible"] !== "false";

  //--------------------------------------------------
  // Game_Actor.nickname
  //  [Modified Definition]
  //--------------------------------------------------
  Game_Actor.prototype.nickname = function () {
    if (NicknameVisible && $dataClasses[this._classId]) {
      return $dataClasses[this._classId].name;
    } else {
      return "";
    }
  };

  //--------------------------------------------------
  // Window_Base.drawActorClass
  //  [Modified Definition for MV]
  //--------------------------------------------------
  Window_Base.prototype.drawActorClass = function (actor, x, y, width) {
    width = width || 168;
    this.resetTextColor();
    this.drawText(actor._nickname, x, y, width);
  };

  //--------------------------------------------------
  // Window_StatusBase.drawActorClass
  //  [Modified Definition for MZ]
  //--------------------------------------------------
  Window_StatusBase.prototype.drawActorClass = function (actor, x, y, width) {
    width = width || 168;
    this.resetTextColor();
    this.drawText(actor._nickname, x, y, width);
  };
})();


code:
//=============================================================================
// PANDA_ProgressTextWindow.js
//=============================================================================
// [Update History]
// 2020-12-08 Ver.1.0.0 First Release for MZ.
// 2021-01-24 Ver.1.1.0 First Release for MV.
// 2021-01-25 Ver.1.1.1 Release for MV/MZ.
// 2021-06-23 Ver.1.2.0 fix for subfolder (MZ 1.3.0).
// 2021-07-05 Ver.1.2.1 revert fix for subfolder (MZ 1.3.2).

/*:
 * @target MV MZ
 * @plugindesc display the text of the story progress on the menu screen.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210125012307.html
 *
 * @help Add the window to display a text on the menu screen.
 * Displays the text according to the value of the variable
 * specified in the plug-in parameter.
 * It is useful for showing the next object etc. according to
 * the progress of the story.
 *
 * The window can be placed in any position
 * by specifying the XY coordinates and width / height.
 * By default, the window is placed in the empty space of the standard menu screen.
 * In MZ, at the top of the menu screen to the left of the cancel button.
 * In MV, between the menu command and the gold window.
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param ProgressVariable
 * @text Progress Variable
 * @desc Specifies the variable of the number of text to display in the window.
 * @type variable
 * @default 0
 *
 * @param ProgressText
 * @text Progress Text
 * @desc Input texts to display according to the value of Progress Variable. Progress number starts from 1. A new line by "\n".
 * @type string[]
 * @default
 *
 * @param WindowLayout
 * @text Window Layout
 * @desc Specify the position and size of the window. If default, it will be placed in the empty space of the menu screen.
 * @type struct<rect>
 *
 */
/*~struct~rect:
 *
 * @param IsDefault
 * @text Default Layout
 * @desc If ON, the window is placed in the empty space of the menu screen, and the following settings are ignored.
 * @type boolean
 * @default true
 *
 * @param Left
 * @text Window Left
 * @desc Specify the left X position of the window in pixels.
 * @type number
 * @default 0
 *
 * @param Top
 * @text Window Top
 * @desc Specify the top Y position of the window in pixels.
 * @type number
 * @default 0
 *
 * @param Width
 * @text Window Width
 * @desc Specify the width of the window in pixels.
 * @type number
 * @default 808
 *
 * @param Height
 * @text Window Height
 * @desc Specify the height of the window in pixels.
 * @type number
 * @default 52
 *
 */

/*:ja
 * @target MV MZ
 * @plugindesc メニュー画面に物語の進行を表すテキストを表示します。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210125012307.html
 *
 * @help メニュー画面にテキストを表示するウィンドウを追加します。
 * プラグインのパラメータで指定した変数の値に応じたテキストを表示します。
 * 物語の進行度に合わせて、次の目的地などを表示するのに役立ちます。
 *
 * ウィンドウは、XY座標と幅・高さを指定して、自由な位置に配置できます。
 * デフォルト状態では、デフォルトのメニュー画面の空きスペースに表示されます。
 * MZでは、メニュー画面の上部、キャンセルボタンの左側に、
 * MVでは、メニューコマンドと所持金ウィンドウの間に、表示されます。
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 * @param ProgressVariable
 * @text 進行度変数
 * @desc ウィンドウに表示するテキストの番号を表す変数を指定します。
 * @type variable
 * @default 0
 *
 * @param ProgressText
 * @text 進行度テキスト
 * @desc 進行度変数の値に応じて表示するテキストをリストで入力します。進行度は1から開始します。"\n"で改行ができます。
 * @type string[]
 * @default
 *
 * @param WindowLayout
 * @text ウィンドウレイアウト
 * @desc ウィンドウの位置とサイズを指定します。デフォルトにするとメニュー画面の空きスペースに配置されます。
 * @type struct<rect>
 *
 */
/*~struct~rect:ja:
 *
 * @param IsDefault
 * @text デフォルトレイアウト
 * @desc ONにするとウィンドウをデフォルトのメニュー画面の空きスペースに配置し、以下のレイアウト設定は無視します。
 * @type boolean
 * @default true
 *
 * @param Left
 * @text ウィンドウ左上X座標
 * @desc ウィンドウの左上のX座標をピクセルで指定します。
 * @type number
 * @default 0
 *
 * @param Top
 * @text ウィンドウ左上Y座標
 * @desc ウィンドウの左上のY座標をピクセルで指定します。
 * @type number
 * @default 0
 *
 * @param Width
 * @text ウィンドウ幅
 * @desc ウィンドウの幅をピクセルで指定します。
 * @type number
 * @default 808
 *
 * @param Height
 * @text ウィンドウ高さ
 * @desc ウィンドウの高さをピクセルで指定します。
 * @type number
 * @default 52
 *
 */

/*:ko
 * @target MV MZ
 * @plugindesc 메뉴 화면에 스토리의 진행을 나타내는 텍스트를 표시합니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20210125012307.html
 *
 * @help 메뉴 화면에 텍스트를 표시하는 윈도우를 추가합니다.
 * 플러그인 매개 변수로 지정된 변수 값에 따라 텍스트를 표시합니다.
 * 스토리 진행도에 따라 다음 목적지 등을 표시하는데 도움이 됩니다.
 *
 * 윈도우는 XY좌표와 폭/높이를 지정하여 원하는 위치에 배치할 수 있습니다.
 * 기본 상태에서는 표준 메뉴 화면의 빈 부분에 표시됩니다.
 * MZ에서는 메뉴 화면 상단, 취소 버튼 왼쪽에,
 * MV에서는 메뉴 명령과 소지금 윈도우 사이에 표시됩니다.
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param ProgressVariable
 * @text 진행도 변수
 * @desc 윈도우에 표시하는 텍스트의 번호를 나타내는 변수를 지정합니다.
 * @type variable
 * @default 0
 *
 * @param ProgressText
 * @text 진행도 텍스트
 * @desc 진행도 변수 값에 따라 표시할 텍스트를 리스트로 입력합니다. 진행도는 1부터 시작됩니다. "\n"으로 줄바꿈할 수 있습니다.
 * @type string[]
 * @default
 *
 * @param WindowLayout
 * @text 윈도우 레이아웃
 * @desc 윈도우의 위치와 크기를 지정합니다. 기본값으로 하면 표준 메뉴 화면 빈 부분에 배치됩니다.
 * @type struct<rect>
 *
 */
/*~struct~rect:ko:
 *
 * @param IsDefault
 * @text 기본 레이아웃
 * @desc ON으로 하면 윈도우가 표준 메뉴 화면의 빈 부분에 배치되고, 이하의 레이아웃 설정은 무시됩니다.
 * @type boolean
 * @default true
 *
 * @param Left
 * @text 윈도우 X좌표
 * @desc 윈도우 왼쪽 상단의 X좌표를 픽셀로 지정합니다.
 * @type number
 * @default 0
 *
 * @param Top
 * @text 윈도우 Y좌표
 * @desc 윈도우 왼쪽 상단의 Y좌표를 픽셀로 지정합니다.
 * @type number
 * @default 0
 *
 * @param Width
 * @text 윈도우 폭
 * @desc 윈도우 폭을 픽셀로 지정합니다.
 * @type number
 * @default 808
 *
 * @param Height
 * @text 윈도우 높이
 * @desc 윈도우 높이를 픽셀로 지정합니다.
 * @type number
 * @default 52
 *
 */

(() => {
  "use strict";

  // This Plugin Name
  const pluginName = decodeURIComponent(document.currentScript.src).match(
    /([^\/]+)\.js$/
  )[1];

  // Parameters
  const parameters = PluginManager.parameters(pluginName);
  const ProgressVariable = parseInt(parameters["ProgressVariable"]) || 0;
  const pt = parameters["ProgressText"] || "";
  const ProgressText = JSON.parse(pt.replace(/\\\\n/g, "\\n")) || [];
  ProgressText.unshift("");

  // Window Layout
  const WindowLayout = JSON.parse(
    parameters["WindowLayout"] || '{"IsDefault": "true"}'
  );
  const LayoutDefault = WindowLayout.IsDefault == "true";
  const WindowLeft = parseInt(WindowLayout.Left);
  const WindowTop = parseInt(WindowLayout.Top);
  const WindowWidth = parseInt(WindowLayout.Width);
  const WindowHeight = parseInt(WindowLayout.Height);

  //--------------------------------------------------
  // Scene_Menu.create
  //  [Modified Definition]
  //--------------------------------------------------
  const _Scene_Menu_create = Scene_Menu.prototype.create;
  Scene_Menu.prototype.create = function () {
    _Scene_Menu_create.call(this);
    this.createProgressWindow();
  };

  //--------------------------------------------------
  // Scene_Menu.createProgressWindow
  //  [New Definition]
  //--------------------------------------------------
  Scene_Menu.prototype.createProgressWindow = function () {
    const rect = this.progressWindowRect();
    this._progressWindow = new Window_Progress(rect);
    this.addWindow(this._progressWindow);
  };

  //--------------------------------------------------
  // Scene_Menu.progressWindowRect
  //  [New Definition]
  //--------------------------------------------------
  Scene_Menu.prototype.progressWindowRect = function () {
    if (LayoutDefault) {
      if (Utils.RPGMAKER_NAME === "MZ") {
        // for MZ
        const ww = this._cancelButton
          ? this._cancelButton.x
          : Graphics.boxWidth;
        const wh = this.buttonAreaHeight() - this.buttonAreaTop();
        const wx = 0;
        const wy = this.buttonAreaTop();
        return new Rectangle(wx, wy, ww, wh);
      } else if (Utils.RPGMAKER_NAME === "MV") {
        // for MV
        const wx = this._commandWindow.x;
        const wy = this._commandWindow.y + this._commandWindow.height;
        const ww = this._commandWindow.width;
        const wh = this._goldWindow.y - wy;
        return new Rectangle(wx, wy, ww, wh);
      }
    } else {
      return new Rectangle(WindowLeft, WindowTop, WindowWidth, WindowHeight);
    }
  };

  //--------------------------------------------------
  // Window_Progress
  //  [New Definition]
  //--------------------------------------------------
  function Window_Progress() {
    this.initialize(...arguments);
  }

  Window_Progress.prototype = Object.create(Window_Help.prototype);
  Window_Progress.prototype.constructor = Window_Progress;

  Window_Progress.prototype.initialize = function (rect) {
    if (Utils.RPGMAKER_NAME === "MZ") {
      // for MZ
      Window_Help.prototype.initialize.call(this, rect);
    } else if (Utils.RPGMAKER_NAME === "MV") {
      // for MV
      Window_Base.prototype.initialize.call(
        this,
        rect.x,
        rect.y,
        rect.width + 20,
        rect.height
      );
    }
    this.setProgressText();
  };

  Window_Progress.prototype.updatePadding = function () {
    if (this.padding * 2 + this.lineHeight() > this._height) {
      this.padding = (this._height - this.lineHeight()) / 2;
    }
  };

  Window_Progress.prototype.setProgressText = function () {
    const p = $gameVariables.value(ProgressVariable) || 0;
    const text = ProgressText[p] || "";
    this.setTextP(text);
  };

  Window_Progress.prototype.setTextP = function (text) {
    if (this._text !== text) {
      this._text = text;
      this.refresh();
    }
  };

  Window_Progress.prototype.refresh = function () {
    this.contents.clear();
    this.drawTextExP(this._text, this.textPadding(), 0);
  };

  Window_Progress.prototype.drawTextExP = function (text, x, y) {
    if (text) {
      var textState = { index: 0, x: x, y: y, left: x };
      textState.text = this.convertEscapeCharacters(text);
      textState.height = this.calcTextHeight(textState, false);
      this.resetFontSettings();
      this.contents.fontSize = 12
      while (textState.index < textState.text.length) {
        this.processCharacter(textState);
      }
      return textState.x - x;
    } else {
      return 0;
    }
  };
})();


code:
//=============================================================================
// PANDA_SEBeforeChoices.js
//=============================================================================
// [Update History]
// 2020-09-27 Ver.1.0.0 First Release for MV/MZ.
// 2021-06-23 Ver.1.1.0 fix for subfolder (MZ 1.3.0).
// 2021-07-05 Ver.1.1.1 revert fix for subfolder (MZ 1.3.2).

/*:
 * @target MV MZ
 * @plugindesc play SE when a choices list is displayed.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200927221414.html
 *
 * @help When the choices list is displayed by the event command "Show Choices",
 * play the SE specified by the plugin parameters.
 * Playing SE makes it easier to recognize that you have a choice.
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param SEFileName
 * @text SE File Name
 * @desc Specify the File Name of the SE to play.
 * @type file
 * @dir audio/se/
 *
 * @param SEVolume
 * @text SE Volume
 * @desc Specify the Volume value of the SE to play.
 * @type number
 * @decimal 0
 * @max 100
 * @min 0
 * @default 90
 *
 * @param SEPitch
 * @text SE Pitch
 * @desc Specify the Pitch value of the SE to play.
 * @type number
 * @decimal 0
 * @max 150
 * @min 50
 * @default 100
 *
 * @param SEPan
 * @text SE Pan
 * @desc Specify the Pan value of the SE to play.
 * @type number
 * @decimal 0
 * @max 100
 * @min -100
 * @default 0
 */

/*:ja
 * @target MV MZ
 * @plugindesc 選択肢の表示時にSEを演奏します。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200927221414.html
 *
 * @help イベントコマンド「選択肢の表示」で選択肢が表示される際に、
 * プラグインパラメータで指定したSEを鳴らします。
 * SEを鳴らすことで、選択肢があることが認識しやすくなります。
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 * @param SEFileName
 * @text SEファイル名
 * @desc 演奏するSEのファイル名を指定します。
 * @type file
 * @dir audio/se/
 *
 * @param SEVolume
 * @text SE音量
 * @desc 演奏するSEの音量を指定します。
 * @type number
 * @decimal 0
 * @max 100
 * @min 0
 * @default 90
 *
 * @param SEPitch
 * @text SEピッチ
 * @desc 演奏するSEのピッチを指定します。
 * @type number
 * @decimal 0
 * @max 150
 * @min 50
 * @default 100
 *
 * @param SEPan
 * @text SE位相
 * @desc 演奏するSEの位相を指定します。
 * @type number
 * @decimal 0
 * @max 100
 * @min -100
 * @default 0
 */

/*:ko
 * @target MV MZ
 * @plugindesc 선택지가 표시될 때에 SE를 재생합니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200927221414.html
 *
 * @help 이벤트 명령 "선택지 표시"로 선택지가 표시될 때
 * 매개 변수에서 지정한 SE를 울립니다.
 * SE를 연주함으로써 선택지가 있는 것을 쉽게 인식할 수 있습니다.
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 *
 * @param SEFileName
 * @text SE 파일명
 * @desc 재생할 SE의 파일명을 지정합니다.
 * @type file
 * @dir audio/se/
 *
 * @param SEVolume
 * @text SE 볼륨
 * @desc 재생할 SE의 볼륨 값을 지정합니다.
 * @type number
 * @decimal 0
 * @max 100
 * @min 0
 * @default 90
 *
 * @param SEPitch
 * @text SE 빠르기
 * @desc 재생할 SE의 빠르기 값을 지정합니다.
 * @type number
 * @decimal 0
 * @max 150
 * @min 50
 * @default 100
 *
 * @param SEPan
 * @text SE 좌우
 * @desc 재생할 SE의 좌우 값을 지정합니다.
 * @type number
 * @decimal 0
 * @max 100
 * @min -100
 * @default 0
 */

(() => {
  "use strict";

  // This Plugin Name
  const pluginName = decodeURIComponent(document.currentScript.src).match(
    /([^\/]+)\.js$/
  )[1];

  // Parameters
  const parameters = PluginManager.parameters(pluginName);
  const SEFileName = parameters["SEFileName"];
  const SEVolume = Number(parameters["SEVolume"]);
  const SEPitch = Number(parameters["SEPitch"]);
  const SEPan = Number(parameters["SEPan"]);

  // SE
  const se = { name: SEFileName, volume: SEVolume, pitch: SEPitch, pan: SEPan };

  //--------------------------------------------------
  // Window_ChoiceList.start
  //  [Added Definition]
  //--------------------------------------------------
  const _Window_ChoiceList_start = Window_ChoiceList.prototype.start;
  Window_ChoiceList.prototype.start = function () {
    AudioManager.playSe(se);
    _Window_ChoiceList_start.call(this);
  };
})();


code:
//
//  永続ステート ver1.00
//
// author yana
//

var Imported = Imported || {};
Imported["PermanentState"] = 1.0;
/*:
 * @plugindesc ver1.00/戦闘不能や全回復で解除されないステートを設定できるようにします。
 * @author Yana
 *
 * @help ------------------------------------------------------
 * 使用方法
 * ------------------------------------------------------
 * ステートのメモ欄に
 * <永続ステート>
 * または、
 * <Permanent>
 * と記述すると、そのステートは戦闘不能や全回復で解除されなくなります。
 * それ以外は通常のステートと同じようにターン経過、バトル終了、解除効果などで
 * 解除されます。
 *
 * ------------------------------------------------------
 * 利用規約
 * ------------------------------------------------------
 * 使用に制限はありません。商用、アダルト、いずれにも使用できます。
 * 二次配布も制限はしませんが、サポートは行いません。
 * 著作表示は任意です。行わなくても利用できます。
 * 要するに、特に規約はありません。
 * バグ報告や使用方法等のお問合せはネ実ツクールスレ、または、Twitterにお願いします。
 * https://twitter.com/yanatsuki_
 * 素材利用は自己責任でお願いします。
 * ------------------------------------------------------
 * 更新履歴:
 * ver1.00:
 * 公開
 */

(function () {
  ////////////////////////////////////////////////////////////////////////////////////

  var parameters = PluginManager.parameters("PermanentState");

  ////////////////////////////////////////////////////////////////////////////////////

  DataManager.isPermanent = function (state) {
    if (!state) {
      return false;
    }
    return !!state.meta["永続ステート"] || !!state.meta["Permanent"];
  };

  ////////////////////////////////////////////////////////////////////////////////////

  var __GBBase_clearStates = Game_BattlerBase.prototype.clearStates;
  Game_BattlerBase.prototype.clearStates = function () {
    var states = this._states ? this._states.clone() : [];
    var turns = this._stateTurns ? JsonEx.makeDeepCopy(this._stateTurns) : {};
    __GBBase_clearStates.call(this);
    if (states.length < 1) {
      return;
    }
    states.forEach(
      function (stateId) {
        var state = $dataStates[stateId];
        if (DataManager.isPermanent(state)) {
          this._states.push(state.id);
          this._stateTurns[state.id] = turns[state.id];
        }
      }.bind(this)
    );
  };

  ////////////////////////////////////////////////////////////////////////////////////
})();


code:
//=============================================================================
// PictureAnimation.js
// ----------------------------------------------------------------------------
// (C) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.6.1 2020/12/06 1.6.0の機能追加で最後のセルの最後のフレームまで到達したときに完了扱いにするよう修正
// 1.6.0 2020/10/24 ピクチャのアニメーション完了まで次の命令に移行しない設定を追加
// 1.5.10 2020/01/30 現在のセル番号を取得できるスクリプトのヘルプを追加
// 1.5.9 2020/01/26 アニメーション中のピクチャを別のピクチャに差し替えて表示したとき、クロスフェード用の半透明ピクチャが残ってしまう場合がある不具合を修正
// 1.5.8 2019/10/27 アニメーションタイプが1以外の場合に、非ループアニメの終了位置が間違っている問題を修正
// 1.5.7 2019/04/20 コマンド「PA_SOUND」にて「1」番目のセルを指定したとき、アニメーション開始直後にも演奏されるよう修正
// 1.5.6 2019/03/03 シーン外のピクチャのアニメーションおよび効果音演奏を無効にするよう修正
// 1.5.5 2019/02/13 コマンド「PA_SET_CELL」において0番(最初のセル)に対する指定が機能しない問題を修正
// 1.5.4 2019/02/09 1.5.3の修正によりセルパターンを指定しないでアニメ再生するとエラーになる問題を修正
// 1.5.3 2019/02/27 セルパターンの直接指定でアニメ再生する際、最初のセルが必ず1番になってしまう現象を修正
// 1.5.2 2018/03/04 縦及び横でアニメーションピクチャを表示した後、同じ番号でピクチャの表示をすると正常に表示されない場合がある不具合を修正
// 1.5.1 2017/08/22 アニメーション再生中に、セル数が少ない別のアニメーションに切り替えたときにエラーが発生する場合がある現象を修正
// 1.5.0 2017/07/03 ループしないアニメーションの終了後に最初のセルに戻るかどうかを選択できる機能を追加
// 1.4.0 2016/09/03 アニメーションに合わせて指定したSEを演奏する機能を追加
// 1.3.2 2016/05/11 クロスフェードを指定していた場合に2回目のアニメ表示でエラーになる場合がある問題を修正
// 1.3.1 2016/03/15 ピクチャ上に戦闘アニメを表示するプラグイン「PictureOnAnimation」との競合を解消
//                  原点を中央したピクチャにクロスフェードを行うと表示位置がずれる問題を修正
// 1.3.0 2016/02/28 セル番号を変数と連動する機能を追加
//                  処理の負荷を少し軽減
// 1.2.3 2016/02/07 戦闘画面でもピクチャのアニメーションができるように修正
// 1.2.2 2016/01/24 空のピクチャを表示しようとした際にエラーが発生する現象を修正
// 1.2.1 2016/01/16 同じ画像を指定してピクチャ表示→アニメーション準備→ピクチャ表示の順で実行した
//                  場合にエラーが発生する現象の修正
// 1.2.0 2016/01/04 セルのパターンを自由に指定できる機能を追加
//                  セルの最大数を100から200に拡大
// 1.1.2 2015/12/24 クロスフェードによる画像切替に対応しました
// 1.1.1 2015/12/21 ピクチャのファイル名を連番方式で指定できる機能を追加
//                  アニメーションの強制終了の機能を追加
// 1.0.0 2015/12/19 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc ピクチャのアニメーションプラグイン
 * @author トリアコンタン
 *
 * @param 最初のセルに戻る
 * @desc ループしないアニメーションの終了後、最初のセルに戻ります。無効にすると最後のセルで止まります。
 * @default true
 * @type boolean
 *
 * @help 指定したフレーム間隔でピクチャをアニメーションします。
 * アニメーションしたいセル画像（※）を用意の上
 * 以下のコマンドを入力してください。
 *
 * 1. ピクチャのアニメーション準備（プラグインコマンド）
 * 2. ピクチャの表示（通常のイベントコマンド）
 * 3. ピクチャのアニメーション開始（プラグインコマンド）
 * 4. ピクチャのアニメーション終了（プラグインコマンド）
 *
 * ※配置方法は以下の3通りがあります。
 *  縦　：セルを縦に並べて全体を一つのファイルにします。
 *  横　：セルを横に並べて全体を一つのファイルにします。
 *  連番：連番のセル画像を複数用意します。(original部分は任意の文字列)
 *   original00.png(ピクチャの表示で指定するオリジナルファイル)
 *   original01.png
 *   original02.png...
 *
 * 要注意！　配置方法の連番を使う場合、デプロイメント時に
 * 未使用ファイルとして除外される可能性があります。
 * その場合、削除されたファイルを入れ直す等の対応が必要です。
 *
 * また、単にアニメーションさせる以外にも、プラグインコマンドから
 * セル番号を直接指定したり、変数の値とセル番号を連動させたりできます。
 * 紙芝居のような演出や、条件次第で立ち絵の表示状態を変化させたりする場合に
 * 有効です。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 *  PA_INIT or
 *  ピクチャのアニメーション準備 [セル数] [フレーム数] [セル配置方法] [フェード時間]
 *  　ピクチャをアニメーション対象にする準備をします。
 *  　「ピクチャの表示」の直前に実行してください。
 *  　セル数　　　：アニメーションするセル画の数（最大200枚）
 *  　フレーム数　：アニメーション間隔のフレーム数（最低でも1を設定）
 *  　セル配置方向：セルの配置（縦 or 横 or 連番）
 *  　フェード時間：画像切替に掛かるフレーム数（0にするとフェードしない）
 *  使用例：PA_INIT 4 10 連番 20
 *
 *  PA_START or
 *  ピクチャのアニメーション開始 [ピクチャ番号] [アニメーションタイプ] [カスタムパターン配列]
 *  　指定したピクチャ番号のピクチャをアニメーションを開始します。
 *  　一周するとアニメーションは自動で止まります。
 *
 *  　アニメーションのタイプは以下の3パターンがあります。
 *  　　例：セル数が 4 の場合
 *  　　　タイプ1: 1→2→3→4→1→2→3→4...
 *  　　　タイプ2: 1→2→3→4→3→2→1→2...
 *  　　　タイプ3: 好きな順番を配列で指定（セルの最小値は 1 です）
 *  使用例：PA_START 1 2
 *  　　　　PA_START 1 3 [1,2,1,3,1,4]
 *
 *  PA_START_LOOP or
 *  ピクチャのループアニメーション開始 [ピクチャ番号] [アニメーションタイプ] [カスタムパターン配列]
 *  　指定したピクチャ番号のピクチャをアニメーションを開始します。
 *  　明示的に終了するまでアニメーションが続きます。
 *  使用例：PA_START_LOOP 1 2
 *  　　　　PA_START_LOOP 1 3 [1,2,1,3,1,4]
 *
 *  PA_STOP or
 *  ピクチャのアニメーション終了 [ピクチャ番号]
 *  　指定したピクチャ番号のピクチャをアニメーションを終了します。
 *  　一番上のセルに戻った時点でアニメーションが止まります。
 *  使用例：PA_STOP 1
 *
 *  PA_STOP_FORCE or
 *  ピクチャのアニメーション強制終了 [ピクチャ番号]
 *  　指定したピクチャ番号のピクチャをアニメーションを終了します。
 *  　現在表示しているセルでアニメーションが止まります。
 *  使用例：PA_STOP_FORCE 1
 *
 *  PA_SET_CELL or
 *  ピクチャのアニメーションセル設定 [ピクチャ番号] [セル番号] [ウェイトあり]
 *  　アニメーションのセルを直接設定します。（セルの最小値は 1 です）
 *  　任意のタイミングでアニメーションしたい場合に有効です。
 *  　ウェイトありを設定すると、クロスフェード中はイベントの実行を待機します。
 *  使用例：PA_SET_CELL 1 3 ウェイトあり
 *
 *  PA_PROG_CELL or
 *  ピクチャのアニメーションセル進行 [ピクチャ番号] [ウェイトあり]
 *  　アニメーションのセルをひとつ先に進めます。
 *  　任意のタイミングでアニメーションしたい場合に有効です。
 *  　ウェイトありを設定すると、クロスフェード中はイベントの実行を待機します。
 *  使用例：PA_PROG_CELL 1 ウェイトあり
 *
 *  PA_SET_VARIABLE or
 *  ピクチャのアニメーションセル変数の設定 [ピクチャ番号] [変数番号]
 *  　アニメーションのセルを指定した変数と連動させます。
 *  　変数の値が変化すると表示しているセルも自動的に変化します。
 *  使用例：PA_SET_VARIABLE 1 2
 *
 *  PA_SOUND or
 *  ピクチャのアニメーション効果音予約 [セル番号]
 *  　アニメーションのセルが切り替わったタイミングで効果音を演奏します。
 *  　このコマンドの直後にイベントコマンド「SEの演奏」を実行すると
 *  　その場でSEは演奏されず、ピクチャのアニメーション開始後に指定のタイミングで
 *  　演奏されるようになります。
 *  　必ずピクチャのアニメーション開始前に実行してください。
 *
 *  PA_WAIT or
 *  ピクチャのアニメーションウェイト [ピクチャ番号]
 * 　　指定したピクチャ番号のアニメーション再生が終了するまでウェイトします。
 *
 * スクリプト詳細
 *
 * アニメーション中のピクチャに対して現在のセル番号を取得します。
 * イベントコマンド「変数の操作」や「条件分岐」で使用できます。
 * ピクチャを表示していないときに実行するとエラーになります。
 * $gameScreen.picture(1).cell; // ピクチャ番号[1]のセルを取得
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
(function () {
  "use strict";
  var pluginName = "PictureAnimation";

  var settings = {
    /* maxCellAnimation:セル数の最大値 */
    maxCellAnimation: 200,
  };

  var getParamString = 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 "";
  };

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

  //=============================================================================
  // ローカル関数
  //  プラグインパラメータやプラグインコマンドパラメータの整形やチェックをします
  //=============================================================================
  var getCommandName = function (command) {
    return (command || "").toUpperCase();
  };

  var getArgArrayString = function (args, upperFlg) {
    var values = getArgString(args, upperFlg);
    return (values || "").split(",");
  };

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

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

  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 convertEscapeCharacters = function (text) {
    if (text == null) text = "";
    var window = SceneManager._scene._windowLayer.children[0];
    return window ? window.convertEscapeCharacters(text) : text;
  };

  //=============================================================================
  // パラメータの取得と整形
  //=============================================================================
  var param = {};
  param.returnToFirstCell = getParamBoolean([
    "ReturnToFirstCell",
    "最初のセルに戻る",
  ]);

  //=============================================================================
  // 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.pluginCommandPictureAnimation(command, args);
  };

  Game_Interpreter.prototype.pluginCommandPictureAnimation = function (
    command,
    args
  ) {
    var pictureNum,
      animationType,
      picture,
      cellNumber,
      frameNumber,
      direction,
      fadeDuration,
      wait,
      customArray;
    switch (getCommandName(command)) {
      case "PA_INIT":
      case "ピクチャのアニメーション準備":
        cellNumber = getArgNumber(args[0], 1, settings.maxCellAnimation);
        frameNumber = getArgNumber(args[1], 1, 9999);
        direction = getArgString(args[2], true) || "縦";
        fadeDuration = getArgNumber(args[3], 0, 9999) || 0;
        $gameScreen.setPicturesAnimation(
          cellNumber,
          frameNumber,
          direction,
          fadeDuration
        );
        break;
      case "PA_SOUND":
      case "ピクチャのアニメーション効果音予約":
        cellNumber = getArgNumber(args[0], 1, settings.maxCellAnimation);
        this.reservePaSound(cellNumber);
        break;
      case "PA_START":
      case "ピクチャのアニメーション開始":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        animationType = getArgNumber(args[1], 1, 3);
        customArray = getArgArrayNumber(args[2], 1, settings.maxCellAnimation);
        picture = $gameScreen.picture(pictureNum);
        if (picture)
          picture.startAnimationFrame(animationType, false, customArray);
        break;
      case "PA_START_LOOP":
      case "ピクチャのループアニメーション開始":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        animationType = getArgNumber(args[1], 1, 3);
        customArray = getArgArrayNumber(args[2], 1, settings.maxCellAnimation);
        picture = $gameScreen.picture(pictureNum);
        if (picture)
          picture.startAnimationFrame(animationType, true, customArray);
        break;
      case "PA_STOP":
      case "ピクチャのアニメーション終了":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        picture = $gameScreen.picture(pictureNum);
        if (picture) picture.stopAnimationFrame(false);
        break;
      case "PA_STOP_FORCE":
      case "ピクチャのアニメーション強制終了":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        picture = $gameScreen.picture(pictureNum);
        if (picture) picture.stopAnimationFrame(true);
        break;
      case "PA_SET_CELL":
      case "ピクチャのアニメーションセル設定":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        cellNumber = getArgNumber(args[1], 0, settings.maxCellAnimation);
        wait = getArgString(args[2]);
        picture = $gameScreen.picture(pictureNum);
        if (picture) {
          if (wait === "ウェイトあり" || wait.toUpperCase() === "WAIT")
            this.wait(picture._fadeDuration);
          picture.cell = cellNumber;
        }
        break;
      case "PA_PROG_CELL":
      case "ピクチャのアニメーションセル進行":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        wait = getArgString(args[1]);
        picture = $gameScreen.picture(pictureNum);
        if (picture) {
          if (wait === "ウェイトあり" || wait.toUpperCase() === "WAIT")
            this.wait(picture._fadeDuration);
          picture.addCellCount();
        }
        break;
      case "PA_SET_VARIABLE":
      case "ピクチャのアニメーションセル変数の設定":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        picture = $gameScreen.picture(pictureNum);
        if (picture) picture.linkToVariable(getArgNumber(args[1]));
        break;
      case "PA_WAIT":
      case "ピクチャのアニメーションウェイト":
        pictureNum = getArgNumber(args[0], 1, $gameScreen.maxPictures());
        picture = $gameScreen.picture(pictureNum);
        if (picture) {
          this.waitForPictureAnimation(pictureNum);
        }
        break;
    }
  };

  Game_Interpreter.prototype.reservePaSound = function (cellNumber) {
    this._paSoundFrame = cellNumber;
  };

  var _Game_Interpreter_command250 = Game_Interpreter.prototype.command250;
  Game_Interpreter.prototype.command250 = function () {
    if (this._paSoundFrame) {
      var se = this._params[0];
      AudioManager.loadStaticSe(se);
      $gameScreen.addPaSound(se, this._paSoundFrame);
      this._paSoundFrame = null;
      return true;
    }
    return _Game_Interpreter_command250.apply(this, arguments);
  };

  const _Game_Interpreter_updateWaitMode =
    Game_Interpreter.prototype.updateWaitMode;
  Game_Interpreter.prototype.updateWaitMode = function () {
    if (this._waitMode === "pictureAnimation") {
      const picture = $gameScreen.picture(this._waitPictureId);
      if (picture && picture.isAnimationPlaying()) {
        return true;
      } else {
        this._waitPictureId = 0;
        this._waitMode = "";
        return false;
      }
    } else {
      return _Game_Interpreter_updateWaitMode.apply(this, arguments);
    }
  };

  Game_Interpreter.prototype.waitForPictureAnimation = function (pictureId) {
    this.setWaitMode("pictureAnimation");
    this._waitPictureId = pictureId;
  };

  //=============================================================================
  // Game_Screen
  //  アニメーション関連の情報を追加で保持します。
  //=============================================================================
  Game_Screen.prototype.setPicturesAnimation = function (
    cellNumber,
    frameNumber,
    direction,
    fadeDuration
  ) {
    this._paCellNumber = cellNumber;
    this._paFrameNumber = frameNumber;
    this._paDirection = direction;
    this._paFadeDuration = fadeDuration;
  };

  Game_Screen.prototype.addPaSound = function (sound, frame) {
    if (!this._paSounds) this._paSounds = [];
    this._paSounds[frame] = sound;
  };

  Game_Screen.prototype.clearPicturesAnimation = function () {
    this._paCellNumber = 1;
    this._paFrameNumber = 1;
    this._paDirection = "";
    this._paFadeDuration = 0;
    this._paSounds = null;
  };

  var _Game_Screen_showPicture = Game_Screen.prototype.showPicture;
  Game_Screen.prototype.showPicture = function (
    pictureId,
    name,
    origin,
    x,
    y,
    scaleX,
    scaleY,
    opacity,
    blendMode
  ) {
    _Game_Screen_showPicture.apply(this, arguments);
    var realPictureId = this.realPictureId(pictureId);
    if (this._paCellNumber > 1) {
      this._pictures[realPictureId].setAnimationFrameInit(
        this._paCellNumber,
        this._paFrameNumber,
        this._paDirection,
        this._paFadeDuration,
        this._paSounds
      );
      this.clearPicturesAnimation();
    }
  };

  Game_Screen.prototype.isActivePicture = function (picture) {
    var realId = this._pictures.indexOf(picture);
    return realId > this.maxPictures() === $gameParty.inBattle();
  };

  //=============================================================================
  // Game_Picture
  //  アニメーション関連の情報を追加で保持します。
  //=============================================================================
  var _Game_Picture_initialize = Game_Picture.prototype.initialize;
  Game_Picture.prototype.initialize = function () {
    _Game_Picture_initialize.call(this);
    this.initAnimationFrameInfo();
  };

  Game_Picture.prototype.initAnimationFrameInfo = function () {
    this._cellNumber = 1;
    this._frameNumber = 1;
    this._cellCount = 0;
    this._frameCount = 0;
    this._animationType = 0;
    this._customArray = null;
    this._loopFlg = false;
    this._direction = "";
    this._fadeDuration = 0;
    this._fadeDurationCount = 0;
    this._prevCellCount = 0;
    this._animationFlg = false;
    this._linkedVariable = 0;
    this._cellSes = [];
  };

  Game_Picture.prototype.direction = function () {
    return this._direction;
  };

  Game_Picture.prototype.cellNumber = function () {
    return this._cellNumber;
  };

  Game_Picture.prototype.prevCellCount = function () {
    return this._prevCellCount;
  };

  Game_Picture.prototype.isMulti = function () {
    var dir = this.direction();
    return dir === "連番" || dir === "N";
  };

  /**
   * The cellCount of the Game_Picture (0 to cellNumber).
   *
   * @property cellCount
   * @type Number
   */
  Object.defineProperty(Game_Picture.prototype, "cell", {
    get: function () {
      if (this._linkedVariable > 0) {
        return $gameVariables.value(this._linkedVariable) % this._cellNumber;
      }
      switch (this._animationType) {
        case 3:
          return (this._customArray[this._cellCount] - 1).clamp(
            0,
            this._cellNumber - 1
          );
        case 2:
          return (
            this._cellNumber -
            1 -
            Math.abs(this._cellCount - (this._cellNumber - 1))
          );
        case 1:
          return this._cellCount;
        default:
          return this._cellCount;
      }
    },
    set: function (value) {
      var newCellCount = value % this.getCellNumber();
      if (this._cellCount !== newCellCount) {
        this._prevCellCount = this.cell;
        this._fadeDurationCount = this._fadeDuration;
      }
      this._cellCount = newCellCount;
    },
  });

  Game_Picture.prototype.getCellNumber = function () {
    switch (this._animationType) {
      case 3:
        return this._customArray.length;
      case 2:
        return (this._cellNumber - 1) * 2;
      case 1:
        return this._cellNumber;
      default:
        return this._cellNumber;
    }
  };

  var _Game_Picture_update = Game_Picture.prototype.update;
  Game_Picture.prototype.update = function () {
    _Game_Picture_update.call(this);
    if (this.isFading()) {
      this.updateFading();
    } else if (this.hasAnimationFrame() && this.isActive()) {
      this.updateAnimationFrame();
    } else if (this._lastFrameCount > 0) {
      this._lastFrameCount--;
    }
  };

  Game_Picture.prototype.linkToVariable = function (variableNumber) {
    this._linkedVariable = variableNumber.clamp(
      1,
      $dataSystem.variables.length
    );
  };

  Game_Picture.prototype.updateAnimationFrame = function () {
    this._frameCount = (this._frameCount + 1) % this._frameNumber;
    if (this._frameCount === 0) {
      this.addCellCount();
      this.playCellSe();
      if (this.isEndFirstLoop() && !this._loopFlg) {
        this._animationFlg = false;
        this._lastFrameCount = this._frameNumber;
      }
    }
  };

  Game_Picture.prototype.isEndFirstLoop = function () {
    return (
      this._cellCount ===
      (param.returnToFirstCell ? 0 : this.getCellNumber() - 1)
    );
  };

  Game_Picture.prototype.updateFading = function () {
    this._fadeDurationCount--;
  };

  Game_Picture.prototype.prevCellOpacity = function () {
    if (this._fadeDuration === 0) return 0;
    return (this.opacity() / this._fadeDuration) * this._fadeDurationCount;
  };

  Game_Picture.prototype.addCellCount = function () {
    this.cell = this._cellCount + 1;
  };

  Game_Picture.prototype.playCellSe = function () {
    var se = this._cellSes[this.cell + 1];
    if (se) {
      AudioManager.playSe(se);
    }
  };

  Game_Picture.prototype.setAnimationFrameInit = function (
    cellNumber,
    frameNumber,
    direction,
    fadeDuration,
    cellSes
  ) {
    this._cellNumber = cellNumber;
    this._frameNumber = frameNumber;
    this._frameCount = 0;
    this._cellCount = 0;
    this._direction = direction;
    this._fadeDuration = fadeDuration;
    this._cellSes = cellSes || [];
  };

  Game_Picture.prototype.startAnimationFrame = function (
    animationType,
    loopFlg,
    customArray
  ) {
    this._animationType = animationType;
    this._customArray = customArray;
    this._animationFlg = true;
    this._loopFlg = loopFlg;
    if (this._cellNumber <= this._cellCount) {
      this._cellCount = this._cellNumber - 1;
    }
    this.playCellSe();
  };

  Game_Picture.prototype.stopAnimationFrame = function (forceFlg) {
    this._loopFlg = false;
    if (forceFlg) {
      this._animationFlg = false;
    }
  };

  Game_Picture.prototype.hasAnimationFrame = function () {
    return this._animationFlg;
  };

  Game_Picture.prototype.isFading = function () {
    return this._fadeDurationCount !== 0;
  };

  Game_Picture.prototype.isAnimationPlaying = function () {
    return (
      this.hasAnimationFrame() || this.isFading() || this._lastFrameCount > 0
    );
  };

  Game_Picture.prototype.isNeedFade = function () {
    return this._fadeDuration !== 0;
  };

  Game_Picture.prototype.isActive = function () {
    return $gameScreen.isActivePicture(this);
  };

  //=============================================================================
  // Sprite_Picture
  //  アニメーション関連の情報を追加で保持します。
  //=============================================================================
  var _Sprite_Picture_initialize = Sprite_Picture.prototype.initialize;
  Sprite_Picture.prototype.initialize = function (pictureId) {
    this._prevSprite = null;
    _Sprite_Picture_initialize.apply(this, arguments);
  };

  var _Sprite_Picture_update = Sprite_Picture.prototype.update;
  Sprite_Picture.prototype.update = function () {
    _Sprite_Picture_update.apply(this, arguments);
    var picture = this.picture();
    if (picture && picture.name()) {
      if (picture.isMulti() && !this._bitmaps) {
        this.loadAnimationBitmap();
      }
      if (this.isBitmapReady()) {
        this.updateAnimationFrame(this, picture.cell);
        if (picture.isNeedFade()) this.updateFading();
      }
    }
  };

  var _Sprite_Picture_updateBitmap = Sprite_Picture.prototype.updateBitmap;
  Sprite_Picture.prototype.updateBitmap = function () {
    _Sprite_Picture_updateBitmap.apply(this, arguments);
    if (!this.picture()) {
      this._bitmaps = null;
      if (this._prevSprite) {
        this._prevSprite.bitmap = null;
      }
    }
  };

  Sprite_Picture.prototype.updateFading = function () {
    if (!this._prevSprite) {
      this.makePrevSprite();
    }
    if (!this._prevSprite.bitmap) {
      this.makePrevBitmap();
    }
    var picture = this.picture();
    if (picture.isFading()) {
      this._prevSprite.visible = true;
      this.updateAnimationFrame(this._prevSprite, picture.prevCellCount());
      this._prevSprite.opacity = picture.prevCellOpacity();
    } else {
      this._prevSprite.visible = false;
    }
  };

  Sprite_Picture.prototype.updateAnimationFrame = function (sprite, cellCount) {
    switch (this.picture().direction()) {
      case "連番":
      case "N":
        sprite.bitmap = this._bitmaps[cellCount];
        sprite.setFrame(0, 0, sprite.bitmap.width, sprite.bitmap.height);
        break;
      case "縦":
      case "V":
        var height = sprite.bitmap.height / this.picture().cellNumber();
        var y = cellCount * height;
        sprite.setFrame(0, y, sprite.bitmap.width, height);
        break;
      case "横":
      case "H":
        var width = sprite.bitmap.width / this.picture().cellNumber();
        var x = cellCount * width;
        sprite.setFrame(x, 0, width, sprite.bitmap.height);
        break;
      default:
        sprite.setFrame(0, 0, this.bitmap.width, this.bitmap.height);
    }
  };

  var _Sprite_Picture_loadBitmap = Sprite_Picture.prototype.loadBitmap;
  Sprite_Picture.prototype.loadBitmap = function () {
    _Sprite_Picture_loadBitmap.apply(this, arguments);
    this._bitmapReady = false;
    this._bitmaps = null;
    if (this._prevSprite) {
      this._prevSprite.visible = false;
    }
  };

  Sprite_Picture.prototype.loadAnimationBitmap = function () {
    var cellNumber = this.picture().cellNumber();
    var cellDigit = cellNumber.toString().length;
    this._bitmaps = [this.bitmap];
    for (var i = 1; i < cellNumber; i++) {
      var filename =
        this._pictureName.substr(0, this._pictureName.length - cellDigit) +
        i.padZero(cellDigit);
      this._bitmaps[i] = ImageManager.loadPicture(filename);
    }
    this._bitmapReady = false;
  };

  Sprite_Picture.prototype.makePrevSprite = function () {
    this._prevSprite = new Sprite();
    this._prevSprite.visible = false;
    this.addChild(this._prevSprite);
  };

  Sprite_Picture.prototype.makePrevBitmap = function () {
    this._prevSprite.bitmap = this.bitmap;
    this._prevSprite.anchor.x = this.anchor.x;
    this._prevSprite.anchor.y = this.anchor.y;
  };

  Sprite_Picture.prototype.isBitmapReady = function () {
    if (!this.bitmap) return false;
    if (this._bitmapReady) return true;
    var result;
    if (this.picture().isMulti()) {
      result = this._bitmaps.every(function (bitmap) {
        return bitmap.isReady();
      });
    } else {
      result = this.bitmap.isReady();
    }
    this._bitmapReady = result;
    return result;
  };
})();