code:
/*:
 * @plugindesc マウス操作を拡張します
 * @author ル
 *
 * @help
 * 条件分岐で　ボタン[キャンセル]が押されている　を指定した場合、
 * マウスの右クリックも条件に含めるようにします。
 *
 * 条件分岐で　ボタン[左]が押されている　を指定した場合、
 * 画面左半分でのマウスの左クリックも条件に含めるようにします。
 *
 * 条件分岐で　ボタン[右]が押されている　を指定した場合、
 * 画面右半分でのマウスの左クリックも条件に含めるようにします。
 *
 * 家系図で、マウスホイールでのスクロールができるようにします。
 *
 * セーブ画面で、マウス操作でページを選択できるようにします。
 *
 */
var Nore;
(function (Nore) {
  const parameters = PluginManager.parameters("Nore_Plugins");

  const _Game_Interpreter_prototype_command111 =
    Game_Interpreter.prototype.command111;
  Game_Interpreter.prototype.command111 = function () {
    var result = false;
    //console.log(TouchInput.isCancelled())
    switch (this._params[0]) {
      case 11: // Button
        //console.log(this._params[1])
        if (this._params[1] == "cancel") {
          //console.log(TouchInput._cancelled2)
          //console.log(TouchInput.rightButton)
          if (TouchInput.rightButton) {
            result = true;
            this._branch[this._indent] = result;
            if (this._branch[this._indent] === false) {
              this.skipBranch();
            }
            return true;
          }
        }
        if (this._params[1] == "left") {
          if (TouchInput.leftButtonByLeftSide) {
            result = true;
            this._branch[this._indent] = result;
            if (this._branch[this._indent] === false) {
              this.skipBranch();
            }
            return true;
          }
        }
        if (this._params[1] == "right") {
          if (TouchInput.leftButtonByRightSide) {
            result = true;
            this._branch[this._indent] = result;
            if (this._branch[this._indent] === false) {
              this.skipBranch();
            }
            return true;
          }
        }
    }
    return _Game_Interpreter_prototype_command111.call(this);
  };

  var _TouchInput_clear = TouchInput.clear;
  TouchInput.clear = function () {
    _TouchInput_clear.call(this);
    this.rightButton = false;
    this.leftButtonByRightSide = false;
    this.leftButtonByLeftSide = false;
    this.rightButtonCount = 0;
  };
  TouchInput._onRightButtonDown = function (event) {
    var x = Graphics.pageToCanvasX(event.pageX);
    var y = Graphics.pageToCanvasY(event.pageY);
    if (Graphics.isInsideCanvas(x, y)) {
      this._onCancel(x, y);
      this.rightButton = true;
      this.rightButtonCount = 10;
    }
  };

  TouchInput._onLeftButtonDown = function (event) {
    var x = Graphics.pageToCanvasX(event.pageX);
    var y = Graphics.pageToCanvasY(event.pageY);
    if (Graphics.isInsideCanvas(x, y)) {
      this._mousePressed = true;
      this._pressedTime = 0;
      this._onTrigger(x, y);

      if (Graphics._boxWidth / 2 < x) {
        this.leftButtonByRightSide = true;
      } else {
        this.leftButtonByLeftSide = true;
      }
      this.leftButtonCount = 10;
    }
  };

  var _TouchInput_update = TouchInput.update;
  TouchInput.update = function () {
    _TouchInput_update.call(this);
    if (this.rightButtonCount > 0) {
      this.rightButtonCount--;
      if (this.rightButtonCount <= 0) {
        this.rightButton = false;
      }
    }
    if (this.leftButtonCount > 0) {
      this.leftButtonCount--;
      if (this.leftButtonCount <= 0) {
        this.leftButtonByRightSide = false;
        this.leftButtonByLeftSide = false;
      }
    }
  };

  const Window_FamilyTree_prototype_update =
    Nore.Window_FamilyTree.prototype.update;
  Nore.Window_FamilyTree.prototype.update = function () {
    Window_FamilyTree_prototype_update.call(this);
    if (TouchInput.wheelY < 0) {
      this.y += this.interval() * 2;
      if (this.y > 0) {
        this.y = 0;
      }
    } else if (TouchInput.wheelY > 0) {
      this.y -= this.interval() * 2;
      if (this.y < -this.maxY()) {
        this.y = -this.maxY();
      }
    }
  };

  const _Scene_File_update = Scene_File.prototype.update;
  Scene_File.prototype.update = function () {
    _Scene_File_update.call(this);
    if (!this._pageWindow) {
      return;
    }
    if (!this._pageWindow.isTouchedInsideFrame()) {
      return;
    }
    if (!TouchInput.isTriggered()) {
      return;
    }
    for (var i = 0; i < 16; i++) {
      const rect = this._pageWindow.itemRect(i);
      if (rect.x <= TouchInput.x && rect.x + rect.width >= TouchInput.x) {
        if (this._pageWindow._index == i) {
          break;
        }
        SoundManager.playCursor();
        var before = this._listWindow.index();

        this._pageWindow._index = i;
        this._pageWindow.refresh();
        this._listWindow.setPageIndex(i);

        if (this._listWindow.maxItems() <= before) {
          this._listWindow.select(0);
        }
        break;
      }
    }
  };
})(Nore || (Nore = {}));

/*
(function() {

    function p(arg) {
        console.log(arg);
    }

    (window).p = p;

})();
*/


code:
/*:
 * @plugindesc いろいろ気になったところ
 * @author ル
 *
 * @param choiseLiseWindowMargin
 * @desc 選択肢を表示するウィンドウの右側の隙間を設定します
 * @default 195
 *
 * @param volumeOffset
 * @desc ボリュームを変更したときに変わる値を設定します
 * @default 5
 *
 * @param loadSkinScript
 * @desc BB_WindowSelector3 と MessageWindowPopup の競合対策をする場合1 しない場合0
 * @default 1
 */
var Nore;
(function (Nore) {
  const parameters = PluginManager.parameters("Nore_Plugins");

  let choiseLiseWindowMargin = parseInt(parameters["choiseLiseWindowMargin"]);
  if (choiseLiseWindowMargin > 0) {
    // 選択肢ウィンドウの位置
    const _Window_ChoiceList_prototype_updatePlacement =
      Window_ChoiceList.prototype.updatePlacement;
    Window_ChoiceList.prototype.updatePlacement = function () {
      _Window_ChoiceList_prototype_updatePlacement.call(this);

      var positionType = $gameMessage.choicePositionType();
      console.log(positionType);
      switch (positionType) {
        case 2:
          this.x = Graphics.boxWidth - this.width - choiseLiseWindowMargin;
          return;
      }
    };
  }

  let volumeOffset = parseInt(parameters["volumeOffset"]);
  if (choiseLiseWindowMargin > 0) {
    Window_Options.prototype.volumeOffset = function () {
      return volumeOffset;
    };
  }

  let loadSkinScript = parseInt(parameters["loadSkinScript"]);
  if (loadSkinScript > 0) {
    var _Window_Message_loadWindowskin =
      Window_Message.prototype.loadWindowskin;
    Window_Message.prototype.loadWindowskin = function () {
      let BBWSvar = 11;
      if ($gameVariables.value(BBWSvar) == 3) {
        this.windowskin = ImageManager.loadSystem("Window3");
      } else if ($gameVariables.value(BBWSvar) == 2) {
        this.windowskin = ImageManager.loadSystem("Window2");
      } else {
        this.windowskin = ImageManager.loadSystem("Window");
      }
    };

    // 通常文字色は固定（ウィンドウ画像読み込み前に文字色を設定された時用）
    Window_Base.prototype.normalColor = function () {
      return "#ffffff";
    };
  }
})(Nore || (Nore = {}));

repo_name: Idkwtcm/violated

license: unknown


code:
/*:
 * @plugindesc 回想拡張プラグイン
 * @author ノレ
 *
 * @param 回想スイッチ
 * @desc 回想時に自動的にONになるスイッチ番号
 * @default 1997
 *
 * @help
 * プラグインコマンド
 * EndRecollection
 * →回想シーンに戻ります。
 * Scene_Recollection.prototype.rngd_exit_scene() をスクリプトで書くのと同じ。
 *
 */
(function () {
  const pluginName = "Nore_RecollectionMode";
  const parameters = PluginManager.parameters(pluginName);
  const RECO_SW = parseInt(parameters["回想スイッチ"]);
  const LOAD_SAVE_FILES = 12 * 10; // 12個入りのセーブ画面が１０枚。保管セーブを除いたもの

  let globalVariableCache = null;

  const _DataManager_saveGameWithoutRescue = DataManager.saveGameWithoutRescue;
  DataManager.saveGameWithoutRescue = function (savefileId) {
    // セーブが入るとキャッシュ削除
    globalVariableCache = null;
    return _DataManager_saveGameWithoutRescue.call(this, savefileId);
  };

  Window_RecList.prototype.get_global_variables = function () {
    if (globalVariableCache) {
      this._global_variables = globalVariableCache;
      return;
    }
    this._global_variables = {
      switches: {},
    };
    globalVariableCache = this._global_variables;
    var maxSaveFiles = LOAD_SAVE_FILES;
    let t = new Date().getTime();
    for (var i = 1; i <= maxSaveFiles; i++) {
      if (DataManager.loadGameSwitch(i)) {
        var rec_cg_max = rngd_hash_size(
          rngd_recollection_mode_settings.rec_cg_set
        );

        for (var j = 0; j < rec_cg_max; j++) {
          var cg = rngd_recollection_mode_settings.rec_cg_set[j + 1];
          if ($gameSwitches._data[cg.switch_id]) {
            this._global_variables["switches"][cg.switch_id] = true;
          }
        }
      }
    }
    //console.log('time:' + (new Date().getTime() - t));
  };

  var _nore_recollection_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _nore_recollection_pluginCommand.call(this, command, args);
    if (command === "EndRecollection") {
      Scene_Recollection.reload_rec_list = true;
      SceneManager.push(Scene_Recollection);
    }
  };

  Scene_Recollection.prototype.commandDoRecMode = function () {
    var target_index = this._rec_list.index() + 1;
    Scene_Recollection.rec_list_index = target_index - 1;

    if (this._rec_list.is_valid_picture(this._rec_list.index() + 1)) {
      // 回想モードの場合
      if (this._mode == "recollection") {
        Scene_Recollection._rngd_recollection_doing = true;

        DataManager.setupNewGame();
        $gamePlayer.setTransparent(255);
        this.fadeOutAll();
        // TODO: パーティを透明状態にする

        //$dataSystem.optTransparent = false;
        $gameSwitches.setValue(RECO_SW, true);

        $gameTemp.reserveCommonEvent(
          rngd_recollection_mode_settings.rec_cg_set[target_index][
            "common_event_id"
          ]
        );
        $gamePlayer.reserveTransfer(
          rngd_recollection_mode_settings.sandbox_map_id,
          0,
          0,
          0
        );
        SceneManager.push(Scene_Map);

        // CGモードの場合
      } else if (this._mode == "cg") {
        this._cg_sprites = [];
        this._cg_sprites_index = 0;

        // シーン画像をロードする
        rngd_recollection_mode_settings.rec_cg_set[
          target_index
        ].pictures.forEach(function (name) {
          // CGクリックを可能とする
          var sp = new Sprite_Button();
          sp.setClickHandler(this.commandDummyOk.bind(this));
          sp.processTouch = function () {
            Sprite_Button.prototype.processTouch.call(this);
          };
          sp.bitmap = ImageManager.loadPicture(name);
          // 最初のSprite以外は見えないようにする
          if (this._cg_sprites.length > 0) {
            sp.visible = false;
          }

          // TODO: 画面サイズにあわせて、拡大・縮小すべき
          this._cg_sprites.push(sp);
          this.addChild(sp);
        }, this);

        this.do_exchange_status_window(this._rec_list, this._dummy_window);
        this._dummy_window.visible = false;
      }
    } else {
      this._rec_list.activate();
    }
  };
})();


code:
var __extends =
  (this && this.__extends) ||
  (function () {
    var extendStatics = function (d, b) {
      extendStatics =
        Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array &&
          function (d, b) {
            d.__proto__ = b;
          }) ||
        function (d, b) {
          for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        };
      return extendStatics(d, b);
    };
    return function (d, b) {
      extendStatics(d, b);
      function __() {
        this.constructor = d;
      }
      d.prototype =
        b === null
          ? Object.create(b)
          : ((__.prototype = b.prototype), new __());
    };
  })();
/*:ja
 * @author ル
 * @plugindesc 回想セーブができるスクリプト
 *
 * @help
 * 回想セーブのプラグインコマンド
 * 回想セーブ <回想ファイルID> <テキスト>
 *
 * 例
 * 回想セーブ オーク敗北
 *
 * @param recollectionPage
 * @text このページから回想セーブになります
 * @desc このページから回想セーブになります
 * @type number
 * @default 11
 *
 * @param maxCols
 * @text セーブページの行の数
 * @desc セーブページの行の数
 * @type number
 * @default 4
 *
 * @param alreadySaveExists
 * @text 回想セーブが存在する時のメッセージ
 * @default 既にセーブデータがあるため回想セーブされませんでした
 *
 * @param alreadySaveExistsEn
 * @text 回想セーブが存在する時のメッセージ(英語)
 * @default Not recollection saved because there is already saved data.
 *
 * @param alreadySaveExistsCh
 * @text 回想セーブが存在する時のメッセージ(中国語)
 * @default 既にセーブデータがあるため回想セーブされませんでした
 *
 * @param fullSaveFiles
 * @text 回想セーブがまんたんでセーブができない時のメッセージ
 * @default これ以上回想セーブを登録することができません
 *
 * @param fullSaveFilesEn
 * @text 回想セーブがまんたん時(英語)
 * @default The maximum number of recollection saves has been reached
 *
 * @param fullSaveFilesCh
 * @text 回想セーブがまんたん時(中国語)
 * @default これ以上回想セーブを登録することができません
 *
 * @param recosaveJp
 * @text 回想セーブの日本語名
 * @default 回想%1
 *
 * @param recosaveEn
 * @text 回想セーブの英語名
 * @default reco%1
 *
 * @param recosaveCh
 * @text 回想セーブの中国語名
 * @default 回想%1
 *
 *
 * @param loadJp
 * @text ロードするの日本語名
 * @default ロードする
 *
 * @param loadEn
 * @text ロードするの英語名
 * @default load
 *
 * @param loadCh
 * @text ロードするの中国語名
 * @default ロードする
 *
 *
 * @param confirmloadJp
 * @text ロードしますかの日本語名
 * @default このファイルをロードしますか？
 *
 * @param confirmloadEn
 * @text ロードするの英語名
 * @default Do you want to load this file?
 *
 * @param confirmloadCh
 * @text ロードするの中国語名
 * @default このファイルをロードしますか？
 *
 *
 * @param deleteJp
 * @text 削除するの日本語名
 * @default 削除する
 *
 * @param deleteEn
 * @text 削除するの英語名
 * @default delete
 *
 * @param deleteCh
 * @text 削除するの中国語名
 * @default 削除する
 *
 * @param copiedJp
 * @text コピーされたファイルの日本語名
 * @default コピーされたファイル
 *
 * @param copiedEn
 * @text コピーされたファイルの英語名
 * @default Copied file
 *
 * @param copiedCh
 * @text コピーされたファイルの中国語名
 * @default Copied file
 */
var Nore;
(function (Nore) {
  var parameters = PluginManager.parameters("Nore_RecollectionSave");
  var RECOLLECTION_PAGE = parameters["recollectionPage"];
  var maxCols = parseInt(parameters["maxCols"] || "4");
  var MAX_PAGE_FILES = maxCols * 3;
  var AUTO_SAVE_ID = 0;
  var maxPage = 16;
  var MAX_ROW = 3;
  var ALREADY_SAVE_EXISTS = parameters["alreadySaveExists"];
  var ALREADY_SAVE_EXISTS_EN = parameters["alreadySaveExistsEn"];
  var ALREADY_SAVE_EXISTS_CH = parameters["alreadySaveExistsCh"];
  var FULL_SAVE_FILES = parameters["fullSaveFiles"];
  var FULL_SAVE_FILES_EN = parameters["fullSaveFilesEn"];
  var FULL_SAVE_FILES_CH = parameters["fullSaveFilesCh"];
  var RECO_LABEL_JP = parameters["recosaveJp"];
  var RECO_LABEL_EN = parameters["recosaveEn"];
  var RECO_LABEL_CH = parameters["recosaveCh"];
  var LOAD_LABEL_JP = parameters["loadJp"];
  var LOAD_LABEL_EN = parameters["loadEn"];
  var LOAD_LABEL_CH = parameters["loadCh"];
  var LOAD_CONFIRM_JP = parameters["confirmloadJp"];
  var LOAD_CONFIRM_EN = parameters["confirmloadEn"];
  var LOAD_CONFIRM_CH = parameters["confirmloadCh"];
  var DELETE_LABEL_JP = parameters["deleteJp"];
  var DELETE_LABEL_EN = parameters["deleteEn"];
  var DELETE_LABEL_CH = parameters["deleteCh"];

  var COPIED_LABEL_JP = parameters["copiedJp"];
  var COPIED_LABEL_EN = parameters["copiedEn"];
  var COPIED_LABEL_CH = parameters["copiedCh"];

  var pluginName = "Nore_RecollectionSave";
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.apply(this, arguments);
    if (command === "回想セーブ") {
      $recoSaveManager.save(args[0]);
    }
  };
  DataManager.latestSavefileId = function () {
    var globalInfo = this.loadGlobalInfo();
    var savefileId = 1;
    var timestamp = 0;
    var recoId = getRecoStartId();
    if (globalInfo) {
      for (var i = 1; i < this.maxSavefiles(); i++) {
        if (i >= recoId) {
          break;
        }
        if (this.isThisGameFile(i) && globalInfo[i].timestamp > timestamp) {
          timestamp = globalInfo[i].timestamp;
          savefileId = i;
        }
      }
    }
    return savefileId;
  };
  var _Window_SavefileList_prototype_drawFileId =
    Window_SavefileList.prototype.drawFileId;
  Window_SavefileList.prototype.drawFileId = function (id, x, y) {
    var recoId = getRecoStartId();
    if (id >= recoId) {
      var text = RECO_LABEL_JP;
      switch ($gameVariables.value(1999)) {
        case 2:
          text = RECO_LABEL_EN;
          break;
        case 3:
          text = RECO_LABEL_CH;
          break;
      }
      this.drawText(text.format(id - recoId + 1), x, y, 180);
      return;
    }
    _Window_SavefileList_prototype_drawFileId.call(this, id, x, y);
  };
  function getRecoStartId() {
    var recoId = (RECOLLECTION_PAGE - 1) * MAX_PAGE_FILES;
    return recoId;
  }
  var $recoSaveManager;
  var _DataManager_createGameObjects = DataManager.createGameObjects;
  DataManager.createGameObjects = function () {
    _DataManager_createGameObjects.call(this);
    $recoSaveManager = new RecoSaveManager();
  };
  var RecoSaveManager = /** @class */ (function () {
    function RecoSaveManager() {
      this._recoSaveName = null;
    }
    RecoSaveManager.prototype.save = function (saveFileName) {
      var slotId = this.findSlotId(saveFileName);
      if (slotId == -1) {
        CommonPopupManager.showInfo({}, this.getAlreadySaveExistMsg(), "");
        return;
      }
      if (slotId == -2) {
        CommonPopupManager.showInfo({}, this.getFullSaveFilesMsg(), "");
        return;
      }
      var lastAccessId = DataManager._lastAccessedId;
      var saveId = getRecoStartId() + slotId - 1;
      var info = DataManager.loadGlobalInfo()[saveId];
      if (info && info.playtime == $gameSystem.playtimeText()) {
        return;
      }
      if (saveId > DataManager.maxSavefiles()) {
        CommonPopupManager.showInfo({}, this.getFullSaveFilesMsg(), "");
        return;
      }
      SceneManager.snapForThumbnail();
      $gameSystem.onBeforeSave();
      this._recoSaveName = saveFileName;
      console.log(
        "回想セーブを実行 " + slotId + " " + saveId + " " + saveFileName
      );
      if (DataManager.saveGame(saveId)) {
        StorageManager.cleanBackup(saveId);
      }
      DataManager._lastAccessedId = lastAccessId;
      this._recoSaveName = null;
    };
    RecoSaveManager.prototype.getAlreadySaveExistMsg = function () {
      switch ($gameVariables.value(1999)) {
        case 2:
          return ALREADY_SAVE_EXISTS_EN;
        case 3:
          return ALREADY_SAVE_EXISTS_CH;
        default:
          return ALREADY_SAVE_EXISTS;
      }
    };
    RecoSaveManager.prototype.getFullSaveFilesMsg = function () {
      switch ($gameVariables.value(1999)) {
        case 2:
          return FULL_SAVE_FILES_EN;
        case 3:
          return FULL_SAVE_FILES_CH;
        default:
          return FULL_SAVE_FILES;
      }
    };
    RecoSaveManager.prototype.findSlotId = function (saveFileName) {
      var start = getRecoStartId();
      var globalInfo = DataManager.loadGlobalInfo();
      let maxSaveFiles = DataManager.maxSavefiles();
      for (var i = 0; i < maxSaveFiles; i++) {
        let fileId = i + start;
        if (fileId >= maxSaveFiles) {
          break;
        }
        var info = globalInfo[fileId];
        if (info) {
          if (info.label == saveFileName) {
            return -1;
          }
        }
      }
      for (var i = 0; i < maxSaveFiles; i++) {
        let fileId = i + start;
        if (fileId >= maxSaveFiles) {
          return -2;
        }

        var info = globalInfo[i + start];
        if (!info) {
          return i + 1;
        }
      }
      return -1;
    };
    RecoSaveManager.prototype.inRecoSave = function () {
      return this._recoSaveName != null;
    };
    RecoSaveManager.prototype.recoSaveName = function () {
      return this._recoSaveName;
    };
    return RecoSaveManager;
  })();
  var _DataManager_makeSavefileInfo = DataManager.makeSavefileInfo;
  DataManager.makeSavefileInfo = function () {
    var info = _DataManager_makeSavefileInfo.call(this);
    if (!$recoSaveManager.inRecoSave()) {
      return info;
    }
    info.label = $recoSaveManager.recoSaveName();
    return info;
  };
  var _Scene_Save_prototype_onSavefileOk = Scene_Save.prototype.onSavefileOk;
  Scene_Save.prototype.onSavefileOk = function () {
    var fileId = this.savefileId();
    if (fileId == undefined || fileId >= getRecoStartId()) {
      this.onSaveFailure();
      return;
    }
    _Scene_Save_prototype_onSavefileOk.call(this);
  };
  Scene_File.prototype.createListWindow = function () {
    var x = 0;
    var y = this._helpWindow.height;
    var width = Graphics.boxWidth;
    var height = Graphics.boxHeight - y;
    this._listWindow = new Window_SavefileList2(x, y, width, height - 60);
    this._listWindow.setHandler("ok", this.onSavefileOk.bind(this));
    this._listWindow.setHandler("cancel", this.popScene.bind(this));
    this._listWindow.setHandler("pageup", this.onPageup.bind(this));
    this._listWindow.setHandler("pagedown", this.onPagedown.bind(this));
    this._listWindow.setHandler("right", this.onRight.bind(this));
    this._listWindow.setHandler("left", this.onLeft.bind(this));
    this._listWindow.setHandler("up", this.onUp.bind(this));
    this._listWindow.setHandler("down", this.onDown.bind(this));
    this._listWindow.setHandler("right", this.onRight.bind(this));
    var index = this.firstSavefileIndex() + 1;
    var page = Math.floor(index / MAX_PAGE_FILES);
    this._listWindow.setPageIndex(page);
    this._listWindow.select(index % MAX_PAGE_FILES);
    this._listWindow.setMode(this.mode());
    this._listWindow.refresh();
    this.addWindow(this._listWindow);
    var yy = this._listWindow.y + this._listWindow.height;
    this._pageWindow = new Window_SavePage(0, yy + 0, width, 60);
    this._pageWindow.setPage(page);
    this.addWindow(this._pageWindow);
  };
  const _Scene_File_prototype_popScene = Scene_File.prototype.popScene;
  Scene_File.prototype.popScene = function () {
    $gameVariables.setValue(11, 0);
    _Scene_File_prototype_popScene.call(this);
  };
  Scene_File.prototype.onRight = function () {
    var page = this._pageWindow.right();
    this._listWindow.setPageIndex(page);
    this._listWindow.select(0);
  };
  Scene_File.prototype.onLeft = function () {
    var page = this._pageWindow.left();
    this._listWindow.setPageIndex(page);
    this._listWindow.select(this._listWindow.maxItems() - 1);
  };
  Scene_File.prototype.onDown = function () {
    var page = this._pageWindow.right();
    var before = this._listWindow.index();
    this._listWindow.setPageIndex(page);
    this._listWindow.select(before % maxCols);
  };
  Scene_File.prototype.onUp = function () {
    var page = this._pageWindow.left();
    var before = this._listWindow.index();
    this._listWindow.setPageIndex(page);
    this._listWindow.select(
      (before % maxCols) + this._listWindow.maxItems() - maxCols
    );
  };
  Scene_File.prototype.onPageup = function () {
    var page = this._pageWindow.left();
    var before = this._listWindow.index();
    this._listWindow.setPageIndex(page);
    if (this._listWindow.maxItems() <= before) {
      this._listWindow.select(0);
    }
  };
  Scene_File.prototype.onPagedown = function () {
    var page = this._pageWindow.right();
    var before = this._listWindow.index();
    this._listWindow.setPageIndex(page);
    if (this._listWindow.maxItems() <= before) {
      this._listWindow.select(0);
    }
  };
  var _Scene_Load_prototype_onSavefileOk = Scene_Load.prototype.onSavefileOk;
  Scene_Load.prototype.onSavefileOk = function () {
    var saveFileId = this.savefileId();
    if (
      saveFileId < getRecoStartId() ||
      saveFileId == Nore.AUTO_SAVE_DUMMY_ID
    ) {
      _Scene_Load_prototype_onSavefileOk.call(this);
      return;
    }
    if (!DataManager.isThisGameFile(saveFileId)) {
      _Scene_Load_prototype_onSavefileOk.call(this);
      return;
    }
    SoundManager.playOk();
    var confiemWindow;
    if (this._confiemWindow) {
      confiemWindow = this._confiemWindow;
    } else {
      confiemWindow = new Window_Confirm();
      confiemWindow.setHandler("ok", this.onConfirmOk.bind(this));
      confiemWindow.setHandler("delete", this.onConfirmDelete.bind(this));
      confiemWindow.setHandler("cancel", this.onConfirmCancel.bind(this));
      this._confiemWindow = confiemWindow;
    }
    var text = LOAD_CONFIRM_JP;
    switch ($gameVariables.value(1999)) {
      case 2:
        text = LOAD_CONFIRM_EN;
        break;
      case 3:
        text = LOAD_CONFIRM_CH;
        break;
    }
    confiemWindow.setText(text);
    confiemWindow.show();
    confiemWindow.activate();
    confiemWindow.select(0);
    this.addWindow(confiemWindow);
    //_Scene_Load_prototype_onSavefileOk.call(this);
  };
  Scene_Load.prototype.onConfirmOk = function () {
    _Scene_Load_prototype_onSavefileOk.call(this);
  };
  Scene_Load.prototype.onConfirmDelete = function () {
    var saveFileId = this.savefileId();
    StorageManager.remove(saveFileId);
    var info = DataManager.loadGlobalInfo();
    delete info[saveFileId];
    this._confiemWindow.deactivate();
    this._confiemWindow.hide();
    this._listWindow.refresh();
    this._listWindow.activate();
  };
  Scene_Load.prototype.onConfirmCancel = function () {
    this._confiemWindow.deactivate();
    this._confiemWindow.hide();
    this._listWindow.activate();
  };
  var Window_SavefileList2 = /** @class */ (function (_super) {
    __extends(Window_SavefileList2, _super);
    function Window_SavefileList2() {
      return (_super !== null && _super.apply(this, arguments)) || this;
    }
    Window_SavefileList2.prototype.maxItems = function () {
      return MAX_PAGE_FILES;
    };
    Window_SavefileList2.prototype.update = function () {
      if (!$gameVariables) {
        return;
      }
      if (this._page >= RECOLLECTION_PAGE - 1) {
        $gameVariables.setValue(11, 2);
        //this.windowskin = ImageManager.loadSystem(recoPageWindowFile);
      } else {
        $gameVariables.setValue(11, 0);
        //this.windowskin = ImageManager.loadSystem('Window');
      }
      _super.prototype.update.call(this);
    };
    Window_SavefileList2.prototype.drawItem = function (index) {
      var id = index + this.pageTopIndex();
      //console.log(id)
      var valid = DataManager.isThisGameFile(id);
      if (!valid && this._page == -1) {
        return;
      }
      var info = DataManager.loadSavefileInfo(id);
      var rect = this.itemRectForText(index);
      this.resetTextColor();

      if (!valid && !info && id > 0) {
        if (StorageManager.exists(id)) {
          try {
            const jsonStr = StorageManager.load(id);
            const json = JsonEx.parse(jsonStr);

            info = this.makeDummySaveFile();
            valid = true;
          } catch (e) {
            console.error(e);
          }
        }
      }
      this.changePaintOpacity(valid);
      this.drawFileId(id, rect.x + 33, rect.y);
      if (valid && info && info.label != null && info.label != 0) {
        this.drawText(info.label, rect.x + 33, rect.y + 30, rect.width - 33);
      }
      if (info) {
        this.changePaintOpacity(valid);
        this.drawContents(info, rect, valid);
        this.changePaintOpacity(true);
      }
    };
    Window_SavefileList2.prototype.makeDummySaveFile = function () {
      var info = {};
      info.globalId = this._globalId;
      info.title = $dataSystem.gameTitle;
      info.characters = [];
      info.faces = [];
      info.timestamp = Date.now();

      var text = COPIED_LABEL_JP;
      switch ($gameVariables.value(1999)) {
        case 2:
          text = COPIED_LABEL_EN;
          break;
        case 3:
          text = COPIED_LABEL_CH;
          break;
      }
      info.playtime = text;

      return info;
    };
    Window_SavefileList2.prototype.pageTopIndex = function () {
      return this._page * this.maxItems();
    };
    Window_SavefileList2.prototype.drawThumbnail = function (
      info,
      thumbRect,
      valid
    ) {
      var _this = this;
      var savefileId = DataManager.getSavefileId(info);
      if (savefileId < 0 && info.title != null) {
        savefileId = AUTO_SAVE_ID;
      }
      var listIndex = savefileId - this.pageTopIndex();
      if (savefileId >= 0 && info.thumbnail) {
        var sprite_1 = this._thumbContainer.children[listIndex];
        if (!sprite_1) {
          console.error(savefileId + "のサムネイルを表示できません");
          return;
        }
        sprite_1.visible = true;
        sprite_1.x = thumbRect.x;
        sprite_1.y = thumbRect.y + 65;
        var thunmbBitmap_1 = ImageManager.loadThumbnail(savefileId, info);
        if (!thunmbBitmap_1.isReady()) {
          // 読み込み終わるまで別のビットマップを表示
          var empty = ImageManager.loadBusyThumbBitmap(
            thumbRect.width,
            thumbRect.height
          );
          sprite_1.bitmap = empty;
        }
        thunmbBitmap_1.addLoadListener(function () {
          // 読み込み終わったときにリスト表示範囲内であれば描画
          if (
            _this.topIndex() <= listIndex &&
            _this.bottomIndex() >= listIndex
          ) {
            sprite_1.visible = true;
            sprite_1.bitmap = thunmbBitmap_1;
            sprite_1.bitmap.paintOpacity = valid
              ? 255
              : _this.translucentOpacity();
          } else {
            sprite_1.visible = false;
          }
        });
      }
    };
    Window_SavefileList2.prototype.drawPlaytime = function (info, x, y, width) {
      if (info.playtime) {
        this.contents.fontSize = 22;
        this.drawText(info.playtime, x, y, width, "right");
      }
    };
    Window_SavefileList2.prototype.selectedId = function () {
      return this.index() + this.pageTopIndex();
    };
    Window_SavefileList2.prototype.maxCols = function () {
      return maxCols;
    };
    Window_SavefileList2.prototype.itemHeight = function () {
      return this._height / MAX_ROW - this.spacing();
    };
    Window_SavefileList2.prototype.setPageIndex = function (page) {
      this._page = page;
      this.refresh();
      this.activate();
    };
    Window_SavefileList2.prototype.cursorUp = function (wrap) {
      var index = this.index();
      if (index - this.maxCols() < 0) {
        this.callHandler("up");
        return;
      }
      _super.prototype.cursorUp.call(this, wrap);
    };
    Window_SavefileList2.prototype.cursorDown = function (wrap) {
      var index = this.index();
      var maxItems = this.maxItems();
      if (index + this.maxCols() >= maxItems) {
        this.callHandler("down");
        return;
      }
      _super.prototype.cursorDown.call(this, wrap);
    };
    Window_SavefileList2.prototype.cursorRight = function (wrap) {
      var index = this.index();
      var maxItems = this.maxItems();
      if (index + 1 >= maxItems) {
        this.callHandler("right");
        return;
      }
      _super.prototype.cursorRight.call(this, wrap);
    };
    Window_SavefileList2.prototype.cursorLeft = function (wrap) {
      var index = this.index();
      if (index == 0) {
        this.callHandler("left");
        return;
      }
      _super.prototype.cursorLeft.call(this, wrap);
    };
    Window_SavefileList2.prototype.scrollDown = function (wrap) {
      SoundManager.playCursor();
      this.callHandler("pagedown");
    };
    Window_SavefileList2.prototype.scrollUp = function (wrap) {
      SoundManager.playCursor();
      this.callHandler("pageup");
    };
    return Window_SavefileList2;
  })(Window_SavefileList);
  var Window_SavePage = /** @class */ (function (_super) {
    __extends(Window_SavePage, _super);
    function Window_SavePage() {
      return (_super !== null && _super.apply(this, arguments)) || this;
    }
    Window_SavePage.prototype.refresh = function () {
      this.margin = 0;
      this.makeItems();
      _super.prototype.refresh.call(this);
    };
    Window_SavePage.prototype.makeItems = function () {
      this._data = [];
      for (var i = 0; i < maxPage; i++) {
        this._data.push(i);
      }
    };
    Window_SavePage.prototype.maxCols = function () {
      return 99;
    };
    Window_SavePage.prototype.maxItems = function () {
      if (!this._data) {
        return 0;
      }
      return this._data.length;
    };
    Window_SavePage.prototype.itemRect = function (index) {
      var rect = new Rectangle();
      var maxCols = this.maxCols();
      rect.width = this.itemWidth();
      rect.height = this.itemHeight();
      rect.x =
        (index % maxCols) * (rect.width + this.spacing()) - this._scrollX + 40;
      rect.y = Math.floor(index / maxCols) * rect.height - this._scrollY;
      return rect;
    };
    Window_SavePage.prototype.drawItem = function (index) {
      this.contents.fontSize = 24;
      var rect = this.itemRect(index);
      var data = this._data[index];
      this.resetTextColor();
      this.changePaintOpacity(index == this._index);
      if (data >= RECOLLECTION_PAGE - 1) {
        var text = RECO_LABEL_JP;
        switch ($gameVariables.value(1999)) {
          case 2:
            text = RECO_LABEL_EN;
            break;
          case 3:
            text = RECO_LABEL_CH;
            break;
        }
        this.drawText(
          text.format(data + 2 - RECOLLECTION_PAGE),
          rect.x,
          -5,
          40,
          30,
          "center"
        );
      } else {
        this.drawText(data + 1, rect.x, -5, 30, 30, "center");
      }
    };
    Window_SavePage.prototype.itemWidth = function () {
      return 48;
    };
    Window_SavePage.prototype.setPage = function (page) {
      this._index = page;
      this.refresh();
    };
    Window_SavePage.prototype.left = function () {
      this._index--;
      if (this._index < 0) {
        this._index = this._data.length - 1;
      }
      this.refresh();
      return this.page();
    };
    Window_SavePage.prototype.right = function () {
      this._index++;
      if (this._index == this._data.length) {
        this._index = 0;
      }
      this.refresh();
      return this.page();
    };
    Window_SavePage.prototype.page = function () {
      return this._data[this._index];
    };
    return Window_SavePage;
  })(Window_Selectable);
  var Window_Confirm = /** @class */ (function (_super) {
    __extends(Window_Confirm, _super);
    function Window_Confirm() {
      var _this_1 = this;
      var w = 680;
      var h = 150;
      var y = (Graphics.boxHeight - h) / 2;
      _this_1 = _super.call(this, (Graphics.boxWidth - w) / 2, y, w, h) || this;
      _this_1.update();
      return _this_1;
    }
    Window_Confirm.prototype.setInfo = function (ok) {
      this._ok = ok;
      this.refresh();
    };
    Window_Confirm.prototype.setText = function (text) {
      this._text = text;
      this._texts = null;
      this.height = 140;
      this.refresh();
    };
    Window_Confirm.prototype.setTexts = function (texts) {
      this._texts = texts;
      this.height = 180;
      this.refresh();
    };
    Window_Confirm.prototype.makeCommandList = function () {
      var loadText = LOAD_LABEL_JP;
      switch ($gameVariables.value(1999)) {
        case 2:
          loadText = LOAD_LABEL_EN;
          break;
        case 3:
          loadText = LOAD_LABEL_CH;
          break;
      }
      var deleteText = DELETE_LABEL_JP;
      switch ($gameVariables.value(1999)) {
        case 2:
          deleteText = DELETE_LABEL_EN;
          break;
        case 3:
          deleteText = DELETE_LABEL_CH;
          break;
      }
      this.addCommand(loadText, "ok", this._ok);
      this.addCommand(deleteText, "delete", true);
      this.addCommand(TextManager.cancel, "cancel", true);
    };
    Window_Confirm.prototype.windowWidth = function () {
      return 620;
    };
    Window_Confirm.prototype.windowHeight = function () {
      return 140;
    };
    Window_Confirm.prototype.maxCols = function () {
      return 3;
    };
    Window_Confirm.prototype.refresh = function () {
      _super.prototype.refresh.call(this);
      if (this._texts) {
        var yy = 4;
        for (var _i = 0, _a = this._texts; _i < _a.length; _i++) {
          var t = _a[_i];
          this.drawText(t, 10, yy, this.windowWidth() - 60, "center");
          yy += 35;
        }
      } else {
        this.drawText(this._text, 10, 4, this.windowWidth() - 60, "center");
      }
    };
    Window_Confirm.prototype.itemRect = function (index) {
      var rect = new Rectangle(0, 0, 0, 0);
      var maxCols = this.maxCols();
      rect.width = this.itemWidth();
      rect.height = this.itemHeight();
      rect.x =
        (index % maxCols) * (rect.width + this.spacing()) - this._scrollX;
      rect.y = Math.floor(index / maxCols) * rect.height - this._scrollY + 64;
      if (this._texts) {
        rect.y += 40;
      }
      return rect;
    };
    Window_Confirm.prototype.spacing = function () {
      return 8;
    };
    return Window_Confirm;
  })(Window_HorzCommand);
  Nore.Window_Confirm = Window_Confirm;
  var _DataManager_loadGameWithoutRescue = DataManager.loadGameWithoutRescue;
  DataManager.loadGameWithoutRescue = function (savefileId) {
    var lastAccessId = this._lastAccessedId;

    let result;
    if (this.isThisGameFile2(savefileId)) {
      var json = StorageManager.load(savefileId);
      this.createGameObjects();
      this.extractSaveContents(JsonEx.parse(json));
      this._lastAccessedId = savefileId;
      result = true;
    } else {
      result = false;
    }

    $gameTemp.interceptorType = 2;

    if (this._lastAccessedId >= getRecoStartId()) {
      this._lastAccessedId = lastAccessId;
    }
    if (this._lastAccessedId == Nore.AUTO_SAVE_DUMMY_ID) {
      this._lastAccessedId = lastAccessId;
    }
    return result;
  };

  var _Nore_DataManager_isThisGameFile = DataManager.isThisGameFile;
  DataManager.isThisGameFile2 = function (savefileId) {
    const result = _Nore_DataManager_isThisGameFile.apply(this, arguments);
    if (!result) {
      if (StorageManager.exists(savefileId)) {
        return true;
      }
      return false;
    }

    return true;
  };
})(Nore || (Nore = {}));
/*
(function () {
    function p(arg) {
        console.log(arg);
    }
    window.p = p;
})();
*/


code:
//=============================================================================
// PANDA_KeywordColor.js
//=============================================================================
// [Update History]
// 2020-08-30 Ver.1.0.0 First Release for MV/MZ.
// 2020-09-06 Ver.1.0.1 Added the Korean Description.

/*:
 * @target MV MZ
 * @plugindesc simplify changing the color of keywords in messages.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200830005445.html
 *
 * @help In messages, replace the following descriptions as follows.
 * You can change the text color of keywords etc. with a simple description.
 *  <Xsome text> → \C[n]some text\C[0]
 * "X" is one alphabet character that means the kind of word.
 * You can specify the color according to the kind of word,
 * such as blue for the person name and red for the item name etc.
 *
 * The word kinds and colors can be defined by parameters,
 * and the default is as follows:
 *  N:4 (person Name : blue)
 *  E:4 (Enemy name : blue)
 *  P:6 (Place name : yellow)
 *  I:2 (Item name : red)
 *  S:2 (Skill name : red)
 *  K:27 (other Keyword : pink)
 *
 * [License]
 * this plugin is released under MIT license.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param KeyList
 * @text Word Kind List
 * @desc The list of an alphabet character that means a kind of the word, "N" as the person name, "I" as the item name etc.
 * @type string[]
 * @default ["N","E","P","I","S","K"]
 *
 * @param ColorList
 * @text Color Number List
 * @desc The list of a color number for a kind of the word. The Color Number List should correspond to the Word Kind List.
 * @type number[]
 * @default ["4","4","6","2","2","27"]
 * @max 31
 * @min 0
 */

/*:ja
 * @target MV MZ
 * @plugindesc 文章中で重要語句の文字色変更を簡略化できます。
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200830005445.html
 *
 * @help 文章の表示や説明文等において、以下の記述を次のように置き換えます。
 * 簡単な記述で、重要語句等の文字色を変更することができます。
 *  <X文章> → \C[n]文章\C[0]
 * "X"の部分には語句の種類を表すアルファベット1文字が入ります。
 * 人名は青、アイテム名は赤など、語句の種類に応じて色の指定が可能です。
 *
 * 語句の種類と色はパラメータで定義が可能で、デフォルトは以下となっています。
 *  N:4（人名：青）
 *  E:4（敵キャラ名：青）
 *  P:6（地名：黄）
 *  I:2（アイテム名：赤）
 *  S:2（スキル名：赤）
 *  K:27（その他の重要語句：ピンク）
 *
 * ■ 利用規約
 * このプラグインはMITライセンスで配布されます。
 * ご自由にお使いください。
 * https://opensource.org/licenses/mit-license.php
 *
 * @param KeyList
 * @text 語句種リスト
 * @desc 人名に"N"、アイテム名に"I"など、語句の種類を表す英字1文字のリスト。
 * @type string[]
 * @default ["N","E","P","I","S","K"]
 *
 * @param ColorList
 * @text 色番号リスト
 * @desc 語句種リストに対応する色番号のリスト。語句種リストと対応させる必要があります。
 * @type number[]
 * @default ["4","4","6","2","2","27"]
 * @max 31
 * @min 0
 */

/*:ko
 * @target MV MZ
 * @plugindesc 텍스트중에서 중요 단어의 글자 색 변경이 간단해집니다.
 * @author panda(werepanda.jp)
 * @url http://www.werepanda.jp/blog/20200830005445.html
 *
 * @help 텍스트 표시나 설명등에서 이하의 기술을 다음과 같이 바꿉니다.
 * 쉬운 기술로 중요 단어의 글자 색깔을 변경할 수 있습니다.
 *  <X텍스트> → \C[n]텍스트\C[0]
 * "X" 부분에는 단어의 종류를 나타내는 알파벳 1글자가 들어갑니다.
 * 인명은 파란색, 아이템명은 빨간색등, 단어의 종류에 따라 색깔 지정이 가능합니다.
 *
 * 단어의 종류와 색깔은 매개변수애서 정의가 되며 기본값은 다음과 같습니다.
 *  N:4 (인명 : 파랑)
 *  E:4 (적 캐릭터명 : 파랑)
 *  P:6 (지명 : 노랑)
 *  I:2 (아이템명 : 빨강)
 *  S:2 (스킬명 : 빨강)
 *  K:27 (기타 중요단어 : 핑크)
 *
 * [이용 약관]
 * 이 플러그인은 MIT 라이센스로 공개됩니다.
 * https://opensource.org/licenses/mit-license.php
 *
 * @param KeyList
 * @text 종류 리스트
 * @desc 인명에 "N", 아이템명에 "I"등, 단어의 종류를 나타내는 알파벳 1글자 리스트.
 * @type string[]
 * @default ["N","E","P","I","S","K"]
 *
 * @param ColorList
 * @text 색 번호 리스트
 * @desc 종류 리스트에 대응되는 색 번호 리스트. 종류 리스트와 대응시켜야 합니다.
 * @type number[]
 * @default ["4","4","6","2","2","27"]
 * @max 31
 * @min 0
 */

(() => {
  "use strict";

  // This Plugin Name
  const pluginName = "PANDA_KeywordColor";

  // Parameters
  const parameters = PluginManager.parameters(pluginName);
  const KeyList = JSON.parse(parameters["KeyList"]) || [];
  const ColorList = JSON.parse(parameters["ColorList"]) || [];

  // Key String for RegExp and [Key => Color] Map
  let keyString = "";
  let keyMap = new Map();
  for (let i in KeyList) {
    let k = KeyList[i];
    if (k) {
      k = k.charAt(0).toUpperCase();
      let c = parseInt(ColorList[i]) || 0;
      keyString += k;
      keyMap.set(k, c);
    }
  }

  // RegExp Object
  const keyRegExp = new RegExp("<([" + keyString + "])(.+?)>", "ig");

  //--------------------------------------------------
  // Window_Base.convertEscapeCharacters
  //  [Additional Definition]
  //--------------------------------------------------
  const _Window_Base_convertEscapeCharacters =
    Window_Base.prototype.convertEscapeCharacters;
  Window_Base.prototype.convertEscapeCharacters = function (text) {
    // Convert Keyword String to Color
    text = text.replace(
      keyRegExp,
      function () {
        let k = arguments[1].toUpperCase();
        let c = keyMap.get(k) || 0;
        return "\\C[" + c + "]" + arguments[2] + "\\C[0]";
      }.bind(this)
    );

    // Original Processing
    text = _Window_Base_convertEscapeCharacters.call(this, text);

    return text;
  };
})();


code:
//=============================================================================
// PictureAnimation.js
// ----------------------------------------------------------------------------
// (C) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 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は演奏されず、ピクチャのアニメーション開始後に指定のタイミングで
 *  　演奏されるようになります。
 *  　必ずピクチャのアニメーション開始前に実行してください。
 *
 * スクリプト詳細
 *
 * アニメーション中のピクチャに対して現在のセル番号を取得します。
 * イベントコマンド「変数の操作」や「条件分岐」で使用できます。
 * ピクチャを表示していないときに実行するとエラーになります。
 * $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;
    }
  };

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

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

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

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