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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


code:
// Generated by RPG Maker.
// Do not edit this file directly.
var $plugins = [
  {
    name: "PluginCommonBase",
    status: true,
    description: "パラメータ解析を提供する共通基盤です",
    parameters: {},
  },
  { name: "Vocab", status: true, description: "", parameters: {} },
  { name: "Vocab_en", status: true, description: "", parameters: {} },
  { name: "Nore_EroParams", status: true, description: "", parameters: {} },
  { name: "Nore_ManParams", status: true, description: "", parameters: {} },
  { name: "Nore_Env", status: true, description: "", parameters: {} },
  { name: "Nore_Troop", status: true, description: "", parameters: {} },
  {
    name: "Nore_DecisiveBattle",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_Facility", status: true, description: "", parameters: {} },
  { name: "Nore_Slg", status: true, description: "", parameters: {} },
  { name: "Nore_Av", status: true, description: "", parameters: {} },
  { name: "Nore_Lib", status: true, description: "", parameters: {} },
  { name: "Nore_Cos", status: true, description: "", parameters: {} },
  { name: "Nore_EroActor", status: true, description: "", parameters: {} },
  {
    name: "Nore_Tachie",
    status: true,
    description: "立ち絵を簡単に表示するプラグインです。別途画像が必要です",
    parameters: {
      disablesTachieActorIdList: "0",
      leftPosX: "-50",
      rightPosX: "800",
      centerPosX: "375",
      posY: "-100",
      actor1offset: "0, 40",
      actor2offset: "40, 150",
      actor3offset: "40, 40",
      actor4offset: "-20, 100",
      actor5offset: "0, 20",
      actor6offset: "0, 50",
      actor7offset: "0, 0",
      actor8offset: "-20, 120",
      actor9offset: "28, 90",
      actor10offset: "50, 150",
      actor11offset: "20, 150",
      actor12offset: "0, 0",
      actor13offset: "-10, 60",
      actor14offset: "0, 0",
      actor15offset: "20, 200",
      actor16offset: "0, 0",
      actor17offset: "-20, 60",
      actor18offset: "-10, 0",
      actor19offset: "0, 0",
      actor20offset: "0, 0",
      actor21offset: "0, 0",
      actor22offset: "40, 5",
      actor23offset: "0, 0",
      actor24offset: "0, 0",
      skipKey: "control",
      windowHideKey: "shift",
      inactiveActorTone: "-120, -120, -120, 0",
      toneChangeDuration: "25",
      windowMargin: "0, 0, 0, 0",
      windowPadding: "0, 0, 0, 0",
    },
  },
  { name: "Nore_Talk", status: true, description: "", parameters: {} },
  { name: "Nore_Formation", status: true, description: "", parameters: {} },
  {
    name: "Nore_Tes",
    status: true,
    description:
      "テキストファイルでツクールのイベントを記述するプラグインです。\n「睡工房」さんの TES の不完全移植版です。",
    parameters: {
      scenarioFolder: "/../scenario/",
      conversionKey: "118",
      customFadeInOut: "true",
      actor1: "シンジ",
      actor2: "タクオ",
      actor3: "ユヅキ",
      actor4: "マリナ",
      actor5: "レン",
      actor6: "コクリュウ",
      actor7: "エリオット",
      actor8: "センリ",
      actor9: "ノノカ",
      actor10: "カナミ",
      actor11: "ミユ",
      actor12: "",
      actor13: "サキ",
      actor14: "",
      actor15: "リツコ",
      actor16: "カスゾウ",
      actor17: "ココナ",
      actor18: "ヨシオ",
      actor19: "ブスジマ",
      actor20: "タロウ",
      actor21: "オリバー",
      actor22: "デブオ",
      actor23: "ヤン",
      actor24: "田吾作",
      actor25: "浮浪者",
      actor26: "ミン",
      actor27: "リポーター",
      actor28: "スタジオの司会",
      actor29: "ザコ戦闘員",
      actor30: "Dr.ゲーリー",
      actor31: "戦車怪人",
      actor32: "キャプテンブランドー",
      actor33: "サンタコロース",
      actor34: "けん玉怪人",
      actor35: "会社員",
      actor36: "男たち",
      actor37: "通信",
      actor38: "怪人",
      actor39: "男優",
      actor40: "下級ヒーロー",
      actor41: "",
      actor42: "市民",
      actor43: "男",
      actor44: "女",
      actor45: "司会者",
      actor46: "おじさん",
      actor47: "ビッグ・ジョン",
      actor48: "クズオ",
      actor49: "ガリオ",
      actor50: "",
      actor51: "",
      actor52: "",
      actor53: "",
      actor54: "",
      actor55: "",
      actor56: "",
      actor57: "",
      actor58: "",
      actor59: "",
      actor60: "",
      actor61: "",
      actor62: "センリの母",
      actor63: "モン",
      actor64: "怪人王",
      actor65: "神父",
      actor66: "中級ヒーロー",
      actor67: "ヒーロー",
      actor68: "友人",
      actor69: "雑魚マフィア",
      actor70: "男",
      actor71: "男子学生",
      actor72: "女子学生",
      actor73: "種つけおじさん",
      actor74: "モナカ",
      actor75: "催眠師",
      actor76: "あかちゃん",
      actor77: "同棲相手",
      actor78: "AV男優",
      actor79: "友人の母",
      actor80: "ニュースキャスター",
      actor81: "黒人",
      actor82: "観客たち",
      actor83: "コクリュウの部下",
      actor84: "ノノカの彼氏母",
      actor85: "ノノカの彼氏",
      actor86: "見物人",
      actor87: "マリナの夫",
      actor88: "マリナの夫の部下",
      actor89: "",
      actor90: "黒人外人",
      actor91: "浮浪者",
      actor92: "雑魚怪人組織員",
      actor93: "ヒーロー協会幹部老人",
      actor94: "チンピラ",
      actor95: "研究員",
      actor96: "上級ヒーロー",
      actor97: "ヒーロー協会幹部",
      actor98: "見張りのヒーロー",
      actor99: "",
      actor100: "",
      actor101: "",
      actor102: "",
      actor103: "",
      actor104: "",
      actor105: "",
      actor106: "",
      actor107: "",
      actor108: "",
      actor109: "",
      actor110: "",
      actor111: "",
      actor112: "",
      actor113: "",
      actor114: "",
      actor115: "",
      actor116: "",
      actor117: "",
      actor118: "",
      actor119: "",
      actor120: "",
      actor133: "",
      actor134: "",
      actor135: "",
      actor136: "",
      actor137: "",
      actor138: "",
      actor139: "",
      actor140: "",
      actor141: "",
      actor142: "",
      actor143: "",
      actor144: "",
      actor145: "",
      actor146: "",
      actor147: "",
      actor148: "",
      actor149: "",
      actor150: "",
      actor151: "",
      actor152: "",
      actor153: "",
      actor154: "",
      actor155: "",
      actor156: "",
      actor157: "",
      actor158: "",
      actor159: "",
      actor160: "",
      actor161: "",
      actor162: "",
      actor163: "",
      actor164: "",
      actor165: "",
      actor166: "",
      actor167: "",
      actor168: "",
      actor169: "",
      actor170: "",
      actor171: "",
      actor172: "",
      actor173: "",
      actor174: "",
      actor175: "",
      actor176: "",
      actor177: "",
      actor178: "",
      actor179: "",
      actor180: "",
      actor181: "",
      actor182: "",
      actor183: "",
      actor184: "",
      actor185: "",
      actor186: "",
      actor187: "",
      actor188: "",
      actor189: "",
      actor190: "",
      actor191: "",
      actor192: "",
      actor193: "",
      actor194: "",
      actor195: "",
      actor196: "",
      actor197: "",
      actor198: "",
    },
  },
  {
    name: "Nore_TesValidator",
    status: true,
    description: "Nore_Tes の文法チェックスクリプトです。",
    parameters: {},
  },
  { name: "Nore_TesPlus", status: true, description: "", parameters: {} },
  {
    name: "Nore_AutoNewGame",
    status: true,
    description: "F6を押した時、自動で NewGame またはゲームロードを行います",
    parameters: { reloadKey: "122", showDevTools: "true", autoConvert: "true" },
  },
  { name: "Nore_Option", status: true, description: "", parameters: {} },
  {
    name: "Nore_BackLog",
    status: true,
    description: "バックログを表示するプラグインです。",
    parameters: {
      backLogButton: "pagedown",
      marginLeft: "70",
      marginRight: "30",
      nameLeft: "20",
      fontSize: "24",
      scrollSpeed: "5",
      windowHeight: "3000",
      maxLogCount: "50",
      bottmMargin: "50",
      logMargin: "34",
      windowSkin: "WindowBacklog",
      backOpacity: "230",
    },
  },
  { name: "Nore_Boot", status: true, description: "", parameters: {} },
  { name: "Nore_EroImg", status: true, description: "", parameters: {} },
  { name: "Nore_System", status: true, description: "", parameters: {} },
  { name: "Nore_Player", status: true, description: "", parameters: {} },
  { name: "Nore_Temp", status: true, description: "", parameters: {} },
  { name: "Nore_Party", status: true, description: "", parameters: {} },
  { name: "Nore_Actor", status: true, description: "", parameters: {} },
  { name: "Nore_Performance", status: true, description: "", parameters: {} },
  {
    name: "Nore_p",
    status: true,
    description: "console.log の別名として p を定義します",
    parameters: {},
  },
  { name: "Nore_Fukidashi", status: true, description: "", parameters: {} },
  { name: "Nore_Sprite", status: true, description: "", parameters: {} },
  {
    name: "RecollectionMode",
    status: true,
    description: "回想モード機能を追加します。",
    parameters: {},
  },
  { name: "Nore_Title", status: true, description: "", parameters: {} },
  { name: "Nore_Utils", status: true, description: "", parameters: {} },
  { name: "Nore_SikyuSprite", status: true, description: "", parameters: {} },
  { name: "Nore_Messsage2", status: true, description: "", parameters: {} },
  { name: "Nore_Dialog", status: true, description: "", parameters: {} },
  { name: "Nore_Selectable", status: true, description: "", parameters: {} },
  { name: "Nore_SlgCommand", status: true, description: "", parameters: {} },
  {
    name: "Nore_SlgCommandWindow",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_Tanetsuke", status: true, description: "", parameters: {} },
  { name: "Nore_Ui", status: true, description: "", parameters: {} },
  {
    name: "Nore_LayeredCharacter",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_Layout", status: true, description: "", parameters: {} },
  { name: "Nore_Military", status: true, description: "", parameters: {} },
  { name: "Nore_Battle", status: true, description: "", parameters: {} },
  { name: "Nore_Action", status: true, description: "", parameters: {} },
  { name: "Nore_F9", status: true, description: "", parameters: {} },
  { name: "Nore_SlgActor", status: true, description: "", parameters: {} },
  { name: "Nore_GetEffect", status: true, description: "", parameters: {} },
  { name: "Nore_BattleLog", status: true, description: "", parameters: {} },
  { name: "Nore_EroStatus", status: true, description: "", parameters: {} },
  { name: "Nore_Manko", status: true, description: "", parameters: {} },
  { name: "Nore_EventChar", status: true, description: "", parameters: {} },
  { name: "Nore_Save", status: true, description: "", parameters: {} },
  { name: "Nore_Menu", status: true, description: "", parameters: {} },
  { name: "Nore_Event", status: true, description: "", parameters: {} },
  {
    name: "Nore_EventPosition",
    status: true,
    description:
      "イベントの座標を1ピクセル単位で調整します。\n張り紙の座標とか、テーブルの上のアイテム座標を調整したいときにどうぞ。",
    parameters: {},
  },
  { name: "Nore_Tutorial", status: true, description: "", parameters: {} },
  { name: "Nore_SlgMap", status: true, description: "", parameters: {} },
  { name: "Nore_Enemy", status: true, description: "", parameters: {} },
  {
    name: "Nore_BattlePreparation",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_Dousei", status: true, description: "", parameters: {} },
  { name: "Nore_AvUi", status: true, description: "", parameters: {} },
  { name: "Nore_Members", status: true, description: "", parameters: {} },
  { name: "Nore_AvTree", status: true, description: "", parameters: {} },
  { name: "Nore_AvResultBar", status: true, description: "", parameters: {} },
  { name: "Nore_Color", status: true, description: "", parameters: {} },
  { name: "Nore_TimeEvent", status: true, description: "", parameters: {} },
  { name: "Nore_CommonEvent", status: true, description: "", parameters: {} },
  { name: "Nore_TowerParams", status: true, description: "", parameters: {} },
  { name: "Nore_Man", status: true, description: "", parameters: {} },
  { name: "Nore_ManUi", status: true, description: "", parameters: {} },
  {
    name: "Nore_FacilityFactory",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_Ninshin", status: true, description: "", parameters: {} },
  { name: "Nore_Recollection", status: true, description: "", parameters: {} },
  { name: "Nore_Sarashi", status: true, description: "", parameters: {} },
  { name: "Nore_Syusan", status: true, description: "", parameters: {} },
  { name: "Nore_Kigae", status: true, description: "", parameters: {} },
  { name: "Nore_Character", status: true, description: "", parameters: {} },
  { name: "Nore_FacilityTree", status: true, description: "", parameters: {} },
  { name: "Nore_TopWindow", status: true, description: "", parameters: {} },
  { name: "Nore_AvJacket", status: true, description: "", parameters: {} },
  { name: "Nore_AvJacketUi", status: true, description: "", parameters: {} },
  {
    name: "Nore_AvJacketScreenshot",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_AvJacketMaker", status: true, description: "", parameters: {} },
  {
    name: "FontLoad",
    status: true,
    description: "フォントロードプラグイン",
    parameters: {
      fontList:
        '["{\\"name\\":\\"sans\\",\\"fileName\\":\\"SourceHanSans-Heavy.otf\\"}","{\\"name\\":\\"rate\\",\\"fileName\\":\\"GenEiLateMinN_v2.ttf\\"}","{\\"name\\":\\"gokuhutomincho\\",\\"fileName\\":\\"gokuhutomincho.ttf\\"}"]',
    },
  },
  { name: "PixiApngAndGif", status: true, description: "", parameters: {} },
  {
    name: "ApngPicture",
    status: true,
    description: "APNGピクチャプラグイン",
    parameters: {
      PictureList:
        '["{\\"FileName\\":\\"kw_gacha01\\",\\"Gif\\":\\"false\\",\\"CachePolicy\\":\\"1\\",\\"LoopTimes\\":\\"0\\",\\"StopSwitch\\":\\"0\\"}"]',
      EnemyList: "[]",
      SideEnemyList: "[]",
      SceneApngList: "[]",
      DefaultLoopTimes: "1",
      StopLastFrame: "false",
      AllStopSwitch: "0",
      FrameCount: "0",
      NoSmooth: "false",
    },
  },
  { name: "Nore_Gacha", status: true, description: "", parameters: {} },
  { name: "Nore_DouseiUi", status: true, description: "", parameters: {} },
  { name: "Nore_Icon", status: true, description: "", parameters: {} },
  { name: "Nore_Clicker", status: true, description: "", parameters: {} },
  { name: "Nore_ClickerUi", status: true, description: "", parameters: {} },
  { name: "Nore_AvCharList", status: true, description: "", parameters: {} },
  { name: "Nore_DouseiChar", status: true, description: "", parameters: {} },
  { name: "Nore_KaijinParam", status: true, description: "", parameters: {} },
  { name: "Nore_Warp", status: true, description: "", parameters: {} },
  {
    name: "Nore_DouseiPosition",
    status: true,
    description: "",
    parameters: {},
  },
  {
    name: "Nore_ConstructionTile",
    status: true,
    description: "",
    parameters: {},
  },
  {
    name: "Nore_MilitaryDetail",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_PassiveSkill", status: true, description: "", parameters: {} },
  { name: "Nore_FormationUi", status: true, description: "", parameters: {} },
  {
    name: "Nore_ClickerBattler",
    status: true,
    description: "",
    parameters: {},
  },
  { name: "Nore_Training", status: true, description: "", parameters: {} },
  { name: "Nore_Button", status: true, description: "", parameters: {} },
  { name: "Nore_ImageFont", status: true, description: "", parameters: {} },
  { name: "Nore_AvJacketUiBig", status: true, description: "", parameters: {} },
  { name: "Nore_Webp", status: true, description: "", parameters: {} },
  { name: "Nore_WebpFiles", status: true, description: "", parameters: {} },
  { name: "Nore_SalesPage", status: true, description: "", parameters: {} },
  { name: "Nore_Window", status: true, description: "", parameters: {} },
  {
    name: "MessageSkip",
    status: true,
    description: "メッセージスキッププラグイン",
    parameters: {
      スキップキー: "S",
      オートキー: "A",
      スキップスイッチ: "0",
      オートスイッチ: "0",
      スキップアイコン: "140",
      オートアイコン: "75",
      アイコンX: "0",
      アイコンY: "0",
      押し続けスキップ: "false",
      オート待機フレーム: "50 + textSize * 5",
      終了解除スイッチID: "0",
      スキップピクチャ: "",
      スキップピクチャX: "500",
      スキップピクチャY: "0",
      オートピクチャ: "",
      オートピクチャX: "750",
      オートピクチャY: "0",
      スイッチピクチャ: "",
      スイッチピクチャトリガー: "0",
      スイッチピクチャX: "750",
      スイッチピクチャY: "0",
      ボタン原点: "0",
      ボタン表示スイッチID: "0",
      ピクチャ座標タイプ: "relative",
      無効化スイッチ: "0",
    },
  },
  { name: "Nore_Version", status: true, description: "", parameters: {} },
  { name: "Nore_ScreenShot", status: true, description: "", parameters: {} },
  { name: "Nore_Help", status: true, description: "", parameters: {} },
  { name: "Nore_Route", status: true, description: "", parameters: {} },
  { name: "Nore_TextInput", status: true, description: "", parameters: {} },
  { name: "Nore_WideUseEro", status: true, description: "", parameters: {} },
  { name: "Nore_Baby", status: true, description: "", parameters: {} },
  { name: "Nore_Epilogue", status: true, description: "", parameters: {} },
  { name: "Nore_DouseiIdle", status: true, description: "", parameters: {} },
];

repo_name: onms/dead

license: unknown


code:
/*=============================================================================
 ApngPicture.js
----------------------------------------------------------------------------
 (C)2019 Triacontane
 This software is released under the MIT License.
 http://opensource.org/licenses/mit-license.php
----------------------------------------------------------------------------
 Version
 2.4.2 2023/10/27 シーンのAPNGに表示スイッチを指定したとき、スイッチがOFFでも一瞬だけ表示されてしまう問題を修正
 2.4.1 2023/03/21 GIFファイルを使用する場合のヘルプ文言を分かりやすく修正
 2.4.0 2022/12/25 APNG画像のぼかしを除去できる設定を追加
 2.3.4 2022/12/15 GIFファイルを選択したとき内部で保持する画像サイズが0になってしまう問題を修正
 2.3.3 2022/12/14 サイドビュー用の敵キャラファイルの設定パラメータにgifファイルかどうかのフラグがなかった問題を修正
 2.3.2 2022/10/27 1セルのフレーム数を変更したとき、ループ回数の設定が機能しなくなる問題を修正
 2.3.1 2022/06/06 apngのフレーム数を指定したとき停止スイッチが機能しない問題を修正
 2.3.0 2022/02/06 1セルごとのフレーム数をゲーム側で設定できるパラメータを追加
 2.2.1 2021/10/09 AltMenuScreen2MZとの並び順を指定するアノテーションを追加
 2.2.0 2021/04/26 2.1.6の修正でGIFファイルが使えなくなっていた問題を修正
                  GIFファイルの指定方法を変更
 2.1.6 2021/03/10 システム画像や敵キャラ画像としてapngを使用するとき、ピクチャにも同名の画像がないとエラーになる問題を修正
 2.1.5 2021/02/01 数字のみのファイルをapng指定して起動するとエラーになる問題を修正
 2.1.4 2021/01/18 2.1.3の修正でapngでないピクチャや敵キャラを表示しようとするとエラーになる問題を修正
 2.1.3 2021/01/17 キャッシュ方針を「あり」にした画像を再表示するとき、フレームを初期化するよう修正
 2.1.2 2021/01/13 2.1.1の修正で一度消去したピクチャを再表示しようとするとエラーになる問題を修正
 2.1.1 2020/12/11 キャッシュ方針を「キャッシュしない」以外に設定すると消去にエラーが起きる場合がある問題を修正
 2.1.0 2020/11/11 APNGのアニメーションを停止、全停止できるスイッチを追加
 2.0.1 2020/11/03 プラグイン上でapng画像の高さを正しく取得できるよう修正
 2.0.0 2020/10/29 MZで動作するよう全面的に修正
 1.6.0 2020/10/24 再生回数を指定したときに最初ではなく最後のフレームでアニメーションが止まる設定を追加
 1.5.0 2020/10/17 サイドビューの敵キャラをapng化できるよう修正。機能が不完全であることに変わりはありません。
 1.4.3 2020/03/17 ライブラリがpixi5.0対応によるバージョンアップで使用できなくなったのでヘルプの取得元を旧版に変更
 1.4.2 2020/03/07 キャッシュしない設定のapngを繰り返し表示、削除し続けるとメモリリークが発生する問題を修正
 1.4.1 2020/02/23 英語版のプラグインパラメータの記述が不足していたので修正
 1.4.0 2020/02/01 アニメーションのループ回数を指定できる機能を追加
 1.3.1 2019/12/31 画像を登録せずゲーム開始するとローディングが完了しない問題を修正
 1.3.0 2019/12/31 APNGのキャッシュ機能を追加
 1.2.1 2019/12/31 シーン追加画像でgifが表示されない問題を修正
 1.2.0 2019/12/31 APNGのみツクール本体の暗号化機能に対応
 1.1.0 2019/12/29 シーン追加画像の表示優先度を設定できる機能を追加
 1.0.0 2019/12/27 初版
----------------------------------------------------------------------------
 [Blog]   : https://triacontane.blogspot.jp/
 [Twitter]: https://twitter.com/triacontane/
 [GitHub] : https://github.com/triacontane/
=============================================================================*/

/*:
 * @plugindesc ApngSupportPlugin
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/ApngPicture.js
 * @base PluginCommonBase
 * @base PixiApngAndGif
 * @orderAfter PluginCommonBase
 * @orderAfter PixiApngAndGif
 * @orderBefore AltMenuScreen2MZ
 * @author triacontane
 *
 * @param PictureList
 * @desc List of picture images to be handled as APNG.
 * @default []
 * @type struct<PictureApngRecord>[]
 *
 * @param EnemyList
 * @desc List of enemy images to be handled as APNG.
 * @default []
 * @type struct<EnemyApngRecord>[]
 *
 * @param SideEnemyList
 * @desc List of enemy images to be handled as APNG.
 * @default []
 * @type struct<SideEnemyApngRecord>[]
 *
 * @param SceneApngList
 * @desc This is a list of APNG to be displayed for each scene.
 * @default []
 * @type struct<SceneApngRecord>[]
 *
 * @param DefaultLoopTimes
 * @desc The number of animation loops. It stops after looping the specified number of times.
 * @default 0
 * @type number
 *
 * @param StopLastFrame
 * @desc The animation stops at the last frame, not at the beginning.
 * @default false
 * @type boolean
 *
 * @param AllStopSwitch
 * @desc All animations stop when the specified number switch is ON.
 * @default 0
 * @type switch
 *
 * @help ApngPicture.js
 *
 * Enables handling of APNGs and GIF animations.
 * You can add APNGs to pictures, enemy characters, and any scene.
 *
 * After registering the file as an APNG from the parameters,
 * you can add You just need to designate them as pictures and enemy characters,
 * just like normal images.
 *
 * The following libraries are required for use.
 * https://github.com/sbfkcel/pixi-apngAndGif
 *
 * Download
 * https://github.com/sbfkcel/pixi-apngAndGif/blob/master/dist/PixiApngAndGif.js
 *
 * Attention!
 * It is not recommended to register a large number of images to
 * load the registered images at the start of the game.
 * In addition, loading large APNG images may slow down the display.
 * If the display is slow, please try GIF animation.
 *
 * If you want to use GIFs, please note that the editor will not recognize
 * files without a GIF extension.
 * Please enter the file name with the extension directly in the parameter.
 * You can also display the picture from a script or by using
 * Please use a dummy png file of the same name to specify it.
 * Also, GIFs are not subject to the editor's encryption feature.
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc APNGピクチャプラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/ApngPicture.js
 * @base PluginCommonBase
 * @base PixiApngAndGif
 * @orderAfter PluginCommonBase
 * @orderAfter PixiApngAndGif
 * @orderBefore AltMenuScreen2MZ
 * @author トリアコンタン
 *
 * @param PictureList
 * @text APNGのピクチャリスト
 * @desc APNGとして扱うピクチャ画像のリストです。GIFを指定したい場合は直接入力してください。
 * @default []
 * @type struct<PictureApngRecord>[]
 *
 * @param EnemyList
 * @text APNGの敵キャラリスト
 * @desc APNGとして扱う敵キャラ画像のリストです。GIFを指定したい場合は直接入力してください。
 * @default []
 * @type struct<EnemyApngRecord>[]
 *
 * @param SideEnemyList
 * @text APNGのSV敵キャラリスト
 * @desc APNGとして扱うSV敵キャラ画像のリストです。サイドビューの画像を使用したい場合はこちらから登録してください。
 * @default []
 * @type struct<SideEnemyApngRecord>[]
 *
 * @param SceneApngList
 * @text シーンAPNGのリスト
 * @desc シーンごとに表示するAPNGのリストです。GIFを指定したい場合は直接入力してください。
 * @default []
 * @type struct<SceneApngRecord>[]
 *
 * @param DefaultLoopTimes
 * @text デフォルトループ回数
 * @desc アニメーションのループ回数です。指定した回数分ループ再生すると止まります。0を指定すると無限にアニメーションします。
 * @default 0
 * @type number
 *
 * @param StopLastFrame
 * @text 最終フレームで止める
 * @desc ループ回数が決まっているアニメーションを再生したとき最初ではなく最後のフレームでアニメーションが止まります。
 * @default false
 * @type boolean
 *
 * @param AllStopSwitch
 * @text 全停止スイッチ
 * @desc 指定した番号スイッチがONのとき全てのアニメーションが停止します。
 * @default 0
 * @type switch
 *
 * @param FrameCount
 * @text 1セルのフレーム数
 * @desc 設定すると1セルごとのフレーム数をゲーム側で固定にできます。
 * @default 0
 * @type number
 *
 * @param NoSmooth
 * @text ぼかし除去
 * @desc 画像拡大時にぼかしが入らなくなります。
 * @default false
 * @type boolean
 *
 * @help ApngPicture.js
 *
 * APNG、もしくはGIFアニメの取り扱いを可能にします。
 * ピクチャ、敵キャラのほか任意のシーンにAPNGを追加表示できます。
 *
 * パラメータからAPNGとしてファイルを登録したら後は
 * 通常の画像と同じようにピクチャや敵キャラとして指定するだけです。
 *
 * 使用には以下のライブラリが必要です。
 * https://github.com/sbfkcel/pixi-apngAndGif
 *
 * ライセンスを確認のうえ以下からダウンロードしてください。
 * https://github.com/sbfkcel/pixi-apngAndGif/blob/master/dist/PixiApngAndGif.js
 *
 * 注意！
 * ゲーム開始時に登録した画像を読み込むため大量の画像を登録することは推奨しません。
 * また、画像サイズの大きいAPNGを読み込むと、表示が遅くなる場合があります。
 * 表示が遅い場合はGIFアニメもお試しください。
 *
 * GIFを使用したい場合、拡張子がgifのファイルはエディタで認識されないので
 * ファイル名が同一のダミーpngファイルを用意して選択してください。
 * ただし、GIFはエディタの暗号化機能の対象外となります。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~SceneApngRecord:ja
 *
 * @param SceneName
 * @text 対象シーン
 * @desc 画像を追加するシーンです。
 * @type select
 * @default Scene_Title
 * @option タイトル
 * @value Scene_Title
 * @option ゲームオーバー
 * @value Scene_Gameover
 * @option バトル
 * @value Scene_Battle
 * @option メインメニュー
 * @value Scene_Menu
 * @option アイテム
 * @value Scene_Item
 * @option スキル
 * @value Scene_Skill
 * @option 装備
 * @value Scene_Equip
 * @option ステータス
 * @value Scene_Status
 * @option オプション
 * @value Scene_Options
 * @option セーブ
 * @value Scene_Save
 * @option ロード
 * @value Scene_Load
 * @option ゲーム終了
 * @value Scene_End
 * @option ショップ
 * @value Scene_Shop
 * @option 名前入力
 * @value Scene_Name
 * @option デバッグ
 * @value Scene_Debug
 * @option サウンドテスト
 * @value Scene_SoundTest
 * @option 用語辞典
 * @value Scene_Glossary
 *
 * @param FileName
 * @text ファイル名
 * @desc 追加するAPNGのファイル名です。
 * @default
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param Gif
 * @text GIFファイル
 * @desc 対象がGIFファイルの場合はONにしてください。ファイル名は拡張子なしのファイル名を指定してください。
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @text キャッシュ方針
 * @desc 画像のキャッシュ方針です。大量にキャッシュするとメモリ使用量に影響が出る場合があります。
 * @default 0
 * @type select
 * @option キャッシュしない
 * @value 0
 * @option 初回表示時にキャッシュ
 * @value 1
 * @option ゲーム起動時にキャッシュ
 * @value 2
 *
 * @param X
 * @text X座標
 * @desc 追加するAPNGのX座標です。
 * @default 0
 * @type number
 *
 * @param Y
 * @text Y座標
 * @desc 追加するAPNGのY座標です。
 * @default 0
 * @type number
 *
 * @param Origin
 * @text 原点
 * @desc 追加するAPNGの原点です。
 * @default 0
 * @type select
 * @option 左上
 * @value 0
 * @option 中央
 * @value 1
 *
 * @param Priority
 * @text 優先度
 * @desc 画像の表示優先度です。最背面は画面上に表示されないことが多いので通常の使用では推奨しません。
 * @default 0
 * @type select
 * @option 最前面
 * @value 0
 * @option ウィンドウの下
 * @value 1
 * @option 最背面
 * @value 2
 *
 * @param Switch
 * @text 出現条件スイッチ
 * @desc 指定したスイッチがONのときのみ表示されます。指定しない場合、常に表示されます。
 * @default 0
 * @type switch
 *
 * @param LoopTimes
 * @text ループ回数
 * @desc アニメーションのループ回数です。0を指定するとデフォルト設定に従います。
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @text 停止スイッチ
 * @desc 指定した番号スイッチがONのときアニメーションが停止します。
 * @default 0
 * @type switch
 */

/*~struct~PictureApngRecord:ja
 *
 * @param FileName
 * @text ファイル名
 * @desc 追加するAPNGのファイル名です。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param Gif
 * @text GIFファイル
 * @desc 対象がGIFファイルの場合はONにしてください。ファイル名は拡張子なしのファイル名を指定してください。
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @text キャッシュ方針
 * @desc 画像のキャッシュ方針です。大量にキャッシュするとメモリ使用量に影響が出る場合があります。
 * @default 0
 * @type select
 * @option キャッシュしない
 * @value 0
 * @option 初回表示時にキャッシュ
 * @value 1
 * @option ゲーム起動時にキャッシュ
 * @value 2
 *
 * @param LoopTimes
 * @text ループ回数
 * @desc アニメーションのループ回数です。0を指定するとデフォルト設定に従います。
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @text 停止スイッチ
 * @desc 指定した番号スイッチがONのときアニメーションが停止します。
 * @default 0
 * @type switch
 */

/*~struct~EnemyApngRecord:ja
 *
 * @param FileName
 * @text ファイル名
 * @desc 追加するAPNGのファイル名です。
 * @default
 * @require 1
 * @dir img/enemies/
 * @type file
 *
 * @param Gif
 * @text GIFファイル
 * @desc 対象がGIFファイルの場合はONにしてください。ファイル名は拡張子なしのファイル名を指定してください。
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @text キャッシュ方針
 * @desc 画像のキャッシュ方針です。大量にキャッシュするとメモリ使用量に影響が出る場合があります。
 * @default 0
 * @type select
 * @option キャッシュしない
 * @value 0
 * @option 初回表示時にキャッシュ
 * @value 1
 * @option ゲーム起動時にキャッシュ
 * @value 2
 *
 * @param LoopTimes
 * @text ループ回数
 * @desc アニメーションのループ回数です。0を指定するとデフォルト設定に従います。
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @text 停止スイッチ
 * @desc 指定した番号スイッチがONのときアニメーションが停止します。
 * @default 0
 * @type switch
 */

/*~struct~SideEnemyApngRecord:ja
 *
 * @param FileName
 * @text ファイル名
 * @desc 追加するAPNGのファイル名です。
 * @default
 * @require 1
 * @dir img/sv_enemies/
 * @type file
 *
 * @param Gif
 * @text GIFファイル
 * @desc 対象がGIFファイルの場合はONにしてください。ファイル名は拡張子なしのファイル名を指定してください。
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @text キャッシュ方針
 * @desc 画像のキャッシュ方針です。大量にキャッシュするとメモリ使用量に影響が出る場合があります。
 * @default 0
 * @type select
 * @option キャッシュしない
 * @value 0
 * @option 初回表示時にキャッシュ
 * @value 1
 * @option ゲーム起動時にキャッシュ
 * @value 2
 *
 * @param LoopTimes
 * @text ループ回数
 * @desc アニメーションのループ回数です。0を指定するとデフォルト設定に従います。
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @text 停止スイッチ
 * @desc 指定した番号スイッチがONのときアニメーションが停止します。
 * @default 0
 * @type switch
 */

/*~struct~SceneApngRecord:
 *
 * @param SceneName
 * @desc Target Scene
 * @type select
 * @default Scene_Title
 * @option Scene_Title
 * @option Scene_Gameover
 * @option Scene_Battle
 * @option Scene_Menu
 * @option Scene_Item
 * @option Scene_Skill
 * @option Scene_Equip
 * @option Scene_Status
 * @option Scene_Options
 * @option Scene_Save
 * @option Scene_Load
 * @option Scene_End
 * @option Scene_Shop
 * @option Scene_Name
 * @option Scene_Debug
 * @option Scene_SoundTest
 * @option Scene_Glossary
 *
 * @param FileName
 * @desc File name of apng
 * @default
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param Gif
 * @text
 * @desc
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @desc Cache policy
 * @default 0
 * @type select
 * @option None
 * @value 0
 * @option Cache on first display
 * @value 1
 * @option Cache at game start
 * @value 2
 *
 * @param X
 * @desc X of apng
 * @default 0
 * @type number
 *
 * @param Y
 * @desc Y of apng
 * @default 0
 * @type number
 *
 * @param Origin
 * @desc Origin of apng
 * @default 0
 * @type select
 * @option Upper left
 * @value 0
 * @option Center
 * @value 1
 *
 * @param Priority
 * @desc Priority of apng
 * @default 0
 * @type select
 * @option Front
 * @value 0
 * @option Under window
 * @value 1
 * @option Back
 * @value 2
 *
 * @param Switch
 * @desc Displayed only when the specified switch is ON
 * @default 0
 * @type switch
 *
 * @param LoopTimes
 * @desc The number of animation loops. Specifying 0 follows the default setting.
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @desc The animation stops when the specified number switch is turned on.
 * @default 0
 * @type switch
 */

/*~struct~PictureApngRecord:
 *
 * @param FileName
 * @desc File name of apng
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param Gif
 * @text
 * @desc
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @desc Cache policy
 * @default 0
 * @type select
 * @option None
 * @value 0
 * @option Cache on first display
 * @value 1
 * @option Cache at game start
 * @value 2
 *
 * @param LoopTimes
 * @desc The number of animation loops. Specifying 0 follows the default setting.
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @desc The animation stops when the specified number switch is turned on.
 * @default 0
 * @type switch
 */

/*~struct~EnemyApngRecord:
 *
 * @param FileName
 * @desc File name of apng
 * @default
 * @require 1
 * @dir img/enemies/
 * @type file
 *
 * @param Gif
 * @text
 * @desc
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @desc Cache policy
 * @default 0
 * @type select
 * @option None
 * @value 0
 * @option Cache on first display
 * @value 1
 * @option Cache at game start
 * @value 2
 *
 * @param LoopTimes
 * @desc The number of animation loops. Specifying 0 follows the default setting.
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @desc The animation stops when the specified number switch is turned on.
 * @default 0
 * @type switch
 */

/*~struct~SideEnemyApngRecord:
 *
 * @param FileName
 * @desc File name of apng
 * @default
 * @require 1
 * @dir img/sv_enemies/
 * @type file
 *
 * @param Gif
 * @text
 * @desc
 * @default false
 * @type boolean
 *
 * @param CachePolicy
 * @desc Cache policy
 * @default 0
 * @type select
 * @option None
 * @value 0
 * @option Cache on first display
 * @value 1
 * @option Cache at game start
 * @value 2
 *
 * @param LoopTimes
 * @desc The number of animation loops. Specifying 0 follows the default setting.
 * @default 0
 * @type number
 *
 * @param StopSwitch
 * @desc The animation stops when the specified number switch is turned on.
 * @default 0
 * @type switch
 */

(function () {
  "use strict";

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

  /**
   * ApngLoader
   * APNGもしくはGIF画像を読み込んで保持します。
   */
  class ApngLoader {
    constructor(folder, paramList) {
      this._folder = folder;
      this._fileHash = {};
      this._cachePolicy = {};
      this._options = {};
      this._paramList = paramList;
      if (this._paramList && this._paramList.length > 0) {
        this.addAllImage();
      }
      this._spriteCache = {};
    }

    addAllImage() {
      const option = this.getLoadOption();
      this._paramList.forEach(function (item) {
        this.addImage(item, option);
      }, this);
      PIXI.Loader.shared.onComplete.add(this.cacheStartup.bind(this));
      ApngLoader.startLoading();
    }

    addImage(item, option) {
      const name = String(item.FileName) || "";
      const ext = this.findExt(item);
      const path = name.match(/http:/)
        ? name
        : `img/${this._folder}/${name}.${ext}`;
      if (!this._fileHash.hasOwnProperty(name)) {
        this._fileHash[name] = ApngLoader.convertDecryptExt(path);
        this._cachePolicy[name] = item.CachePolicy;
        this._options[name] = item;
        PIXI.Loader.shared.add(path, option);
      }
    }

    findExt(item) {
      if (item.Gif) {
        return "gif";
      } else {
        return Utils.hasEncryptedImages() ? "png_" : "png";
      }
    }

    getLoadOption() {
      return {
        loadType: PIXI.LoaderResource.LOAD_TYPE.XHR,
        xhrType: PIXI.LoaderResource.XHR_RESPONSE_TYPE.BUFFER,
        crossOrigin: "",
      };
    }

    createSprite(name) {
      if (!this.isApng(name)) {
        return null;
      }
      if (this._isNeedCache(name)) {
        if (this._spriteCache[name]) {
          return this._spriteCache[name];
        }
        const sprite = this._createPixiApngAndGif(name);
        this._spriteCache[name] = sprite;
        return sprite;
      } else {
        return this._createPixiApngAndGif(name);
      }
    }

    _createPixiApngAndGif(name) {
      const pixiApng = new PixiApngAndGif(
        this._fileHash[name],
        ApngLoader._resource
      );
      const loopCount = this._options[name].LoopTimes || param.DefaultLoopTimes;
      if (loopCount > 0) {
        pixiApng.play(loopCount);
      }
      const sprite = pixiApng.sprite;
      sprite.pixiApng = pixiApng;
      sprite.pixiApngOption = this._options[name];
      if (param.NoSmooth) {
        pixiApng.textures.forEach(
          (texture) =>
            (texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST)
        );
      }
      return sprite;
    }

    _isNeedCache(name) {
      return this._cachePolicy[name] > 0;
    }

    isApng(name) {
      return !!this._fileHash[name];
    }

    cacheStartup() {
      Object.keys(this._cachePolicy).forEach(function (name) {
        if (this._cachePolicy[name] === 2) {
          this.createSprite(name);
        }
      }, this);
    }

    static startLoading() {
      this._loading = true;
    }

    static onLoadResource(progress, resource) {
      this._resource = resource;
      Object.keys(this._resource).forEach(function (key) {
        if (this._resource[key].extension === "png_") {
          ApngLoader.decryptResource(key);
        }
      }, this);
    }

    static decryptResource(key) {
      const resource = this._resource[key];
      resource.data = Utils.decryptArrayBuffer(resource.data);
      const newKey = ApngLoader.convertDecryptExt(key);
      resource.name = newKey;
      resource.url = newKey;
      resource.extension = "png";
      this._resource[newKey] = resource;
      delete this._resource[key];
    }

    static isReady() {
      return !!this._resource || !this._loading;
    }

    static convertDecryptExt(key) {
      return key.replace(/\.png_$/, ".png");
    }
  }
  ApngLoader._resource = null;

  const _Scene_Boot_isReady = Scene_Boot.prototype.isReady;
  Scene_Boot.prototype.isReady = function () {
    const result = _Scene_Boot_isReady.apply(this, arguments);
    if (result) {
      SceneManager.setupApngLoaderIfNeed();
    }
    return result && ApngLoader.isReady();
  };

  const _Scene_Base_create = Scene_Base.prototype.create;
  Scene_Base.prototype.create = function () {
    _Scene_Base_create.apply(this, arguments);
    this.createSceneApng();
  };

  Scene_Base.prototype.createSceneApng = function () {
    this._apngList = this.findSceneApngList().map(function (item) {
      return new SpriteSceneApng(item);
    }, this);
  };

  const _Scene_Base_terminate = Scene_Base.prototype.terminate;
  Scene_Base.prototype.terminate = function () {
    _Scene_Base_terminate.apply(this, arguments);
    this.destroySceneApng();
    if (this._spriteset) {
      this._spriteset.destroyApngPicture();
    }
  };

  Scene_Base.prototype.destroySceneApng = function () {
    this._apngList.forEach(function (sprite) {
      sprite.destroyApngIfNeed();
    });
  };

  const _Scene_Base_start = Scene_Base.prototype.start;
  Scene_Base.prototype.start = function () {
    _Scene_Base_start.apply(this, arguments);
    this.setApngPriority();
  };

  Scene_Base.prototype.setApngPriority = function () {
    let windowLayerIndex = this._windowLayer
      ? this.getChildIndex(this._windowLayer)
      : 0;
    this._apngList.forEach(function (sprite) {
      switch (sprite.getPriority()) {
        case 0:
          this.addChild(sprite);
          break;
        case 1:
          this.addChildAt(sprite, windowLayerIndex);
          windowLayerIndex++;
          break;
        default:
          this.addChildAt(sprite, 0);
      }
    }, this);
  };

  Scene_Base.prototype.findSceneApngList = function () {
    const currentSceneName = PluginManagerEx.findClassName(this);
    return (param.SceneApngList || []).filter(function (data) {
      return data.SceneName === currentSceneName;
    }, this);
  };

  Spriteset_Base.prototype.destroyApngPicture = function () {
    this.destroyApngPictureContainer(this._pictureContainer);
    // for PicturePriorityCustomize.js
    this.destroyApngPictureContainer(this._pictureContainerLower);
    this.destroyApngPictureContainer(this._pictureContainerMiddle);
    this.destroyApngPictureContainer(this._pictureContainerUpper);
  };

  Spriteset_Base.prototype.destroyApngPictureContainer = function (container) {
    if (!container) {
      return;
    }
    container.children.forEach(function (sprite) {
      if (sprite.destroyApngIfNeed) {
        sprite.destroyApngIfNeed();
      }
    });
  };

  Spriteset_Battle.prototype.destroyApngPicture = function () {
    Spriteset_Base.prototype.destroyApngPicture.call(this);
    this._enemySprites.forEach(function (sprite) {
      sprite.destroyApngIfNeed();
    });
  };

  /**
   * SceneManager
   * APNGのローダを管理します。
   */
  SceneManager.setupApngLoaderIfNeed = function () {
    if (this._apngLoaderPicture) {
      return;
    }
    PIXI.Loader.shared.onComplete.add(
      ApngLoader.onLoadResource.bind(ApngLoader)
    );
    this._apngLoaderPicture = new ApngLoader("pictures", param.PictureList);
    this._apngLoaderEnemy = new ApngLoader("enemies", param.EnemyList);
    this._apngLoaderSideEnemy = new ApngLoader(
      "sv_enemies",
      param.SideEnemyList
    );
    this._apngLoaderSystem = new ApngLoader("system", param.SceneApngList);
    PIXI.Loader.shared.load();
  };

  SceneManager.tryLoadApngPicture = function (name) {
    return this._apngLoaderPicture.createSprite(name);
  };

  SceneManager.tryLoadApngEnemy = function (name) {
    return this._apngLoaderEnemy.createSprite(name);
  };

  SceneManager.tryLoadApngSideEnemy = function (name) {
    return this._apngLoaderSideEnemy.createSprite(name);
  };

  SceneManager.tryLoadApngSystem = function (name) {
    return this._apngLoaderSystem.createSprite(name);
  };

  /**
   * Sprite
   * APNGの読み込み処理を追加します。
   */
  Sprite.prototype.addApngChild = function (name) {
    if (this._apngSprite) {
      this.destroyApngIfNeed();
    }
    this._apngSprite = this.loadApngSprite(name);
    if (this._apngSprite) {
      if (this.isApngCache()) {
        this._apngSprite.pixiApng.jumpToFrame(0);
        this._apngSprite.pixiApng.play();
      }
      this.addChild(this._apngSprite);
      const frame = this._apngSprite.pixiApng.textures[0]._frame;
      this.bitmap = new Bitmap(frame.width, frame.height);
      this.updateApngAnchor();
      this.updateApngBlendMode();
    }
    this._apngLoopCount = 1;
    this._apngLoopFrame = 0;
  };

  Sprite.prototype.destroyApngIfNeed = function () {
    if (this._apngSprite) {
      if (!this.isApngCache()) {
        this.destroyApng();
      } else {
        this.removeApng();
      }
    }
  };

  Sprite.prototype.destroyApng = function () {
    const pixiApng = this._apngSprite.pixiApng;
    if (pixiApng) {
      pixiApng.textures.forEach(function (texture) {
        texture.baseTexture.destroy();
        texture.destroy();
      });
      pixiApng.stop();
    }
    this.removeApng();
  };

  Sprite.prototype.removeApng = function () {
    this.removeChild(this._apngSprite);
    this._apngSprite = null;
  };

  Sprite.prototype.isApngCache = function () {
    return this._apngSprite.pixiApngOption.CachePolicy !== 0;
  };

  Sprite.prototype.loadApngSprite = function () {
    return null;
  };

  Sprite.prototype.updateApngAnchor = function () {
    if (this._apngSprite) {
      this._apngSprite.anchor.x = this.anchor.x;
      this._apngSprite.anchor.y = this.anchor.y;
    }
  };

  Sprite.prototype.updateApngBlendMode = function () {
    if (this._apngSprite) {
      this._apngSprite.blendMode = this.blendMode;
    }
  };

  const _Sprite_update = Sprite.prototype.update;
  Sprite.prototype.update = function () {
    _Sprite_update.apply(this, arguments);
    if (this._apngSprite) {
      if (param.FrameCount > 0 && !this._apngSpritePause) {
        this.updateApngFrame();
      }
      this.updateApngSwitchStop();
      this.updateApngFrameStop();
    }
  };

  Sprite.prototype.updateApngFrame = function () {
    if (this._apngStop) {
      return;
    }
    const frameLength = this._apngSprite.pixiApng.getFramesLength();
    const frame =
      Math.floor(Graphics.frameCount / param.FrameCount) % frameLength;
    this._apngSprite.pixiApng.jumpToFrame(frame);
  };

  Sprite.prototype.updateApngFrameStop = function () {
    if (!param.StopLastFrame && !param.FrameCount) {
      return;
    }
    const frame = this._apngSprite.pixiApng.__status.frame;
    if (frame < this._apngLoopFrame) {
      this._apngLoopCount++;
    }
    this._apngLoopFrame = frame;
    const loopLimit = this.getLoopTimes();
    if (loopLimit <= 0) {
      return;
    }
    const frameLength = this._apngSprite.pixiApng.getFramesLength();
    if (loopLimit <= this._apngLoopCount && frameLength <= frame + 1) {
      this._apngSprite.pixiApng.stop();
      this._apngStop = true;
    }
  };

  Sprite.prototype.updateApngSwitchStop = function () {
    if (
      $gameSwitches.value(this.getStopSwitch()) ||
      $gameSwitches.value(param.AllStopSwitch)
    ) {
      this._apngSprite.pixiApng.stop();
      this._apngSpritePause = true;
    } else if (this._apngSpritePause) {
      this._apngSprite.pixiApng.play();
      this._apngSpritePause = false;
    }
  };

  Sprite.prototype.getLoopTimes = function () {
    return this._apngSprite.pixiApngOption.LoopTimes || param.DefaultLoopTimes;
  };

  Sprite.prototype.getStopSwitch = function () {
    return this._apngSprite.pixiApngOption.StopSwitch;
  };

  Sprite.prototype.isGif = function () {
    return this._apngSprite && this._apngSprite.pixiApngOption.Gif;
  };

  /**
   * Sprite_Picture
   * APNGとして登録されているピクチャの読み込みを追加します。
   */
  const _Sprite_Picture_loadBitmap = Sprite_Picture.prototype.loadBitmap;
  Sprite_Picture.prototype.loadBitmap = function () {
    _Sprite_Picture_loadBitmap.apply(this, arguments);
    this.addApngChild(this._pictureName);
  };

  Sprite_Picture.prototype.loadApngSprite = function (name) {
    return SceneManager.tryLoadApngPicture(name);
  };

  const _Sprite_Picture_updateOrigin = Sprite_Picture.prototype.updateOrigin;
  Sprite_Picture.prototype.updateOrigin = function () {
    _Sprite_Picture_updateOrigin.apply(this, arguments);
    this.updateApngAnchor();
  };

  const _Sprite_Picture_updateOther = Sprite_Picture.prototype.updateOther;
  Sprite_Picture.prototype.updateOther = function () {
    _Sprite_Picture_updateOther.apply(this, arguments);
    this.updateApngBlendMode();
  };

  const _Sprite_Picture_updateBitmap = Sprite_Picture.prototype.updateBitmap;
  Sprite_Picture.prototype.updateBitmap = function () {
    _Sprite_Picture_updateBitmap.apply(this, arguments);
    const picture = this.picture();
    if (!picture && this._apngSprite) {
      this.destroyApngIfNeed();
    }
  };

  /**
   * Sprite_Enemy
   * APNGとして登録されている敵キャラの読み込みを追加します。
   */
  const _Sprite_Enemy_loadBitmap = Sprite_Enemy.prototype.loadBitmap;
  Sprite_Enemy.prototype.loadBitmap = function (name, hue) {
    _Sprite_Enemy_loadBitmap.apply(this, arguments);
    this.addApngChild(name);
  };

  Sprite_Enemy.prototype.loadApngSprite = function (name) {
    if ($gameSystem.isSideView()) {
      return SceneManager.tryLoadApngSideEnemy(name);
    } else {
      return SceneManager.tryLoadApngEnemy(name);
    }
  };

  /**
   * SpriteSceneApng
   * シーンに追加表示するAPNGスプライトです。
   */
  class SpriteSceneApng extends Sprite {
    constructor(item) {
      super();
      this.setup(item);
    }

    setup(item) {
      this.addApngChild(item.FileName);
      this.x = item.X;
      this.y = item.Y;
      if (item.Origin === 1) {
        this.anchor.x = 0.5;
        this.anchor.y = 0.5;
      }
      this._switch = item.Switch;
      this._priority = item.Priority;
      this.updateVisibly();
    }

    loadApngSprite(name) {
      return SceneManager.tryLoadApngSystem(name.replace(/\..*/, ""));
    }

    update() {
      super.update();
      this.updateVisibly();
    }

    updateVisibly() {
      this.visible = this.isValid();
    }

    isValid() {
      return !this._switch || $gameSwitches.value(this._switch);
    }

    getPriority() {
      return this._priority;
    }
  }
})();


code:
//=============================================================================
// FontLoad.js
// ----------------------------------------------------------------------------
// (C)2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.2.1 2022/11/26 ヘルプ微修正
// 2.2.0 2022/08/28 メッセージ中に一時的にフォントを変更できる機能を追加
// 2.1.0 2022/06/19 メッセージフォントを変更できるプラグインコマンドを追加
// 2.0.1 2021/10/20 ヘルプ微修正
// 2.0.0 2021/06/05 MZで動作するよう再構築
// 1.1.1 2019/09/15 パラメータの型指定機能に対応
// 1.1.0 2017/03/11 本体v1.3.5(コミュニティ版)で機能しなくなる問題を修正
// 1.0.0 2016/06/02 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc フォントロードプラグイン
 * @target MZ
 * @url https://github.com/triacontane/RPGMakerMV/tree/mz_master/FontLoad.js
 * @base PluginCommonBase
 * @orderAfter PluginCommonBase
 * @author トリアコンタン
 *
 * @param fontList
 * @text フォント一覧
 * @desc 使用するフォントの一覧です。
 * @default []
 * @type struct<Font>[]
 *
 * @command CHANGE_MESSAGE_FONT
 * @text メッセージフォント変更
 * @desc メッセージ表示のフォントを変更します。
 *
 * @arg name
 * @text フォント名
 * @desc 変更するフォントの名称です。
 * @default
 *
 * @help 指定したURLのフォントを指定した名前でロードします。
 * ロードするだけなので、基本的には他のプラグインやスクリプトと
 * 組み合わせて使用します。
 *
 * メッセージフォントの変更だけはプラグインコマンドと制御文字を用意しています。
 * メッセージ中に以下の制御文字が使用できます。
 * ・nameで指定したフォント名に一時的に変更
 * \fn[name]
 *
 * ・デフォルトのフォントに戻す
 * \fn
 *
 * このプラグインの利用にはベースプラグイン『PluginCommonBase.js』が必要です。
 * 『PluginCommonBase.js』は、RPGツクールMZのインストールフォルダ配下の
 * 以下のフォルダに格納されています。
 * dlc/BasicResources/plugins/official
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/*~struct~Font:
 *
 * @param name
 * @text 名称
 * @desc 利用側から指定する際に使うフォントの名称です。省略するとフォントファイルから拡張子を除いた名称になります。
 * @default
 *
 * @param fileName
 * @text ファイル名
 * @desc フォントのファイル名です。fontフォルダ配下のwoffファイルを拡張子付きで指定してください。
 * @default
 *
 */

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

  PluginManagerEx.registerCommand(script, "CHANGE_MESSAGE_FONT", (args) => {
    $gameMessage.setFontFace(args.name);
  });

  const _Scene_Boot_loadGameFonts = Scene_Boot.prototype.loadGameFonts;
  Scene_Boot.prototype.loadGameFonts = function () {
    _Scene_Boot_loadGameFonts.apply(this, arguments);
    param.fontList.forEach((font) => {
      const name = font.name || font.fileName.replace(/\..*/, "");
      FontManager.load(name, font.fileName);
    });
  };

  const _Window_Message_newPage = Window_Message.prototype.newPage;
  Window_Message.prototype.newPage = function (textState) {
    _Window_Message_newPage.apply(this, arguments);
    if ($gameMessage.getFontFace()) {
      this.contents.fontFace = $gameMessage.getFontFace();
    }
  };

  const _Window_Message_processEscapeCharacter =
    Window_Message.prototype.processEscapeCharacter;
  Window_Message.prototype.processEscapeCharacter = function (code, textState) {
    _Window_Message_processEscapeCharacter.apply(this, arguments);
    if (code === "FN") {
      const font = this.obtainEscapeParamForFontLoad(textState);
      this.contents.fontFace = font ? font : $gameSystem.mainFontFace();
    }
  };

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

  Game_Message.prototype.getFontFace = function () {
    return this._faceFace;
  };

  Game_Message.prototype.setFontFace = function (font) {
    this._faceFace = font;
  };
})();


code:
//=============================================================================
// MessageSkip.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.17.1 2024/01/14 メッセージウィンドウが表示されていないときも、スキップの解除判定が有効になるよう修正
// 1.17.0 2022/06/19 スキップモードのときは同時にイベントのFastForwardも有効になるよう仕様変更
// 1.16.1 2021/08/29 スキップ中はウィンドウ背景が変わってもウィンドウを閉じないよう修正
// 1.16.0 2021/06/15 ピクチャによるクリックは押し続けスキップの対象外とするよう仕様変更
// 1.15.1 2021/06/01 1.15.0でループボイスを再生するとオートモードで文章が送られなくなる問題を修正
// 1.15.0 2021/05/31 SimpleVoice.jsと併用したとき、ボイス演奏中はオートモードによる文章送りを待機するよう変更
// 1.14.1 2020/10/15 ヘルプに注釈を追加
// 1.14.0 2020/08/02 クリックすることで任意のスイッチをONにできるピクチャをメッセージウィンドウに表示する機能を追加
// 1.13.0 2020/03/26 オート、スキップピクチャの表示方法をメッセージウィンドウからの相対座標と絶対座標とを選択できる機能を追加
// 1.12.1 2020/03/25 アイコン表示位置をメッセージウィンドウの位置やサイズの変更に追従するよう修正
// 1.12.0 2019/05/26 オート、スキップアイコンの位置を自由に指定できる機能を追加
// 1.11.0 2018/06/16 オート及びスキップの機能を一時的に無効化するスイッチを追加
// 1.10.1 2018/05/07 オートモードで途中に「\!」が含まれる場合の待機フレームが正しく計算されない問題を修正
// 1.10.0 2018/05/01 スキップモードとオートモードをスイッチで自動制御できる機能を追加
// 1.9.0 2018/02/18 イベント終了時にオート、スキップを解除するかどうかを任意のスイッチで判定できるように仕様変更
// 1.8.0 2018/02/16 オート待機フレーム数の計算式にウィンドウに表示した文字数を組み込める機能を追加
// 1.7.0 2017/12/12 SkipAlreadyReadMessage.jsとの連携したときに当プラグインのスキップ機能が既読スキップになるよう修正
//                  スキップピクチャの条件スイッチが0(指定なし)のときに同ピクチャが表示されない問題を修正
// 1.6.1 2017/09/21 オートモード時 改ページを伴わない入力待ちの後のメッセージを一瞬でスキップする問題を修正(by DarkPlasmaさん)
// 1.6.0 2017/08/03 キーを押している間だけスキップが有効にできる機能を追加
// 1.5.0 2017/05/27 オートおよびスキップボタンの原点指定と表示可否を変更できるスイッチの機能を追加
// 1.4.0 2017/05/26 クリックでオートおよびスキップを切り替えるボタンを追加
// 1.3.1 2017/05/13 アイコンの量を増やしたときにオートとスキップのアイコンが正常に表示されない問題を修正
// 1.3.0 2017/05/05 スキップ中はメッセージのウェイトを無視するよう修正
// 1.2.0 2017/04/29 並列実行のイベントでも通常イベントが実行中でなければスキップを解除するよう修正
//                  キーコードの「右」と「上」が逆になっていた問題を修正
//                  オート待機フレームを制御文字を使って動的に変更できる機能を追加
// 1.1.0 2016/12/14 並列処理イベントが実行されている場合にスキップが効かなくなる問題を修正
// 1.0.1 2016/02/15 モバイル端末での動作が遅くなる不具合を修正
// 1.0.0 2016/01/15 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc MessageSkipPlugin
 * @author triacontane
 *
 * @param SkipKey
 * @desc メッセージスキップに該当するキー(controlを選択するとAltキーも対象に含まれます)
 * (キーのアルファベット/shift/control/tab)
 * @default S
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option S
 *
 * @param AutoKey
 * @desc メッセージオートに該当するキー(controlを選択するとAltキーも対象に含まれます)
 * (キーのアルファベット/shift/control/tab)
 * @default A
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option A
 *
 * @param SkipSwitchId
 * @desc 指定した番号のスイッチがONになっている場合は常にスキップします。
 * @default 0
 * @type switch
 *
 * @param AutoSwitchIId
 * @desc 指定した番号のスイッチがONになっている場合は常にオートします。スキップが優先されます。
 * @default 0
 * @type switch
 *
 * @param SkipIcon
 * @desc メッセージスキップ中にウィンドウ右下に表示されるアイコン
 * @default 140
 * @type number
 *
 * @param AutoIcon
 * @desc メッセージオート中にウィンドウ右下に表示されるアイコン
 * @default 75
 * @type number
 *
 * @param IconX
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param IconY
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param PressingSkip
 * @desc スキップの判定が指定のキーを押している間のみになります。
 * @default false
 * @type boolean
 *
 * @param AutoWaitFrame
 * @desc オートモードが有効の場合にメッセージを表示しておくフレーム数。制御文字\v[n]および計算式が指定できます。
 * @default 100 + textSize * 10
 *
 * @param ResetOnEndSwitch
 * @desc 指定した番号のスイッチがONのとき、イベント終了時にスキップ、オート状態を解除します。0の場合は常に解除します。
 * @default 0
 * @type switch
 *
 * @param SkipPicture
 * @desc ウィンドウ内に表示するスキップピクチャのファイル名です。クリックするとスキップモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param SkipPictureX
 * @desc ウィンドウ内に表示するスキップピクチャのX座標です。
 * @default 500
 * @type number
 *
 * @param SkipPictureY
 * @desc ウィンドウ内に表示するスキップピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param AutoPicture
 * @desc ウィンドウ内に表示するオートピクチャのファイル名です。クリックするとオートモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param AutoPictureX
 * @desc ウィンドウ内に表示するオートピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param AutoPictureY
 * @desc ウィンドウ内に表示するオートピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param SwitchPicture
 * @desc ウィンドウ内に表示するスイッチピクチャのファイル名です。クリックすると指定したスイッチがONになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param SwitchPictureTrigger
 * @desc スイッチピクチャをクリックしたときにONにするスイッチ番号です。
 * @default 0
 * @type switch
 *
 * @param SwitchPictureX
 * @desc ウィンドウ内に表示するスイッチピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param SwitchPictureY
 * @desc ウィンドウ内に表示するスイッチピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param PictureSwitchId
 * @desc 指定した番号のスイッチがONのときのみスキップ、オートの各ピクチャボタンを表示します。0の場合は無条件で表示します。
 * @default 0
 * @type switch
 *
 * @param PictureAnchor
 * @desc スキップ、オートの各ピクチャボタン座標の原点です。（0:左上、1:右上、2:左下、3:右下）
 * @default 0
 * @type select
 * @option 0
 * @option 1
 * @option 2
 * @option 3
 *
 * @param PicturePosType
 * @desc オート、スキップピクチャの配置方法です。相対座標を選択するとウィンドウ表示位置からの相対座標となります。
 * @default relative
 * @type select
 * @option absolute
 * @option relative
 *
 * @param InvalidSwitchId
 * @desc 指定したスイッチがONのときプラグインの全機能が無効になります。
 * @default 0
 * @type switch
 *
 * @help メッセージウィンドウでメッセージのスキップやオートモードの切替ができます。
 * イベントが終了すると自働でスキップやオートモードは解除されます。
 * 並列実行イベントは、通常イベントが実行中でない場合のみ解除されます。
 * 明示的に解除したい場合は、以下のスクリプトを実行してください。
 *
 * $gameMessage.clearSkipInfo();
 *
 * ・SkipAlreadyReadMessage.jsとの連携
 * SkipAlreadyReadMessage.js（奏ねこま様作）と併用したときに
 * 当プラグインのスキップ機能は「既読スキップ」機能になります。
 * http://makonet.sakura.ne.jp/rpg_tkool/
 *
 * ・パラメータ「オート待機フレーム」を設定するとオートモード時の待機フレームを変更できます。
 * 制御文字\v[n]のほか、JavaScript計算式が使えます。
 * さらにtextSizeで表示文字数を計算式に組み込むことができます。
 *
 * 指定例：
 * 100 + textSize * 10
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * This plugin is released under the MIT License.
 */

/*:ja
 * @plugindesc メッセージスキッププラグイン
 * @author トリアコンタン
 *
 * @param スキップキー
 * @desc メッセージスキップに該当するキー
 * (キーのアルファベット/shift/control/tab)
 * @default S
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option S
 *
 * @param オートキー
 * @desc メッセージオートに該当するキー
 * (キーのアルファベット/shift/control/tab)
 * @default A
 * @type select
 * @option shift
 * @option control
 * @option tab
 * @option A
 *
 * @param スキップスイッチ
 * @desc 指定した番号のスイッチがONになっている場合は常にスキップします。
 * @default 0
 * @type switch
 *
 * @param オートスイッチ
 * @desc 指定した番号のスイッチがONになっている場合は常にオートします。スキップが優先されます。
 * @default 0
 * @type switch
 *
 * @param スキップアイコン
 * @desc メッセージスキップ中にウィンドウ右下に表示されるアイコン
 * @default 140
 * @type number
 *
 * @param オートアイコン
 * @desc メッセージオート中にウィンドウ右下に表示されるアイコン
 * @default 75
 * @type number
 *
 * @param アイコンX
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param アイコンY
 * @desc オート、スキップのアイコン位置を自由に変更したい場合に指定するX座標です。
 * @default 0
 * @type number
 * @min -2000
 * @max 2000
 *
 * @param 押し続けスキップ
 * @desc スキップの判定が指定のキーを押している間のみになります。
 * @default false
 * @type boolean
 *
 * @param オート待機フレーム
 * @desc オートモードが有効の場合にメッセージを表示しておくフレーム数。制御文字\v[n]および計算式が指定できます。
 * @default 100 + textSize * 10
 *
 * @param 終了解除スイッチID
 * @desc 指定した番号のスイッチがONのとき、イベント終了時にスキップ、オート状態を解除します。0の場合は常に解除します。
 * @default 0
 * @type switch
 *
 * @param スキップピクチャ
 * @desc ウィンドウ内に表示するスキップピクチャのファイル名です。クリックするとスキップモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param スキップピクチャX
 * @desc ウィンドウ内に表示するスキップピクチャのX座標です。
 * @default 500
 * @type number
 *
 * @param スキップピクチャY
 * @desc ウィンドウ内に表示するスキップピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param オートピクチャ
 * @desc ウィンドウ内に表示するオートピクチャのファイル名です。クリックするとオートモードになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param オートピクチャX
 * @desc ウィンドウ内に表示するオートピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param オートピクチャY
 * @desc ウィンドウ内に表示するオートピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param スイッチピクチャ
 * @desc ウィンドウ内に表示するスイッチピクチャのファイル名です。クリックすると指定したスイッチがONになります。
 * @default
 * @require 1
 * @dir img/pictures/
 * @type file
 *
 * @param スイッチピクチャトリガー
 * @desc スイッチピクチャをクリックしたときにONにするスイッチ番号です。
 * @default 0
 * @type switch
 *
 * @param スイッチピクチャX
 * @desc ウィンドウ内に表示するスイッチピクチャのX座標です。
 * @default 750
 * @type number
 *
 * @param スイッチピクチャY
 * @desc ウィンドウ内に表示するスイッチピクチャのY座標です。
 * @default 0
 * @type number
 *
 * @param ボタン原点
 * @desc スキップ、オートの各ピクチャボタン座標の原点です。（0:左上、1:右上、2:左下、3:右下）
 * @default 0
 * @type select
 * @option 0
 * @option 1
 * @option 2
 * @option 3
 *
 * @param ボタン表示スイッチID
 * @desc 指定した番号のスイッチがONのときのみスキップ、オートの各ピクチャボタンを表示します。0の場合は無条件で表示します。
 * @default 0
 * @type switch
 *
 * @param ピクチャ座標タイプ
 * @desc オート、スキップピクチャの配置方法です。相対座標を選択するとウィンドウ表示位置からの相対座標となります。
 * @default relative
 * @type select
 * @option 絶対座標
 * @value absolute
 * @option 相対座標
 * @value relative
 *
 * @param 無効化スイッチ
 * @desc 指定したスイッチがONのときプラグインの全機能が無効になります。
 * @default 0
 * @type switch
 *
 * @help メッセージウィンドウでメッセージのスキップやオートモードの切替ができます。
 * イベントが終了すると自働でスキップやオートモードは解除されます。
 * 並列実行イベントは、通常イベントが実行中でない場合のみ解除されます。
 * 明示的に解除したい場合は、以下のスクリプトを実行してください。
 *
 * $gameMessage.clearSkipInfo();
 *
 * ・SkipAlreadyReadMessage.jsとの連携
 * SkipAlreadyReadMessage.js（奏ねこま様作）と併用したときに
 * 当プラグインのスキップ機能は「既読スキップ」機能になります。
 * http://makonet.sakura.ne.jp/rpg_tkool/
 *
 * ・パラメータ「オート待機フレーム」を設定するとオートモード時の待機フレームを変更できます。
 * 制御文字\v[n]のほか、JavaScript計算式が使えます。
 * さらにtextSizeで表示文字数を計算式に組み込むことができます。
 *
 * 指定例：
 * 100 + textSize * 10
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/**
 * メッセージボタンスプライト
 * @constructor
 */
function Sprite_MessageButton() {
  this.initialize.apply(this, arguments);
}

/**
 * アイコン描画用スプライト
 * @constructor
 */
function Sprite_Frame() {
  this.initialize.apply(this, arguments);
}

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

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

  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) || 0).clamp(min, max);
  };

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

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

  var isNotAString = function (args) {
    return String(args) !== args;
  };

  Number.prototype.times = function (handler) {
    var i = 0;
    while (i < this) handler.call(this, i++);
  };

  Input.keyCodeReverseMapper = {
    a: 65,
    b: 66,
    c: 67,
    d: 68,
    e: 69,
    f: 70,
    g: 71,
    h: 72,
    i: 73,
    j: 74,
    k: 75,
    l: 76,
    m: 77,
    n: 78,
    o: 79,
    p: 80,
    q: 81,
    r: 82,
    s: 83,
    t: 84,
    u: 85,
    v: 86,
    w: 87,
    x: 88,
    y: 89,
    z: 90,
    backspace: 8,
    tab: 9,
    enter: 13,
    shift: 16,
    ctrl: 17,
    alt: 18,
    pause: 19,
    esc: 27,
    space: 32,
    page_up: 33,
    page_down: 34,
    end: 35,
    home: 36,
    left: 37,
    right: 39,
    up: 38,
    down: 40,
    insert: 45,
    delete: 46,
  };
  (9).times(function (i) {
    Input.keyCodeReverseMapper[i] = i + 48;
  });
  (12).times(function (i) {
    Input.keyCodeReverseMapper["f" + (i + 1)] = i + 112;
  });

  //=============================================================================
  // パラメータの取得と整形
  //=============================================================================
  var skipKeyName = getParamString(["SkipKey", "スキップキー"]).toLowerCase();
  var skipKeyCode = Input.keyCodeReverseMapper[skipKeyName];
  var autoKeyName = getParamString(["AutoKey", "オートキー"]).toLowerCase();
  var autoKeyCode = Input.keyCodeReverseMapper[autoKeyName];
  if (skipKeyCode) {
    if (!Input.keyMapper[skipKeyCode]) {
      Input.keyMapper[skipKeyCode] = "messageSkip";
    } else {
      skipKeyName = Input.keyMapper[skipKeyCode];
    }
  }
  if (autoKeyCode) {
    if (!Input.keyMapper[autoKeyCode]) {
      Input.keyMapper[autoKeyCode] = "messageAuto";
    } else {
      autoKeyName = Input.keyMapper[autoKeyCode];
    }
  }
  var paramSkipPicture = getParamString(["SkipPicture", "スキップピクチャ"]);
  var paramSkipPictureX = getParamNumber(["SkipPictureX", "スキップピクチャX"]);
  var paramSkipPictureY = getParamNumber(["SkipPictureY", "スキップピクチャY"]);
  var paramAutoPicture = getParamString(["AutoPicture", "オートピクチャ"]);
  var paramAutoPictureX = getParamNumber(["AutoPictureX", "オートピクチャX"]);
  var paramAutoPictureY = getParamNumber(["AutoPictureY", "オートピクチャY"]);
  var paramSwitchPicture = getParamString([
    "SwitchPicture",
    "スイッチピクチャ",
  ]);
  var paramSwitchPictureX = getParamNumber([
    "SwitchPictureX",
    "スイッチピクチャX",
  ]);
  var paramSwitchPictureY = getParamNumber([
    "SwitchPictureY",
    "スイッチピクチャY",
  ]);
  var paramSwitchPictureTrigger = getParamNumber(
    ["SwitchPictureTrigger", "スイッチピクチャトリガー"],
    0
  );
  var paramPictureAnchor = getParamNumber(["PictureAnchor", "ボタン原点"]);
  var paramPictureSwitchId = getParamNumber(
    ["PictureSwitchId", "ボタン表示スイッチID"],
    0
  );
  var paramPressingSkip = getParamBoolean(["PressingSkip", "押し続けスキップ"]);
  var paramSkipSwitchId = getParamNumber(
    ["SkipSwitchId", "スキップスイッチ"],
    0
  );
  var paramAutoSwitchIId = getParamNumber(
    ["AutoSwitchIId", "オートスイッチ"],
    0
  );
  var paramInvalidSwitchId = getParamNumber(
    ["InvalidSwitchId", "無効化スイッチ"],
    0
  );
  var paramIconX = getParamNumber(["IconX", "アイコンX"], 0);
  var paramIconY = getParamNumber(["IconY", "アイコンY"], 0);
  var paramPicturePosType = getParamString([
    "PicturePosType",
    "ピクチャ座標タイプ",
  ]);

  //=============================================================================
  // Game_Message
  //  メッセージスキップ情報を保持します。
  //=============================================================================
  var _Game_Message_initialize = Game_Message.prototype.initialize;
  Game_Message.prototype.initialize = function () {
    _Game_Message_initialize.apply(this, arguments);
    this.clearSkipInfo();
    this._autoClearSkipSwitch = getParamNumber([
      "ResetOnEndSwitch",
      "終了解除スイッチID",
    ]);
  };

  Game_Message.prototype.toggleSkip = function () {
    this.setSkipFlg(!this._skipFlg);
  };

  Game_Message.prototype.toggleAuto = function () {
    SoundManager.playCursor();
    this.setAutoFlg(!this._autoFlg);
  };

  Game_Message.prototype.skipFlg = function () {
    return this._skipFlg;
  };

  Game_Message.prototype.autoFlg = function () {
    return this._autoFlg;
  };

  Game_Message.prototype.setSkipFlg = function (value) {
    //this._skipFlg = value;
    //if (this._skipFlg) this._autoFlg = false;
  };

  Game_Message.prototype.setAutoFlg = function (value) {
    if (!this._skipFlg) {
      this._autoFlg = value;
    }
  };

  Game_Message.prototype.clearSkipInfo = function () {
    this._skipFlg = false;
    this._autoFlg = false;
  };

  Game_Message.prototype.terminateEvent = function () {
    if (
      !this._autoClearSkipSwitch ||
      $gameSwitches.value(this._autoClearSkipSwitch)
    ) {
      this.clearSkipInfo();
    }
  };

  //=============================================================================
  // Game_Interpreter
  //  マップイベント終了時にメッセージスキップフラグを初期化します。
  //=============================================================================
  var _Game_Interpreter_terminate = Game_Interpreter.prototype.terminate;
  Game_Interpreter.prototype.terminate = function () {
    _Game_Interpreter_terminate.apply(this, arguments);
    if (this.isNeedClearSkip()) {
      $gameMessage.terminateEvent();
    }
  };

  Game_Interpreter.prototype.isNeedClearSkip = function () {
    return (
      ($gameMap.isMapInterpreterOf(this) || !$gameMap.isEventRunning()) &&
      this._depth === 0
    );
  };

  var _Scene_Map_isFastForward = Scene_Map.prototype.isFastForward;
  Scene_Map.prototype.isFastForward = function () {
    const result = _Scene_Map_isFastForward.apply(this, arguments);
    if (
      !result &&
      $gameMap.isEventRunning() &&
      !SceneManager.isSceneChanging()
    ) {
      return $gameMessage.skipFlg();
    }
    return result;
  };

  //=============================================================================
  // Game_Map
  //  指定されたインタプリタがマップイベントかどうかを返します。
  //=============================================================================
  Game_Map.prototype.isMapInterpreterOf = function (interpreter) {
    return this._interpreter === interpreter;
  };

  //=============================================================================
  // Window_Message
  //  メッセージスキップ状態を描画します。
  //=============================================================================
  var _Window_Message_initialize = Window_Message.prototype.initialize;
  Window_Message.prototype.initialize = function () {
    _Window_Message_initialize.apply(this, arguments);
    this.createSpriteFrame();
    this.createSpriteSkipButton();
    this.createSpriteAutoButton();
    this.createSpriteSwitchButton();
  };

  Window_Message.prototype.createSpriteFrame = function () {
    this._icon = new Sprite_Frame(ImageManager.loadSystem("IconSet"), -1);
    this.addChild(this._icon);
    this.updatePlacementIcon();
  };

  Window_Message.prototype.updatePlacementIcon = function () {
    this._icon.x = paramIconX
      ? paramIconX - this.x
      : this.width - this._icon.width;
    this._icon.y = paramIconY
      ? paramIconY - this.y
      : this.height - this._icon.height;
  };

  Window_Message.prototype.createSpriteSkipButton = function () {
    if (!paramSkipPicture) return;
    this._skipButton = new Sprite_MessageButton(paramSkipPicture);
    this.addChild(this._skipButton);
  };

  var _Window_Message_areSettingsChanged =
    Window_Message.prototype.areSettingsChanged;
  Window_Message.prototype.areSettingsChanged = function () {
    var result = _Window_Message_areSettingsChanged.apply(this, arguments);
    if ($gameMessage.skipFlg()) {
      return this._positionType !== $gameMessage.positionType();
    } else {
      return result;
    }
  };

  Window_Message.prototype.createSpriteAutoButton = function () {
    if (!paramAutoPicture) return;
    this._autoButton = new Sprite_MessageButton(paramAutoPicture);
    this.addChild(this._autoButton);
  };

  Window_Message.prototype.createSpriteSwitchButton = function () {
    if (!paramSwitchPicture) return;
    this._switchButton = new Sprite_MessageButton(paramSwitchPicture);
    this.addChild(this._switchButton);
  };

  Window_Message.prototype.getRelativeButtonX = function (originalX) {
    if (paramPictureAnchor === 1 || paramPictureAnchor === 3) {
      originalX += this.width;
    }
    if (paramPicturePosType === "absolute") {
      originalX -= this.x;
    }
    return originalX;
  };

  Window_Message.prototype.getRelativeButtonY = function (originalY) {
    if (paramPictureAnchor === 2 || paramPictureAnchor === 3) {
      originalY += this.height;
    }
    if (paramPicturePosType === "absolute") {
      originalY -= this.y;
    }
    return originalY;
  };

  var _Window_Message_startMessage = Window_Message.prototype.startMessage;
  Window_Message.prototype.startMessage = function () {
    _Window_Message_startMessage.apply(this, arguments);
    this.initializeMessageAutoCount();
  };

  Window_Message.prototype.initializeMessageAutoCount = function () {
    var textSize = 0;
    if (this._textState) {
      var index = this._textState.index;
      var text = this._textState.text;
      while (
        text[index] &&
        !(text[index] === "\x1b" && text[index + 1] === "!")
      ) {
        index++;
      }
      // use in eval
      textSize = index - this._textState.index;
    }
    var paramValue =
      convertEscapeCharacters(
        getParamString(["AutoWaitFrame", "オート待機フレーム"])
      ) || 1;

    this._messageAutoCount = eval(paramValue);
    if (ConfigManager.autoSpeed == 4) {
      this._messageAutoCount = Math.round(this._messageAutoCount / 3);
    } else if (ConfigManager.autoSpeed == 3) {
      this._messageAutoCount = Math.round(this._messageAutoCount / 2);
    } else if (ConfigManager.autoSpeed == 2) {
      this._messageAutoCount = Math.round((this._messageAutoCount * 2) / 3);
    } else if (ConfigManager.autoSpeed == 0) {
      this._messageAutoCount = Math.round((this._messageAutoCount * 3) / 2);
    }
  };

  var _Window_Message_update = Window_Message.prototype.update;
  Window_Message.prototype.update = function () {
    this.updateAutoIcon();
    return _Window_Message_update.apply(this, arguments);
  };

  var _Window_Message_updatePlacement =
    Window_Message.prototype.updatePlacement;
  Window_Message.prototype.updatePlacement = function () {
    _Window_Message_updatePlacement.apply(this, arguments);
    if (this._skipButton) {
      this.updateSkipButtonPlacement();
    }
    if (this._autoButton) {
      this.updateAutoButtonPlacement();
    }
    if (this._switchButton) {
      this.updateSwitchButtonPlacement();
    }
  };

  Window_Message.prototype.updateSkipButtonPlacement = function () {
    var x = this.getRelativeButtonX(paramSkipPictureX);
    var y = this.getRelativeButtonY(paramSkipPictureY);
    this._skipButton.move(x, y);
  };

  Window_Message.prototype.updateAutoButtonPlacement = function () {
    var x = this.getRelativeButtonX(paramAutoPictureX);
    var y = this.getRelativeButtonY(paramAutoPictureY);
    this._autoButton.move(x, y);
  };

  Window_Message.prototype.updateSwitchButtonPlacement = function () {
    var x = this.getRelativeButtonX(paramSwitchPictureX);
    var y = this.getRelativeButtonY(paramSwitchPictureY);
    this._switchButton.move(x, y);
  };

  Window_Message.prototype.updateAutoIcon = function () {
    if (this.messageSkip() && this.openness === 255) {
      this._icon.refresh(getParamNumber(["SkipIcon", "スキップアイコン"]));
      this._icon.flashSpeed = 16;
      this._icon.flash = true;
      this.updatePlacementIcon();
    } else if (this.messageAuto() && this.openness === 255) {
      this._icon.refresh(getParamNumber(["AutoIcon", "オートアイコン"]));
      this._icon.flashSpeed = 2;
      this._icon.flash = true;
      this.updatePlacementIcon();
    } else {
      this._icon.refresh(0);
      this._icon.flash = false;
    }
  };

  var _Window_Message_updateWait = Window_Message.prototype.updateWait;
  Window_Message.prototype.updateWait = function () {
    this.updateSkipAuto();
    this.updateSwitchPicture();
    if (this.messageSkip()) {
      this._waitCount = 0;
    }
    return _Window_Message_updateWait.apply(this, arguments);
  };

  Window_Message.prototype.updateSkipAuto = function () {
    if (this.isClosed() && !$gameMessage.skipFlg()) {
      return;
    }
    if (this.isAnySubWindowActive()) {
      $gameMessage.clearSkipInfo();
    } else {
      this.setSkipAutoFlagByTrigger();
      this.setSkipAutoFlagBySwitch();
    }
    this.updateSkipForSkipAlreadyReadMessage();
  };

  Window_Message.prototype.updateSwitchPicture = function () {
    if (this.isTriggeredMessageSwitchButton()) {
      $gameSwitches.setValue(paramSwitchPictureTrigger, true);
    }
  };

  Window_Message.prototype.setSkipAutoFlagByTrigger = function () {
    if (this.isTriggeredMessageSkip()) {
      if (!paramPressingSkip) {
        $gameMessage.toggleSkip();
      }
      this._pressSkipStop = false;
    } else if (this.isTriggeredMessageSkipButton()) {
      $gameMessage.toggleSkip();
      this._pressSkipStop = true;
    } else if (this.isTriggeredMessageAuto()) {
      $gameMessage.toggleAuto();
    } else if (paramPressingSkip && !this._pressSkipStop) {
      $gameMessage.setSkipFlg(this.isPressedMessageSkip());
    }
  };

  Window_Message.prototype.setSkipAutoFlagBySwitch = function () {
    if (paramInvalidSwitchId > 0 && $gameSwitches.value(paramInvalidSwitchId)) {
      $gameMessage.setSkipFlg(false);
      $gameMessage.setAutoFlg(false);
      return;
    }
    if (paramSkipSwitchId > 0) {
      $gameMessage.setSkipFlg($gameSwitches.value(paramSkipSwitchId));
    }
    if (paramAutoSwitchIId > 0) {
      $gameMessage.setAutoFlg($gameSwitches.value(paramAutoSwitchIId));
    }
  };

  // for SkipAlreadyReadMessage.js
  Window_Message.prototype.updateSkipForSkipAlreadyReadMessage = function () {
    var pluginName = "SkipAlreadyReadMessage";
    if ($gameMessage[pluginName] && !$gameMessage[pluginName].already_read) {
      $gameMessage.setSkipFlg(false);
    }
  };

  Window_Message.prototype.messageAuto = function () {
    return $gameMessage.autoFlg();
  };

  Window_Message.prototype.messageSkip = function () {
    return $gameMessage.skipFlg();
  };

  var _Window_Message_updateInput = Window_Message.prototype.updateInput;
  Window_Message.prototype.updateInput = function () {
    if (this.messageAuto() && this._messageAutoCount > 0 && this.visible)
      this._messageAutoCount--;
    return _Window_Message_updateInput.apply(this, arguments);
  };

  Window_Message.prototype.isTriggeredMessageSkip = function () {
    return Input.isTriggered("messageSkip") || Input.isTriggered(skipKeyName);
  };

  Window_Message.prototype.isPressedMessageSkip = function () {
    return Input.isPressed("messageSkip") || Input.isPressed(skipKeyName);
  };

  Window_Message.prototype.isTriggeredMessageSkipButton = function (pressed) {
    return this.isTriggeredButton(this._skipButton, pressed);
  };

  Window_Message.prototype.isTriggeredMessageAuto = function () {
    return (
      Input.isTriggered("messageAuto") ||
      Input.isTriggered(autoKeyName) ||
      this.isTriggeredMessageAutoButton()
    );
  };

  Window_Message.prototype.isTriggeredMessageAutoButton = function () {
    return this.isTriggeredButton(this._autoButton, false);
  };

  Window_Message.prototype.isTriggeredMessageSwitchButton = function () {
    return this.isTriggeredButton(this._switchButton, false);
  };

  Window_Message.prototype.isTriggeredButton = function (button, pressed) {
    if (!button) {
      return false;
    }
    var x = this.canvasToLocalX(TouchInput.x);
    var y = this.canvasToLocalY(TouchInput.y);
    return button.isTriggered(x, y, pressed);
  };

  var _Window_Message_isTriggered = Window_Message.prototype.isTriggered;
  Window_Message.prototype.isTriggered = function () {
    if (this.isTriggeredAnyButton()) {
      return false;
    }
    if (this.messageAuto() && this._messageAutoCount <= 0) {
      if (!AudioManager.isExistVoice()) {
        this.initializeMessageAutoCount();
        return true;
      }
    }
    return (
      _Window_Message_isTriggered.apply(this, arguments) || this.messageSkip()
    );
  };

  Window_Message.prototype.isTriggeredAnyButton = function () {
    return (
      this.isTriggeredMessageSkipButton() ||
      this.isTriggeredMessageAutoButton() ||
      this.isTriggeredMessageSwitchButton()
    );
  };

  var _Window_Message_startPause = Window_Message.prototype.startPause;
  Window_Message.prototype.startPause = function () {
    _Window_Message_startPause.apply(this, arguments);
    if (this.messageSkip()) this.startWait(2);
  };

  AudioManager.isExistVoice = function () {
    if (!AudioManager._voiceBuffers) {
      return false;
    }
    this.filterPlayingVoice();
    return this._voiceBuffers.some(function (buffer) {
      return !buffer._sourceNode.loop;
    });
  };

  //=============================================================================
  // Sprite_MessageButton
  //  メッセージボタン描画用スプライトです。
  //=============================================================================
  Sprite_MessageButton.prototype = Object.create(Sprite.prototype);
  Sprite_MessageButton.prototype.constructor = Sprite_MessageButton;

  Sprite_MessageButton.prototype.initialize = function (fileName) {
    Sprite.prototype.initialize.call(this);
    this.bitmap = ImageManager.loadPicture(fileName);
    this.anchor.x = 0.5;
    this.anchor.y = 0.5;
    this.visible = false;
  };

  Sprite_MessageButton.prototype.update = function () {
    Sprite.prototype.update.call(this);
    this.updateOpacity();
    this.updateVisibility();
  };

  Sprite_MessageButton.prototype.updateOpacity = function () {
    this.opacity = this.parent.openness;
  };

  Sprite_MessageButton.prototype.updateVisibility = function () {
    if (paramInvalidSwitchId > 0 && $gameSwitches.value(paramInvalidSwitchId)) {
      this.visible = false;
      return;
    }
    this.visible =
      !paramPictureSwitchId || $gameSwitches.value(paramPictureSwitchId);
  };

  Sprite_MessageButton.prototype.isTriggered = function (
    targetX,
    targetY,
    pressed
  ) {
    var realX = targetX + this._frame.width * this.anchor.x;
    var realY = targetY + this._frame.height * this.anchor.y;
    var triggeredOk = pressed
      ? TouchInput.isPressed()
      : TouchInput.isTriggered();
    return triggeredOk && this.isInSprite(realX, realY);
  };

  Sprite_MessageButton.prototype.isInSprite = function (targetX, targetY) {
    return (
      this.x <= targetX &&
      this.x + this._frame.width >= targetX &&
      this.y <= targetY &&
      this.y + this._frame.height >= targetY
    );
  };

  //=============================================================================
  // Sprite_Frame
  //  アイコン描画用スプライトです。
  //=============================================================================
  Sprite_Frame.prototype = Object.create(Sprite.prototype);
  Sprite_Frame.prototype.constructor = Sprite_Frame;

  Sprite_Frame.prototype.initialize = function (bitmap, index) {
    Sprite.prototype.initialize.call(this);
    bitmap.addLoadListener(
      function () {
        this._column = Math.floor(bitmap.width / Window_Base._iconWidth);
        this._row = Math.floor(bitmap.height / Window_Base._iconHeight);
      }.bind(this)
    );
    this.bitmap = bitmap;
    this.anchor.x = 0.5;
    this.anchor.y = 0.5;
    this.flash = false;
    this.flashSpeed = 2;
    this._flashAlpha = 0;
    this.refresh(index ? index : 0);
  };

  Sprite_Frame.prototype.refresh = function (index) {
    if (!this.bitmap.isReady()) return;
    var w = Window_Base._iconWidth;
    var h = Window_Base._iconHeight;
    this.setFrame(
      (index % this._column) * w,
      Math.floor(index / this._column) * h,
      w,
      h
    );
  };

  Sprite_Frame.prototype.update = function () {
    if (this.flash) {
      if (this._flashAlpha <= -64) this._flashAlpha = 192;
      this.setBlendColor([255, 255, 255, this._flashAlpha]);
      this._flashAlpha -= this.flashSpeed;
    }
  };
})();


code:
var Nore;
(function (Nore) {
  Game_Action.prototype.apply = function (target) {
    var result = target.result();
    this.subject().clearResult();
    result.clear();
    result.used = this.testApply(target);
    result.missed = false; //result.used && Math.random() >= this.itemHit(target);
    result.evaded = false; // !result.missed && Math.random() < this.itemEva(target);
    result.physical = this.isPhysical();
    result.drain = this.isDrain();
    if (result.isHit()) {
      if (this.item().damage.type > 0) {
        result.critical = Math.random() < this.itemCri(target);
        var value = this.makeDamageValue(target, result.critical);
        this.executeDamage(target, value);
      }
      for (var _i = 0, _a = this.item().effects; _i < _a.length; _i++) {
        var effect = _a[_i];
        this.applyItemEffect(target, effect);
      }
      this.applyItemUserEffect(target);
    }
    this.updateLastTarget(target);
  };
  Game_Action.prototype.speed = function () {
    var agi = this.subject().agi;
    var speed = agi;
    if (this.item()) {
      speed += this.item().speed;
    }
    if (this.isAttack()) {
      speed += this.subject().attackSpeed();
    }
    return speed;
  };
})(Nore || (Nore = {}));