code:
//=============================================================================
// TDDP_MouseSystemEx.js
// Version: 1.6.1
//=============================================================================

var Imported = Imported || {};
Imported.TDDP_MouseSystemEx = "1.6.1";

//=============================================================================
/*:
 * @plugindesc 1.6.1 Custom mouse cursors, highlight menu items on hover, custom event mouse interaction and much more! See Help.
 *
 * @author Tor Damian Design / Galenmereth
 *
 * @param ---Custom Cursor---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Use Custom Cursor?
 * @desc Whether you want to use a custom mouse cursor image.
 * true => ON       false => OFF
 * @default false
 *
 * @param Custom Cursor Image
 * @desc The filename for the custom cursor. It looks for this in your project's Custom Cursor Folder.
 * @default default.png
 *
 * @param Custom Cursors Folder
 * @desc The folder you wish to store the custom cursors in. Must end with a forward slash. Default: img/cursors/
 * @default img/cursors/
 *
 * @param ---Auto Change Cursors---
 * @desc Options for automatically changing the mouse cursor when hovering over events with the given event commands in them.
 * @default
 *
 * @param Show Text Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Show Text commands in them.
 *
 * @param Transfer Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Transfer Player commands in them.
 *
 * @param Change Gold Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Gold commands in them.
 *
 * @param Change Items Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Items commands in them.
 *
 * @param Change Weapons Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Weapons commands in them.
 *
 * @param Change Armors Cursor
 * @desc Automatically show this custom cursor image when hovering over events with Change Armors commands in them.
 *
 * @param ---Auto Change Icons---
 * @desc Options for automatically showing an icon when hovering over events with the given event commands in them.
 * @default
 *
 * @param Show Text Icon
 * @desc Automatically show this icon when hovering over events with Show Text commands in them.
 *
 * @param Transfer Icon
 * @desc Automatically show this icon when hovering over events with Transfer Player commands in them.
 *
 * @param Change Gold Icon
 * @desc Automatically show this icon when hovering over events with Change Gold commands in them.
 *
 * @param Change Items Icon
 * @desc Automatically show this icon when hovering over events with Change Items commands in them.
 *
 * @param Change Weapons Icon
 * @desc Automatically show this icon when hovering over events with Change Weapons commands in them.
 *
 * @param Change Armors Icon
 * @desc Automatically show this icon when hovering over events with Change Armors commands in them.
 *
 * @param ---Hover Select---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Highlight On Hover
 * @desc Highlight menu items when hovering over them with the mouse.
 * true => ON       false => OFF
 * @default false
 *
 * @param Hover SE Cooldown
 * @desc Audio cooldown (in frames) between playing Cursor SE when Highlight On Hover is set to true. Default 4.
 * @default 4
 *
 * @param ---Customizeable Notetags---
 * @desc These are options for activating events by mouse interaction instead of player character.
 * @default
 *
 * @param No Auto Cursor Notetag
 * @desc The notetag used to disable auto cursor switching on this event or event page.
 * @default no_auto_cursor!
 *
 * @param No Auto Icon Notetag
 * @desc The notetag used to disable auto icon switching on this event or event page.
 * @default no_auto_icon!
 *
 * @param Click Notetag
 * @desc The notetag used to trigger the event when it is clicked on.
 * Default: click_activate!
 * @default click_activate!
 *
 * @param Hover Notetag
 * @desc The notetag used to trigger the event when the mouse is over it.
 * Default: hover_activate!
 * @default hover_activate!
 *
 * @param Leave Notetag
 * @desc The notetag used to trigger the event when the mouse leaves it.
 * Default: leave_activate!
 * @default leave_activate!
 *
 * @param ---Mouse Icons---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Hide Cursor
 * @desc Hide the default mouse cursor when an icon is shown.
 * true => ON       false => OFF
 * @default false
 *
 * @param Icon Offset X
 * @desc The icon's offset from the mouse horizontally.
 * Default: 9
 * @default 9
 *
 * @param Icon Offset Y
 * @desc The icon's offset from the mouse vertically.
 * Default: 14
 * @default 14
 *
 * @param ---Mouse Icon Tags---
 * @desc This is a heading, no need to touch it.
 * @default
 *
 * @param Icon Tag 1
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default quest: 191
 *
 * @param Icon Tag 2
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default chest: 210
 *
 * @param Icon Tag 3
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default door: 106
 *
 * @param Icon Tag 4
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default world_map: 190
 *
 * @param Icon Tag 5
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default potion: 176
 *
 * @param Icon Tag 6
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default poison: 177
 *
 * @param Icon Tag 7
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default four_leaf_clover: 182
 *
 * @param Icon Tag 8
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default notebook: 187
 *
 * @param Icon Tag 9
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default letter: 192
 *
 * @param Icon Tag 10
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 11
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 12
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 13
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 14
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @param Icon Tag 15
 * @desc Set up an icon tag shortcut to be used with the Mouse Hover Icons notetag. See plugin Help for more information.
 * @default key: 195
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Information
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP - MouseSystem is a collection of methods for modifying mouse-based
 * interaction in your games. You can set custom mouse cursors, show icons beside
 * the mouse when hovering over events, activate events by mouse, and more.
 *
 * For updates and easy to use documentation, please go to the plugin's website:
 * http://mvplugins.tordamian.com/?p=26
 *
 * There you can also download a PDF of the documentation for offline use, and
 * having the documentation in one cleanly presented place means you can always
 * be sure it's the most recent available.
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This plugin is free for both non-commercial and commercial use. Please see
 * http://mvplugins.tordamian.com/terms-of-use for the full terms of use.
 *
 * A big thank you to Degica for making this plugin free for commercial use for
 * everyone!
 */
/*:ja
 * @plugindesc マウスカーソルのカスタム、メニューアイテムの
 * ハイライトなどを行います。詳しくはHelpをご覧ください。
 *
 * @author Tor Damian Design / Galenmereth
 *
 * @param ---Custom Cursor---
 * @desc カーソルをカスタムするオプションです。(見出しのため変更不要)
 * @default
 *
 * @param Use Custom Cursor?
 * @desc カスタムマウスカーソル画像を利用するかどうか選択します。
 * true => ON       false => OFF
 * @default false
 *
 * @param Custom Cursor Image
 * @desc カスタムカーソルのファイル名です。プロジェクト内のカスタムカーソルフォルダで、このファイル名を探します。
 * @default default.png
 *
 * @param Custom Cursors Folder
 * @desc カスタムカーソルを入れておきたいフォルダです。「/」で終わるように設定してください。デフォルト設定: img/cursors/
 * @default img/cursors/
 *
 * @param ---Auto Change Cursors---
 * @desc イベントのマウスオーバー時に、自動的にカーソルを変更するオプションです。(見出しのため変更不要)
 * @default
 *
 * @param Show Text Cursor
 * @desc Show Textのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
 *
 * @param Transfer Cursor
 * @desc Transfer Playerのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
 *
 * @param Change Gold Cursor
 * @desc Change Goldのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
 *
 * @param Change Items Cursor
 * @desc Change Itemsのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
 *
 * @param Change Weapons Cursor
 * @desc Change Weaponsのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
 *
 * @param Change Armors Cursor
 * @desc Change Armorsのコマンドを含むイベントにマウスオーバーした際、このカスタムカーソル画像を表示します。
 *
 * @param ---Auto Change Icons---
 * @desc イベントのマウスオーバー時に、自動的にアイコンを表示するオプションです。(見出しのため変更不要)
 * @default
 *
 * @param Show Text Icon
 * @desc Show Textのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
 *
 * @param Transfer Icon
 * @desc Transfer Playerのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
 *
 * @param Change Gold Icon
 * @desc Change Goldのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
 *
 * @param Change Items Icon
 * @desc Change Itemsのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
 *
 * @param Change Weapons Icon
 * @desc Change Weaponsのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
 *
 * @param Change Armors Icon
 * @desc Change Armorsのコマンドを含むイベントにマウスオーバーした際、このアイコンを表示します。
 *
 * @param ---Hover Select---
 * @desc マウス移動時のエフェクトを設定するオプションです。(見出しのため変更不要)
 * @default
 *
 * @param Highlight On Hover
 * @desc マウスオーバー時にメニューアイテムをハイライトします。
 * true => ON       false => OFF
 * @default false
 *
 * @param Hover SE Cooldown
 * @desc Highlight On HoverがONになっている状態で、オーディオの音量を下げます。デフォルト値=4
 * @default 4
 *
 * @param ---Customizeable Notetags---
 * @desc プレイヤーキャラクターの行動によってではなく、マウスインタラクションによってイベントを発動させるオプションです。
 * @default
 *
 * @param No Auto Cursor Notetag
 * @desc イベントもしくはイベントページ上で、オートカーソルスイッチを無効化するnotetagです。
 * @default no_auto_cursor!
 *
 * @param No Auto Icon Notetag
 * @desc イベントもしくはイベントページ上で、オートアイコンスイッチを無効化するnotetagです。
 * @default no_auto_icon!
 *
 * @param Click Notetag
 * @desc クリック時にイベントを発動させるnotetagです。
 * Default: click_activate!
 * @default click_activate!
 *
 * @param Hover Notetag
 * @desc マウスオ―バー時にイベントを発動させるnotetagです。
 * Default: hover_activate!
 * @default hover_activate!
 *
 * @param Leave Notetag
 * @desc マウスが離れた時にイベントを発動させるnotetagです。
 * Default: leave_activate!
 * @default leave_activate!
 *
 * @param ---Mouse Icons---
 * @desc マウスアイコンにまつわるオプションです。(見出しのため変更不要)
 * @default
 *
 * @param Hide Cursor
 * @desc アイコン表示時に、デフォルトのマウスカーソルを隠すオプションです。
 * true => ON       false => OFF
 * @default false
 *
 * @param Icon Offset X
 * @desc マウスからアイコンの距離を設定します。(X軸)
 * Default: 9
 * @default 9
 *
 * @param Icon Offset Y
 * @desc マウスからアイコンの距離を設定します。(Y軸)
 * Default: 14
 * @default 14
 *
 * @param ---Mouse Icon Tags---
 * @desc マウスアイコンにまつわるタグです。(見出しのため変更不要)
 * @default
 *
 * @param Icon Tag 1
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default quest: 191
 *
 * @param Icon Tag 2
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default chest: 210
 *
 * @param Icon Tag 3
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default door: 106
 *
 * @param Icon Tag 4
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default world_map: 190
 *
 * @param Icon Tag 5
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default potion: 176
 *
 * @param Icon Tag 6
 * @desc Mouse Hover Iconsnotetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default poison: 177
 *
 * @param Icon Tag 7
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default four_leaf_clover: 182
 *
 * @param Icon Tag 8
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default notebook: 187
 *
 * @param Icon Tag 9
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default letter: 192
 *
 * @param Icon Tag 10
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default key: 195
 *
 * @param Icon Tag 11
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default key: 195
 *
 * @param Icon Tag 12
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default key: 195
 *
 * @param Icon Tag 13
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default key: 195
 *
 * @param Icon Tag 14
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default key: 195
 *
 * @param Icon Tag 15
 * @desc Mouse Hover Icons notetagと合わせて使用するため、アイコンタグのショートカットを設定します。
 * @default key: 195
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Information
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP - MouseSystemは、ゲーム内でのマウスを用いた
 * 様々なアクションを可能にするプラグインです。
 * マウスカーソル自体のカスタマイズや、イベントマウスオーバー時のアイコン表示、
 * マウスでのイベントの発動などを行なうことができます。
 *
 * アップデートと簡易使用方法については、
 * こちらのプラグインのサイトを参照してください。
 * http://mvplugins.tordamian.com/?p=26
 * このサイトでは、オフラインで使用するためのPDFをダウンロードすることができます。
 * またいつでも最新版の確認を行なうことができます。
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * このプラグインは、商用利用・非商用利用どちらにもフリーで公開されています。
 * 使用方法の全文についてはこちらのサイトを確認してください。
 * http://mvplugins.tordamian.com/terms-of-use
 *
 * 最後に、このプラグインのフリーでの商用利用を実現してくれた
 * Degicaさんに感謝の意を表します。
 */
//=============================================================================
// All anonymous/helper functions are registered on this object for the convenience of other plugins.
var TDDP_MouseSystemEx = {};
(function () {
  "use strict";
  /**
   * Return .png if no file extension present in filename
   */
  TDDP_MouseSystemEx._ext = function (filename) {
    if (String(filename).split(".").length > 1) {
      return filename;
    } else {
      // Default filetype extension
      return filename + ".png";
    }
  };
  //=============================================================================
  // Setting up parameters
  //=============================================================================
  var parameters = PluginManager.parameters("TDDP_MouseSystemEx");
  // Auto change cursors
  TDDP_MouseSystemEx.showTextCursor =
    String(parameters["Show Text Cursor"]) || false;
  TDDP_MouseSystemEx.changeGoldCursor =
    String(parameters["Change Gold Cursor"]) || false;
  TDDP_MouseSystemEx.changeItemCursor =
    String(parameters["Change Items Cursor"]) || false;
  TDDP_MouseSystemEx.changeWeaponCursor =
    String(parameters["Change Weapons Cursor"]) || false;
  TDDP_MouseSystemEx.changeArmorCursor =
    String(parameters["Change Armors Cursor"]) || false;
  TDDP_MouseSystemEx.transferPlayerCursor =
    String(parameters["Transfer Cursor"]) || false;
  // Auto change icons
  TDDP_MouseSystemEx.showTextIcon =
    String(parameters["Show Text Icon"]) || false;
  TDDP_MouseSystemEx.changeGoldIcon =
    String(parameters["Change Gold Icon"]) || false;
  TDDP_MouseSystemEx.changeItemIcon =
    String(parameters["Change Items Icon"]) || false;
  TDDP_MouseSystemEx.changeWeaponIcon =
    String(parameters["Change Weapons Icon"]) || false;
  TDDP_MouseSystemEx.changeArmorIcon =
    String(parameters["Change Armors Icon"]) || false;
  TDDP_MouseSystemEx.transferPlayerIcon =
    String(parameters["Transfer Icon"]) || false;
  // Settings
  TDDP_MouseSystemEx.highlightOnHover = Boolean(
    parameters["Highlight On Hover"] === "true" || false
  );
  TDDP_MouseSystemEx.audioCooldownOnHover = Number(
    parameters["Hover SE Cooldown"] || 4
  );
  TDDP_MouseSystemEx.hideCursor = Boolean(
    parameters["Hide Cursor"] === "true" || false
  );
  TDDP_MouseSystemEx.iconOffsetX = Number(parameters["Icon Offset X"]) || 0;
  TDDP_MouseSystemEx.iconOffsetY = Number(parameters["Icon Offset Y"]) || 0;
  TDDP_MouseSystemEx.noAutoCursorNotetag = String(
    parameters["No Auto Cursor Notetag"]
  );
  TDDP_MouseSystemEx.noAutoIconNotetag = String(
    parameters["No Auto Icon Notetag"]
  );
  TDDP_MouseSystemEx.clickToActivateNote = String(parameters["Click Notetag"]);
  TDDP_MouseSystemEx.hoverToActivateNote = String(parameters["Hover Notetag"]);
  TDDP_MouseSystemEx.leaveToActivateNote = String(parameters["Leave Notetag"]);
  TDDP_MouseSystemEx.useCustomCursor = Boolean(
    parameters["Use Custom Cursor?"] === "true" || false
  );
  TDDP_MouseSystemEx.cursorImage = TDDP_MouseSystemEx._ext(
    String(parameters["Custom Cursor Image"])
  );
  TDDP_MouseSystemEx.defaultCursorImage = TDDP_MouseSystemEx.cursorImage;
  TDDP_MouseSystemEx.customCursorPath = String(
    parameters["Custom Cursors Folder"]
  );

  TDDP_MouseSystemEx.mouseIconTags = {};
  TDDP_MouseSystemEx._cursorFilenameInUse = null; // Helper to compare changes
  TDDP_MouseSystemEx._lastUpdateFrame = 0; // Last frame cursor got updated
  TDDP_MouseSystemEx._cssClassPrefix = "TDDP_customCursor_";

  // Add all mouse icon tags
  for (var i = 1; i <= 15; ++i) {
    var tag = parameters["Icon Tag " + i];
    if (!tag) continue;
    tag = tag.split(":");
    var key = tag[0];
    var val = tag[1].replace(" ", "");
    TDDP_MouseSystemEx.mouseIconTags[key] = val;
  }
  /**
   * Pre-cache all custom cursors when in test mode
   */
  // Check if playtest; if so, store file. If not, read stored
  TDDP_MouseSystemEx._indexFilename = "_index.json";
  if (StorageManager.isLocalMode() && Utils.isOptionValid("test")) {
    var fs = require("fs");
    // Find that relative local path, using MV's own methods
    var path = window.location.pathname.replace(
      /\/[^\/]*$/,
      "/" + TDDP_MouseSystemEx.customCursorPath
    );
    if (path.match(/^\/([A-Z]\:)/)) {
      path = path.slice(1);
    }
    path = decodeURIComponent(path);
    // Check if cursors dir exists, make if not
    if (!fs.existsSync(path)) {
      alert(
        'TDDP MouseSystemEx\nThe chosen cursor folder "' +
          TDDP_MouseSystemEx.customCursorPath +
          '" has been created for you. Please put any custom cursor image files in this folder.'
      );
      fs.mkdirSync(path);
    }
    // Read dir
    var files = fs.readdirSync(path).filter(function (v) {
      if (v != TDDP_MouseSystemEx._indexFilename && v[1]) return v;
    });
    // Store in json
    fs.writeFile(
      path + TDDP_MouseSystemEx._indexFilename,
      JSON.stringify(files),
      "utf8",
      _loadAndSetupCustomCursorCSS
    );
  } else {
    // Read stored file
    _loadAndSetupCustomCursorCSS();
  }
  /**
   * Load and setup the custom cursor CSS additions
   */
  function _loadAndSetupCustomCursorCSS() {
    var xhr = new XMLHttpRequest();
    var url =
      TDDP_MouseSystemEx.customCursorPath + TDDP_MouseSystemEx._indexFilename;
    xhr.open("GET", url);
    xhr.overrideMimeType("application/json");
    xhr.onload = function () {
      if (xhr.status < 400) {
        var dummyContainerElement = document.createElement("div");
        dummyContainerElement.id = "TDD_MS_CursorDummies";
        document.body.appendChild(dummyContainerElement);
        // Next we iterate the cached cursor list
        var classPrefix = TDDP_MouseSystemEx._cssClassPrefix;
        var cachedCursors = JSON.parse(xhr.responseText);
        for (var i = 0, max = cachedCursors.length; i < max; i++) {
          var cursor = cachedCursors[i];
          var cursorName = cursor.split(".")[0];
          var cursorPath = TDDP_MouseSystemEx.customCursorPath + cursor;
          var sheet = window.document.styleSheets[0];
          sheet.insertRule(
            "." +
              classPrefix +
              cursorName +
              " { cursor: url(../" +
              cursorPath +
              "), default; }",
            sheet.cssRules.length
          );
          // To ensure all the cursors get prefetched by browsers, we create dummy divs to hold all the styles...
          var dummyLoaderElement = document.createElement("div");
          dummyLoaderElement.id = cursorName + "_dummy";
          dummyContainerElement.appendChild(dummyLoaderElement);
          dummyLoaderElement.className = classPrefix + cursorName;
        }
      }
    };
    xhr.onerror = function () {
      //
    };
    xhr.send();
  }
  //=============================================================================
  // Game_Interpreter - register plugin commands
  //=============================================================================
  /**
   * Alias and extend pluginCommand
   */
  var Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === "SetCustomCursor")
      TDDP_MouseSystemEx._setCustomCursor(args);
    if (command === "ResetCustomCursor")
      TDDP_MouseSystemEx._resetCustomCursor();
  };
  //=============================================================================
  // Helper functions
  //=============================================================================
  /**
   * Show custom cursor
   */
  TDDP_MouseSystemEx._showCustomCursor = function (filename) {
    var filename = filename || this.cursorImage;
    document.body.className = this._cssClassPrefix + filename.split(".")[0];
  };
  /**
   * Set new default custom cursor
   */
  TDDP_MouseSystemEx._setCustomCursor = function (filename) {
    this.cursorImage = filename;
    this._showCustomCursor(TouchInput.cursorImage);
  };
  /**
   * Reset custom cursor to parameter setting defaults
   */
  TDDP_MouseSystemEx._resetCustomCursor = function () {
    this._setCustomCursor(this.defaultCursorImage);
  };
  /**
   * Show the mouse cursor
   */
  TDDP_MouseSystemEx._showMouseCursor = function () {
    if (this.useCustomCursor) {
      this._showCustomCursor();
    } else {
      document.body.style.cursor = "inherit";
    }
  };
  /**
   * Hide the mouse cursor
   */
  TDDP_MouseSystemEx._hideMouseCursor = function () {
    document.body.style.cursor = "none";
  };
  /**
   * Return Comments from event page. Multiline comments require an additional check (408)
   */
  TDDP_MouseSystemEx._filterComments = function (pageListObject) {
    var comments =
      pageListObject.code == 108 || pageListObject.code == 408 ? true : false;
    return comments;
  };
  /**
   * Return Show Text messages from event page
   */
  TDDP_MouseSystemEx._filterMessages = function (pageListObject) {
    return pageListObject.code == 401;
  };
  /**
   * Return Transfer Player events from event page
   */
  TDDP_MouseSystemEx._filterTransferPlayer = function (pageListObject) {
    return pageListObject.code == 201;
  };
  /**
   * Return Change Gold events from event page
   */
  TDDP_MouseSystemEx._filterChangeGold = function (pageListObject) {
    return pageListObject.code == 125;
  };
  /**
   * Return Change Items events from event page
   */
  TDDP_MouseSystemEx._filterChangeItems = function (pageListObject) {
    return pageListObject.code == 126;
  };
  /**
   * Return Change Weapons events from event page
   */
  TDDP_MouseSystemEx._filterChangeWeapons = function (pageListObject) {
    return pageListObject.code == 127;
  };
  /**
   * Return Change Armors events from event page
   */
  TDDP_MouseSystemEx._filterChangeArmors = function (pageListObject) {
    return pageListObject.code == 128;
  };
  /**
   * Check if current scene is of the type Scene_Map
   */
  TDDP_MouseSystemEx._isSceneMap = function () {
    return SceneManager._scene instanceof Scene_Map;
  };
  /**
   * Find a given notetag either in a game_event's Note box or Comment box on current active page
   */
  TDDP_MouseSystemEx._findInEventNotetags = function (
    game_event,
    notetag,
    onMatch
  ) {
    if (!game_event.page()) return false;
    var comments = game_event.page().list.filter(this._filterComments);
    var result = null;
    var foundMatch = false;
    var matchInString = function (string) {
      result = string.match(notetag);
      if (result !== null) {
        foundMatch = true;
      }
    };
    // First see if there's a relevant page comment, has higher priority
    if (comments.length > 0) {
      comments.forEach(function (comment) {
        if (foundMatch) return;
        matchInString(comment.parameters[0]);
      });
    }
    // If nothing found in page comment, check Note box
    if (!foundMatch) {
      if (game_event.event().note) {
        matchInString(game_event.event().note);
      }
    }
    if (foundMatch) {
      onMatch.call(game_event, result);
    }
  };
  /**
   * Arrays of pairs of cursors/icons and filters to run to check if they should be used
   */
  TDDP_MouseSystemEx.autoCursorFilters = [
    // The order is the priority; the first match stops further lookup
    [
      TDDP_MouseSystemEx.transferPlayerCursor,
      TDDP_MouseSystemEx._filterTransferPlayer,
    ],
    [TDDP_MouseSystemEx.changeGoldCursor, TDDP_MouseSystemEx._filterChangeGold],
    [
      TDDP_MouseSystemEx.changeItemCursor,
      TDDP_MouseSystemEx._filterChangeItems,
    ],
    [
      TDDP_MouseSystemEx.changeWeaponCursor,
      TDDP_MouseSystemEx._filterChangeWeapons,
    ],
    [
      TDDP_MouseSystemEx.changeArmorCursor,
      TDDP_MouseSystemEx._filterChangeArmors,
    ],
    [TDDP_MouseSystemEx.showTextCursor, TDDP_MouseSystemEx._filterMessages],
  ];
  TDDP_MouseSystemEx.autoIconFilters = [
    // The order is the priority; the first match stops further lookup
    [
      TDDP_MouseSystemEx.transferPlayerIcon,
      TDDP_MouseSystemEx._filterTransferPlayer,
    ],
    [TDDP_MouseSystemEx.changeGoldIcon, TDDP_MouseSystemEx._filterChangeGold],
    [TDDP_MouseSystemEx.changeItemIcon, TDDP_MouseSystemEx._filterChangeItems],
    [
      TDDP_MouseSystemEx.changeWeaponIcon,
      TDDP_MouseSystemEx._filterChangeWeapons,
    ],
    [
      TDDP_MouseSystemEx.changeArmorIcon,
      TDDP_MouseSystemEx._filterChangeArmors,
    ],
    [TDDP_MouseSystemEx.showTextIcon, TDDP_MouseSystemEx._filterMessages],
  ];
  /**
   * Function to check whether conditions are prime to check for events under the mouse
   */
  TDDP_MouseSystemEx.conditionsValidForMouseHoverCheck = function () {
    return (
      SceneManager.isCurrentSceneStarted() &&
      this._isSceneMap() &&
      $gameMap !== null &&
      $dataMap !== null &&
      !$gameMap._interpreter.isRunning()
    );
  };
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // START - Highlight On Hover option
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  if (TDDP_MouseSystemEx.highlightOnHover) {
    //=========================================================================
    // TouchInput modifications
    //=========================================================================
    /**
     * Removing the check for whether _mousePressed is active to facilitate hover events
     */
    TouchInput._onMouseMove = function (event) {
      var x = Graphics.pageToCanvasX(event.pageX);
      var y = Graphics.pageToCanvasY(event.pageY);
      this._onMove(x, y);
    };
    //=========================================================================
    // Window_Selectable modifications
    //=========================================================================
    /**
     * Aliased update function, adds processMouseMoved() call
     */
    var _Window_Selectable_update = Window_Selectable.prototype.update;
    Window_Selectable.prototype.update = function () {
      this.processMouseMoved();
      _Window_Selectable_update.call(this);
    };
    /**
     * Check if conditions are right for calling onTouch when using mouse movement (for hover activation)
     */
    Window_Selectable.prototype.processMouseMoved = function () {
      if (
        this.isOpenAndActive() &&
        TouchInput.isMoved() &&
        this.cursorIsWithinWindow()
      ) {
        this.onTouch(false);
      }
    };
    /**
     * Check if cursor is within window
     */
    Window_Selectable.prototype.cursorIsWithinWindow = function () {
      var _x = this.canvasToLocalX(TouchInput.x);
      var _y = this.canvasToLocalY(TouchInput.y);
      if (_x > this.padding && _x <= this.width - this.padding) {
        if (_y > this.padding && _y < this.height - this.padding) {
          return true;
        }
      }
      return false;
    };

    //=============================================================================
    // SoundManager modifications
    //=============================================================================
    /*
     * Static var to keep track of last played cursor SE frame
     */
    SoundManager._lastPlayCursorFrame = 0;
    /**
     * Aliased function to add check for whether playCursor should play, based on cooldown setting
     */
    var _SoundManager_playCursor = SoundManager.playCursor;
    SoundManager.playCursor = function () {
      var _canPlay =
        SoundManager._lastPlayCursorFrame > Graphics.frameCount ||
        Graphics.frameCount >
          SoundManager._lastPlayCursorFrame +
            TDDP_MouseSystemEx.audioCooldownOnHover;

      if (_canPlay) {
        _SoundManager_playCursor.call(this);
        SoundManager._lastPlayCursorFrame = Graphics.frameCount;
      }
    };
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // END - Highlight On Hover option
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //=============================================================================
  // TouchInput modifications
  //=============================================================================
  /**
   * Alias and extend initialize() with _setupCursorIconObject()
   */
  var _TouchInput_initialize = TouchInput.initialize;
  TouchInput.initialize = function () {
    this._setupCursorIconObject();
    _TouchInput_initialize.call(this);
  };
  /**
   * Setup cursorIcon object
   */
  TouchInput._setupCursorIconObject = function () {
    this.cursorIcon = new Sprite();
    this.cursorIcon.drawIcon = Window_Base.prototype.drawIcon;
    this.cursorIcon.bitmap = new Bitmap(
      Window_Base._iconWidth,
      Window_Base._iconHeight
    );
    this.cursorIcon.contents = this.cursorIcon.bitmap;
    this.cursorIcon.iconIndex = null;
  };
  /**
   * Alias and extend _onMouseMove() to use new function _checkCursorStatus()
   */
  var _TouchInput_onMouseMove = TouchInput._onMouseMove;
  TouchInput._onMouseMove = function (event) {
    _TouchInput_onMouseMove.call(this, event);
    this._checkCursorStatus(event.pageX, event.pageY);
  };
  /**
   * Check cursor's status and whether to alter cursor
   */
  TouchInput._checkCursorStatus = function (pageX, pageY) {
    // Check for events under mouse and perform actions, and get event in result
    var overEvent = this._checkForEventUnderMouse(pageX, pageY);

    // Update cursor icon position
    if (this.cursorIcon.iconIndex) {
      this.cursorIcon.x =
        Graphics.pageToCanvasX(pageX) +
        (this.cursorIcon.customOffsetX !== null
          ? this.cursorIcon.customOffsetX
          : TDDP_MouseSystemEx.iconOffsetX);
      this.cursorIcon.y =
        Graphics.pageToCanvasY(pageY) +
        (this.cursorIcon.customOffsetY !== null
          ? this.cursorIcon.customOffsetY
          : TDDP_MouseSystemEx.iconOffsetY);
      this.cursorIcon.visible = true;
    }

    // Check if leave activate is to be triggered for a previous event
    if (
      this._activeEvent &&
      this._activeEvent.TDDP_MS.leaveActivate &&
      (!overEvent || overEvent !== this._activeEvent)
    ) {
      this._activeEvent.start();
      this._activeEvent = false;
    }
    // Set active event
    this._activeEvent = overEvent || this._activeEvent;
  };
  /**
   * Alias and extend update() to store last event coords for checking if cursor has left an event
   */
  var _TouchInput_update = TouchInput.update;
  TouchInput.update = function () {
    _TouchInput_update.call(this);
    if (
      this._lastEventPageX == this._curEventPageX &&
      this._lastEventPageY == this._curEventPageY
    ) {
      this._checkCursorStatus(this._lastEventPageX, this._lastEventPageY);
    }
    this._lastEventPageX = this._curEventPageX;
    this._lastEventPageY = this._curEventPageY;
  };
  /**
   * Perform check for event under mouse and perform functions depending on parsed notetag properties
   */
  TouchInput._checkForEventUnderMouse = function (pageX, pageY) {
    this._curEventPageX = pageX;
    this._curEventPageY = pageY;
    if (TDDP_MouseSystemEx.conditionsValidForMouseHoverCheck()) {
      var x = $gameMap.canvasToMapX(Graphics.pageToCanvasX(pageX));
      var y = $gameMap.canvasToMapY(Graphics.pageToCanvasY(pageY));
      var _events = $gameMap.eventsXy(x, y);
      if (_events.length > 0) {
        var game_event = _events[_events.length - 1]; // Get topmost event
        if (game_event.TDDP_MS.hoverIcon) {
          TouchInput._updateCursorIcon(game_event.TDDP_MS.hoverIcon);
          if (TDDP_MouseSystemEx.hideCursor)
            TDDP_MouseSystemEx._hideMouseCursor();
        } else {
          TouchInput._hideCursorIcon();
        }
        if (game_event.TDDP_MS.hoverActivate && !$gameMessage.isBusy()) {
          game_event.start();
        }
        if (game_event.TDDP_MS.hideCursor) {
          TDDP_MouseSystemEx._hideMouseCursor();
        }
        if (
          game_event.TDDP_MS.customOffsetX &&
          game_event.TDDP_MS.customOffsetY
        ) {
          TouchInput.cursorIcon.customOffsetX =
            game_event.TDDP_MS.customOffsetX;
          TouchInput.cursorIcon.customOffsetY =
            game_event.TDDP_MS.customOffsetY;
        }
        if (TDDP_MouseSystemEx.useCustomCursor) {
          if (game_event.TDDP_MS.customCursor) {
            TDDP_MouseSystemEx._showCustomCursor(
              game_event.TDDP_MS.customCursor
            );
          } else {
            TDDP_MouseSystemEx._showCustomCursor();
          }
        }
        if (game_event.TDDP_MS.hoverSwitch) {
          var key = [
            $gameMap._mapId,
            game_event._eventId,
            game_event.TDDP_MS.hoverSwitch.key,
          ];
          $gameSelfSwitches.setValue(
            key,
            game_event.TDDP_MS.hoverSwitch.val === "true"
          );
        }
        return game_event;
      }
    }
    TouchInput._hideCursorIcon();
    TDDP_MouseSystemEx._showMouseCursor();
    return false;
  };
  /**
   * Update the cursor icon
   */
  TouchInput._updateCursorIcon = function (iconIndex) {
    if (this.cursorIcon.iconIndex != iconIndex) {
      this.cursorIcon.iconIndex = iconIndex;
      this.cursorIcon.contents.clear();
      this.cursorIcon.drawIcon(iconIndex, 0, 0);
      this.cursorIcon.visible = false;
    }
  };
  /**
   * Hide the cursor icon
   */
  TouchInput._hideCursorIcon = function () {
    this.cursorIcon.iconIndex = null;
    this.cursorIcon.visible = false;
    this.cursorIcon.customOffsetX = null;
    this.cursorIcon.customOffsetY = null;
  };
  /**
   * Alias and extend _onTrigger() to only fire if we're not activating on click
   */
  var _TouchInput_onTrigger = TouchInput._onTrigger;
  TouchInput._onTrigger = function (x, y) {
    if (TouchInput._activateClickEvents(x, y)) {
      $gameTemp.clearDestination(); // Invalidate destination
    } else {
      _TouchInput_onTrigger.call(this, x, y);
    }
  };
  /**
   * Activate click events if valid and return true if so
   */
  TouchInput._activateClickEvents = function (x, y) {
    var found_click_event = false;
    if (
      SceneManager.isCurrentSceneStarted() &&
      $gameMap !== null &&
      $dataMap !== null &&
      !$gameMessage.isBusy()
    ) {
      var x = $gameMap.canvasToMapX(x);
      var y = $gameMap.canvasToMapY(y);
      var _events = $gameMap.eventsXy(x, y);
      if (_events.length > 0) {
        var game_event = _events[_events.length - 1];
        if (game_event.TDDP_MS.clickActivate) {
          game_event.start();
          found_click_event = true;
        }
        if (game_event.TDDP_MS.clickSwitch) {
          var key = [
            $gameMap._mapId,
            game_event._eventId,
            game_event.TDDP_MS.clickSwitch.key,
          ];
          $gameSelfSwitches.setValue(
            key,
            game_event.TDDP_MS.clickSwitch.val === "true"
          );
          found_click_event = true;
        }
      }
    }
    return found_click_event;
  };
  //=============================================================================
  // Spriteset_Map modifications
  //=============================================================================
  /**
   * Alias and extend createScreenSprites() to also create cursor icon holder sprite
   */
  var _Spriteset_Map_createScreenSprites =
    Spriteset_Map.prototype.createScreenSprites;
  Spriteset_Map.prototype.createScreenSprites = function () {
    _Spriteset_Map_createScreenSprites.call(this);
    this.createCursorIconSprite();
  };
  /**
   * Create a container sprite for the cursor icon
   */
  Spriteset_Map.prototype.createCursorIconSprite = function () {
    this._cursorIconSprite = new Sprite();
    this._cursorIconSprite.setFrame(0, 0, Graphics.width, Graphics.height);
    this._cursorIconSprite.addChild(TouchInput.cursorIcon);
    this.addChild(this._cursorIconSprite);
  };
  //=============================================================================
  // Game_Event modifications
  //=============================================================================
  /**
   * Alias and extend setupPage() to also setup mouse system properties
   */
  var _Game_Event_setupPage = Game_Event.prototype.setupPage;
  Game_Event.prototype.setupPage = function () {
    _Game_Event_setupPage.call(this);
    this.setupMouseSystemProperties();
  };
  /**
   * Setup mouse system properties on events, for storing notetag parsing on page updates
   */
  Game_Event.prototype.setupMouseSystemProperties = function () {
    this.TDDP_MS = {};
    this.TDDP_MS.hoverIcon = false;
    this.TDDP_MS.allowAutoCursor = true;
    this.TDDP_MS.allowAutoIcon = true;
    this.TDDP_MS.clickActivate = false;
    this.TDDP_MS.hoverActivate = false;
    this.TDDP_MS.leaveActivate = false;
    this.TDDP_MS.hideCursor = false;
    this.TDDP_MS.customOffsetX = false;
    this.TDDP_MS.customOffsetY = false;
    this.TDDP_MS.customCursor = false;
    this.TDDP_MS.clickSwitch = false;
    this.TDDP_MS.hoverSwitch = false;
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      /hover_icon\s(.*?);/i,
      function (result) {
        if (!result) return;
        result = result[result.length - 1];
        if (TDDP_MouseSystemEx.mouseIconTags[result]) {
          result = TDDP_MouseSystemEx.mouseIconTags[result];
        }
        this.TDDP_MS.hoverIcon = Number(result);
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      TDDP_MouseSystemEx.noAutoCursorNotetag,
      function () {
        this.TDDP_MS.allowAutoCursor = false;
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      TDDP_MouseSystemEx.noAutoIconNotetag,
      function () {
        this.TDDP_MS.allowAutoIcon = false;
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      TDDP_MouseSystemEx.clickToActivateNote,
      function () {
        this.TDDP_MS.clickActivate = true;
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      TDDP_MouseSystemEx.hoverToActivateNote,
      function () {
        this.TDDP_MS.hoverActivate = true;
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      TDDP_MouseSystemEx.leaveToActivateNote,
      function () {
        this.TDDP_MS.leaveActivate = true;
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(this, "hide_cursor!", function () {
      this.TDDP_MS.hideCursor = true;
    });
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      /icon_offset\s(.*?)\s(.*?);/i,
      function (result) {
        this.TDDP_MS.customOffsetX = Number(result[1]);
        this.TDDP_MS.customOffsetY = Number(result[2]);
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      /hover_cursor\s(.*?);/i,
      function (result) {
        this.TDDP_MS.customCursor = result[result.length - 1];
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      /click_switch\s(.*?)\s(.*?);/i,
      function (result) {
        this.TDDP_MS.clickSwitch = {};
        this.TDDP_MS.clickSwitch.key = String(result[1]);
        this.TDDP_MS.clickSwitch.val = String(result[2]);
      }
    );
    TDDP_MouseSystemEx._findInEventNotetags(
      this,
      /hover_switch\s(.*?)\s(.*?);/i,
      function (result) {
        this.TDDP_MS.hoverSwitch = {};
        this.TDDP_MS.hoverSwitch.key = String(result[1]);
        this.TDDP_MS.hoverSwitch.val = String(result[2]);
      }
    );
    if (!this.page()) return;
    // Auto cursor checks, only if there's a page and allowed
    if (this.TDDP_MS.allowAutoCursor) {
      for (
        var i = 0, max = TDDP_MouseSystemEx.autoCursorFilters.length;
        i < max;
        i++
      ) {
        if (this.TDDP_MS.customCursor) break;
        var entry = TDDP_MouseSystemEx.autoCursorFilters[i];
        var cursor = entry[0];
        var filter = entry[1];
        if (typeof cursor == "string") {
          var matches = this.page().list.filter(filter);
          if (matches.length > 0) {
            this.TDDP_MS.customCursor = cursor;
          }
        }
      }
    }
    // Auto icon checks
    if (this.TDDP_MS.allowAutoIcon) {
      for (
        var i = 0, max = TDDP_MouseSystemEx.autoIconFilters.length;
        i < max;
        i++
      ) {
        if (this.TDDP_MS.hoverIcon) break;
        var entry = TDDP_MouseSystemEx.autoIconFilters[i];
        var icon = entry[0];
        var filter = entry[1];
        if (typeof icon == "string") {
          var matches = this.page().list.filter(filter);
          if (matches.length > 0) {
            if (isNaN(icon)) {
              // Icon is a string, so let's look in Icon Tags
              icon = TDDP_MouseSystemEx.mouseIconTags[icon];
            }
            this.TDDP_MS.hoverIcon = Number(icon);
          }
        }
      }
    }
  };
})();


code:
//=============================================================================
// TDDP_PreloadManager.js
// Version: 1.0.0
//=============================================================================

var Imported = Imported || {};
Imported.TDDP_PreloadManager = "1.0.0";

var TDDP = TDDP || {};
TDDP.PreloadManager = TDDP.PreloadManager || {};
//=============================================================================
/*:
 * @plugindesc 1.0.0 Preload resources on scene/map load as well as game boot for a smoother gameplay experience.
 *
 * @author Tor Damian Design / Galenmereth
 *
 * @param Preload System SFX
 * @desc If you want to preload all the SFX specified in the Database System tab on boot, set this to true.
 * @default false
 *
 * @param Print Debug to Console
 * @desc If you want to see debug information in the console (F8) set this to true.
 * @default false
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Introduction / Table of contents
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP PreloadManager lets you preload resources on both boot (before the
 * game title screen displays) and on map load (in between map transfers) to
 * ensure resources such as pictures, music and sound effects are preloaded
 * before called.
 *
 * By default MV will stream the resources as they are required. This plugin
 * serves as an alternative for a smoother gameplay experience at the cost of
 * more bandwidth.
 *
 * This Plugin will load all resources in all event pages on the map,
 * regardless of if they will be triggered by the player at any time or not.
 * Since page conditions cannot be predicted as they are dependent on player
 * interaction, this is a necessity to ensure the right files are ready and
 * preloaded.
 *
 * For updates and easy to use documentation, please go to the plugin's website:
 * http://mvplugins.tordamian.com/?p=29
 *
 * There you can also download a PDF of the documentation for offline use, and
 * having the documentation in one cleanly presented place means you can always
 * be sure it's the most recent available.
 *
 * Table of contents
 * -----------------
 * 1. Installation
 * 2. Advanced Configuration
 * 3. Terms & Conditions
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 1. Installation
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Drag and drop plugin .js file into your project's js/plugins folder, then
 * enable it in the editor interface.
 *
 * Make sure this plugin is placed at the top for maximum compatibility.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 2. Advanced Configuration
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * There is an advanced configuration section if you open the plugin .js file
 * in a text editor. Look for BOOT PRELOAD CONFIG -- ADVANCED USERS. This lets
 * you define resources to preload on boot manually.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 3. Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * This plugin is free for both non-commercial and commercial use. Please see
 * http://mvplugins.tordamian.com/terms-of-use for the full terms of use.
 *
 * A big thank you to Degica for making this plugin free for commercial use for
 * everyone!
 */
/*:ja
 * @plugindesc マップ/シーン切り替え時、またブート時に素材の事前ロードを行います。
 *
 * @author Tor Damian Design / Galenmereth
 *
 * @param Preload System SFX
 * @desc ブート時に、データベース上で指定された全てのSFXをプリロードしたい場合は、trueにしてください。
 * @default false
 *
 * @param Print Debug to Console
 * @desc コンソール(F8)でデバッグ情報を見たい場合は、trueにしてください。
 * @default false
 *
 * @help =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * Introduction / Table of contents
 * =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 * TDDP PreloadManagerは、画像・音楽・サウンドエフェクトのような素材を、
 * 事前にロードさせることができるプラグインです。
 * タイトル前のゲームブート時や、マップ切り替わりのロード時に、
 * 事前ローディングを可能にします。
 *
 * デフォルト設定時には、素材のストリームは要求後に行われますが、
 * このプラグインを利用することで、高帯域を使用し、
 * スムーズなゲームプレイを提供することが可能になります。
 *
 * このプラグインは、プレイヤーのアクションがトリガーとなるか否かに関わらず、
 * マップ上のすべてのイベントページで、全素材をロードします。
 * ページの条件分岐がプレイヤーのアクションに依存しないため、
 * 必ず正しいファイルがロードされるように注意してください。
 *
 * アップデートと簡易使用方法については、
 * こちらのプラグインのサイトを参照してください。
 * http://mvplugins.tordamian.com/?p=29
 *
 * このサイトでは、オフラインで使用するためのPDFをダウンロードすることができます。
 * またいつでも最新版の確認を行なうことができます。
 *
 *
 *
 * コンテンツ目次
 * -----------------
 * 1. Installation
 * 2. Advanced Configuration
 * 3. Terms & Conditions
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 1. Installation
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * プラグインの「.js」ファイルを、プロジェクト内のプラグインフォルダに
 * ドラッグ&ドロップし、エディター内で有効にしてください。
 *
 * 最大の互換性を得るため、このプラグインはトップに置くようにしてください。
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 2. Advanced Configuration
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * プラグインの「.js」ファイルを開くと、
 * アドバンスドコンフィグレーションを行うことができます。
 * BOOT PRELOAD CONFIG -- ADVANCED USERSを用いて、
 * ブート時にプリロードされる素材を手動で指定することができます。
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 3. Terms & Conditions
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * このプラグインは、商用利用・非商用利用どちらにもフリーで公開されています。
 * 使用方法の全文についてはこちらのサイトを確認してください。
 * http://mvplugins.tordamian.com/terms-of-use
 *
 * 最後に、このプラグインのフリーでの商用利用を実現してくれた
 * Degicaさんに感謝の意を表します。
 */

/*
 * =============================================================================
 * BOOT PRELOAD CONFIG -- ADVANCED USERS
 * =============================================================================
 *
 * Tip: ファイル名は省略することができます。
 * 拡張子はMVの特性に合わせ、「.png」とみなされます。
 *
 * -----------------------------------------------------------------------------
 * Image files to load on boot:
 * -----------------------------------------------------------------------------
 * Keys:
 *   animation
 *   battleback1
 *   battleback2
 *   character
 *   enemy
 *   face
 *   parallax
 *   picture
 *   svActor
 *   svEnemy
 *   system
 *   tileset
 *   title1
 *   title2
 *
 * 上記のフォルダ内に、サブフォルダを作成している場合は、
 * ファイル名にそれを付け足してください。
 * 例えば「arrow」という画像が「cursors」というサブフォルダの中に入っている場合
 * 下記のように指定してください。
 *
 * system: [
 *   "balloon",
 *   "cursors/arrow"
 * ]
 */
TDDP.bootPreloadImages = {
  /* Example
    face: [
        "Actor3"
    ],
    system: [
      "myFile",
      "subfolder/myOtherFile"
    ]
    */
};
/*
 *
 * -----------------------------------------------------------------------------
 * BGM files to load on boot
 * -----------------------------------------------------------------------------
 */
TDDP.bootPreloadBGM = [
  // "Town1"
];
/*
 *
 * -----------------------------------------------------------------------------
 * BGS files to load on boot
 * -----------------------------------------------------------------------------
 */
TDDP.bootPreloadBGS = [
  // "Quake"
];
/*
 *
 * -----------------------------------------------------------------------------
 * SFX files to load on boot.
 * -----------------------------------------------------------------------------
 */
TDDP.bootPreloadSE = [
  // "Open2"
];
/*
 *
 * -----------------------------------------------------------------------------
 * ME files to load on boot.
 * -----------------------------------------------------------------------------
 */
TDDP.bootPreloadME = [
  // "Shock1"
];
//=============================================================================
// END OF BOOT PRELOAD CONFIG
//=============================================================================
var PreloadManager;
(function () {
  //=============================================================================
  // Setting up parameters
  //=============================================================================
  var parameters = PluginManager.parameters("TDDP_PreloadManager");
  var preloadSystemSFX = Boolean(
    parameters["Preload System SFX"] === "true" || false
  );
  var debug = Boolean(parameters["Print Debug to Console"] === "true" || false);
  if (debug)
    console.log("========= TDDP PreloadManager: Debug mode on =========");

  PreloadManager = function () {
    throw new Error("This is a static class");
  };

  PreloadManager._callOnComplete = false;
  PreloadManager._filesLoaded = 0;
  PreloadManager._filesTotal = 0;
  PreloadManager._ready = false;
  PreloadManager._preloadedMaps = [];
  PreloadManager._preloadedAudio = [];

  PreloadManager.callOnComplete = function (func) {
    this._callOnComplete = func;
  };

  PreloadManager.start = function () {
    this._ready = true;
    this.controlIfReady(true);
  };

  PreloadManager.preloadImages = function (type, filename, hue) {
    if (filename.constructor === Array) {
      for (var i = 0; i < filename.length; i++) {
        this.preloadImages(type, filename[i], hue);
      }
    } else {
      if (filename.length > 0) {
        if (debug) console.log("Preloading image (" + type + "): ", filename);
        var func =
          "load" + type.charAt(0).toUpperCase() + type.substr(1).toLowerCase();
        if (typeof ImageManager[func] === "undefined") {
          e =
            "PreloadManager: " +
            type +
            " is not a valid image load key. Check your configuration.";
          Graphics.printError(e);
          throw new Error(e);
        }
        this._increaseFileNums();
        ImageManager[func](filename, hue).addLoadListener(
          this.onFileLoaded.bind(this, filename)
        );
      }
    }
  };

  PreloadManager.preloadBGM = function (audioObject) {
    this.preloadAudio("bgm", audioObject);
  };

  PreloadManager.preloadBGS = function (audioObject) {
    this.preloadAudio("bgs", audioObject);
  };

  PreloadManager.preloadSE = function (audioObject) {
    this.preloadAudio("se", audioObject);
  };

  PreloadManager.preloadME = function (audioObject) {
    this.preloadAudio("me", audioObject);
  };

  PreloadManager.preloadAudio = function (type, audioObject) {
    if (!audioObject) return;
    if (audioObject.constructor === Array) {
      for (var i = 0, max = audioObject.length; i < max; i++) {
        this.preloadAudio(type, audioObject[i]);
      }
    } else {
      if (audioObject.name.length <= 0) return;
      if (this.isAudioCached(type, audioObject.name)) {
        if (debug)
          console.log(
            type + "/" + audioObject.name + " already preloaded; skipping."
          );
        return;
      }
      this._increaseFileNums();
      var bufferObject = AudioManager.createBuffer(type, audioObject.name);
      bufferObject.addLoadListener(
        this.onFileLoaded.bind(this, bufferObject.name)
      );
      bufferObject.addErrorListener(
        this.onAudioFileError.bind(this, bufferObject)
      );
      this._cacheAudio(type, audioObject.name);
    }
  };

  PreloadManager.preloadAnimation = function (animationId) {
    var animation = $dataAnimations[animationId];
    this.preloadImages("animation", [
      animation.animation1Name,
      animation.animation2Name,
    ]);
    for (var i = 0, max = animation.timings.length; i < max; i++) {
      var se = animation.timings[i].se;
      this.preloadSE(se);
    }
  };

  PreloadManager.preloadMapResources = function (mapId) {
    this._ready = false;
    // Wait and ensure map is loaded
    if (!DataManager.isMapDataLoaded())
      return setTimeout(this.preloadMapResources.bind(this, mapId), 250);
    if (this._preloadedMaps.indexOf(mapId) > -1) {
      if (debug) console.log("Map " + mapId + " already preloaded, skipping.");
    } else {
      if (debug) console.log("Map " + mapId + " preload starting.");
      // Map is loaded, preload resources now
      this.preloadBGM($dataMap.bgm);
      this.preloadBGS($dataMap.bgs);
      this.preloadImages("battleback1", $dataMap.battleback1Name);
      this.preloadImages("battleback2", $dataMap.battleback2Name);
      this.preloadImages("parallax", $dataMap.parallaxName);
      // Cycle events and load appropriate resources
      for (var i = 0, max = $dataMap.events.length; i < max; i++) {
        var event = $dataMap.events[i];
        if (!event) continue;
        for (var p = 0, pMax = event.pages.length; p < pMax; p++) {
          var page = event.pages[p];
          // Preload character graphic for page
          this.preloadImages("character", page.image.characterName);
          for (var l = 0, lMax = page.list.length; l < lMax; l++) {
            var listEntry = page.list[l];
            this.preloadEventListEntry(listEntry);
          }
        }
      }
      this._preloadedMaps.push(mapId);
    }
    this.start(true);
  };

  PreloadManager.preloadEventListEntry = function (listEntry) {
    var code = listEntry.code;
    var parameters = listEntry.parameters;
    switch (code) {
      // Show Picture
      case 231:
        this.preloadImages("picture", parameters[1]);
        break;
      // Play BGM
      case 241:
        this.preloadBGM(parameters[0]);
        break;
      // Play BGS
      case 245:
        this.preloadBGS(parameters[0]);
        break;
      case 249:
        this.preloadME(parameters[0]);
        break;
      // Play SE
      case 250:
        this.preloadSE(parameters[0]);
        break;
      // Change Parallax
      case 284:
        this.preloadImages("parallax", parameters[0]);
        break;
      // Show Text
      case 101:
        this.preloadImages("face", parameters[0]);
        break;
      // Show Animation
      case 212:
        this.preloadAnimation(parameters[1]);
        break;
    }
  };

  PreloadManager.onFileLoaded = function (filename) {
    this._filesLoaded += 1;
    if (debug)
      console.log(
        "Loaded file: " +
          filename +
          "(" +
          this._filesLoaded +
          "/" +
          this._filesTotal +
          ")"
      );
    this.controlIfReady();
  };

  PreloadManager.onAudioFileError = function (bufferObject) {
    throw new Error("Could not load file " + bufferObject._url);
  };

  PreloadManager.controlIfReady = function (manual) {
    if (this.isReady()) {
      if (debug && !manual)
        console.log(
          "All files loaded (" +
            this._filesLoaded +
            "/" +
            this._filesTotal +
            ")"
        );
      this._filesTotal = this._filesLoaded = 0;
      if (this._callOnComplete) {
        this._callOnComplete.call();
      }
    }
  };

  PreloadManager._cacheAudio = function (path, filename) {
    this._preloadedAudio.push(path + filename);
  };

  PreloadManager.isAudioCached = function (path, filename) {
    return this._preloadedAudio.indexOf(path + filename) > -1;
  };

  PreloadManager._increaseFileNums = function () {
    this._ready = false;
    this._filesTotal += 1;
  };

  PreloadManager.isReady = function () {
    if (this._filesLoaded >= this._filesTotal) {
      if (this._ready || this._filesTotal == 0) {
        return true;
      }
    }
    return false;
  };

  //=============================================================================
  // Scene_Boot extensions
  //=============================================================================
  var Scene_Boot_prototype_create = Scene_Boot.prototype.create;
  Scene_Boot.prototype.create = function () {
    Scene_Boot_prototype_create.call(this);
    this._performPreload();
  };

  Scene_Boot.prototype._performPreload = function () {
    if (!DataManager.isDatabaseLoaded())
      return setTimeout(this._performPreload.bind(this), 5);
    if (debug)
      console.log("========= TDDP PreloadManager: Boot Preload =========");
    // Preload bootPreloadImages resources
    if (TDDP.bootPreloadImages) {
      for (var key in TDDP.bootPreloadImages) {
        if (TDDP.bootPreloadImages.hasOwnProperty(key)) {
          PreloadManager.preloadImages(key, TDDP.bootPreloadImages[key]);
        }
      }
    }
    // Preload bootPreloadBGM resources
    if (TDDP.bootPreloadBGM && TDDP.bootPreloadBGM.length > 0) {
      for (var i = 0, max = TDDP.bootPreloadBGM.length; i < max; i++) {
        PreloadManager.preloadBGM({
          name: TDDP.bootPreloadBGM[i],
          volume: 90,
          pitch: 100,
        });
      }
    }
    // Preload bootPreloadBGS resources
    if (TDDP.bootPreloadBGS && TDDP.bootPreloadBGS.length > 0) {
      for (var i = 0, max = TDDP.bootPreloadBGS.length; i < max; i++) {
        PreloadManager.preloadBGS({
          name: TDDP.bootPreloadBGS[i],
          volume: 90,
          pitch: 100,
        });
      }
    }
    // Preload bootPreloadSE resources
    if (TDDP.bootPreloadSE && TDDP.bootPreloadSE.length > 0) {
      for (var i = 0, max = TDDP.bootPreloadSE.length; i < max; i++) {
        PreloadManager.preloadSE({
          name: TDDP.bootPreloadSE[i],
          volume: 90,
          pitch: 100,
        });
      }
    }
    // Preload bootPreloadME resources
    if (TDDP.bootPreloadME && TDDP.bootPreloadME.length > 0) {
      for (var i = 0, max = TDDP.bootPreloadME.length; i < max; i++) {
        PreloadManager.preloadME({
          name: TDDP.bootPreloadME[i],
          volume: 90,
          pitch: 100,
        });
      }
    }
    // Preload system SFX if set
    if (preloadSystemSFX) {
      ("========= TDDP PreloadManager: Boot Preloading System SFX =========");
      for (var i = 0, max = $dataSystem.sounds.length; i < max; i++) {
        PreloadManager.preloadSE($dataSystem.sounds[i]);
      }
    }
    PreloadManager.start();
  };

  //=============================================================================
  // DataManager extensions
  //=============================================================================
  var DataManager_loadMapData = DataManager.loadMapData;
  DataManager.loadMapData = function (mapId) {
    if (debug)
      console.log("========= TDDP PreloadManager: Map Preload =========");
    this._preloaded = false;
    DataManager_loadMapData.call(this, mapId);
    PreloadManager.preloadMapResources(mapId);
    PreloadManager.callOnComplete(this._onPreloadDone.bind(this));
  };

  DataManager._onPreloadDone = function () {
    this._preloaded = true;
  };

  var DataManager_isMapLoaded = DataManager.isMapLoaded;
  DataManager.isMapLoaded = function () {
    return this.isMapDataLoaded() && this._preloaded;
  };

  DataManager.isMapDataLoaded = function () {
    return DataManager_isMapLoaded.call(this);
  };

  //=============================================================================
  // Scene_Base extensions
  //=============================================================================
  var Scene_Base_prototype_isReady = Scene_Base.prototype.isReady;
  Scene_Base.prototype.isReady = function () {
    if (!PreloadManager.isReady()) return false;
    return Scene_Base_prototype_isReady.call(this);
  };

  //=============================================================================
  // WebAudio extensions
  //=============================================================================
  /**
   * NEW function for adding error listener
   *
   * @method addErrorListener
   * @param {Function} listener The callback function
   */
  WebAudio.prototype.addErrorListener = function (listener) {
    this._errorListeners.push(listener);
  };
  /**
   * NEW function for calling on error listeners
   *
   * @method onError
   */
  WebAudio.prototype.onError = function () {
    while (this._errorListeners.length > 0) {
      var listener = this._errorListeners.shift();
      listener();
    }
  };
  /**
   * Clears the audio data.
   *
   * @method clear
   */
  TDDP.PreloadManager.WebAudio_clear = WebAudio.prototype.clear;
  WebAudio.prototype.clear = function () {
    TDDP.PreloadManager.WebAudio_clear.call(this);
    this._errorListeners = [];
  };
  /**
   * EXTENDED to call onError
   * @method _load
   * @param {String} url
   * @private
   */
  WebAudio.prototype._load = function (url) {
    if (WebAudio._context) {
      var xhr = new XMLHttpRequest();
      xhr.open("GET", url);
      xhr.responseType = "arraybuffer";
      xhr.onload = function () {
        if (xhr.status < 400) {
          this._onXhrLoad(xhr);
        }
      }.bind(this);
      xhr.onerror = function () {
        this._hasError = true;
        this.onError(); // NEW call
      }.bind(this);
      xhr.send();
    }
  };
  //=============================================================================
  // HTML5Audio extensions
  //=============================================================================
  /**
   * EXTENDED Clears the audio data.
   *
   * @static
   * @method clear
   */
  TDDP.PreloadManager.Html5Audio_clear = Html5Audio.clear;
  Html5Audio.clear = function () {
    TDDP.PreloadManager.Html5Audio_clear.call(this);
    this._errorListeners = [];
  };
  /**
   * EXTENDED Calls error listeners
   * @static
   * @method _onError
   * @private
   */
  TDDP.PreloadManager.Html5Audio__onError = Html5Audio._onError;
  Html5Audio._onError = function () {
    TDDP.PreloadManager.Html5Audio__onError.call(this);
    while (this._errorListeners.length > 0) {
      var listener = this._errorListeners.shift();
      listener();
    }
  };
})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// YED_Eventspassable.js
//=============================================================================

/*:ja
 * @plugindesc イベントもしくはフォロワーが他のイベントにヒットした際に、途中で停止してしまうことを防ぎます。
 */
Game_Event.prototype.isCollidedWithEvents = function (x, y) {
  var events = $gameMap.eventsXyNt(x, y);
  return events.some(function (event) {
    return event._priorityType === this._priorityType;
  });
};


code:
/*:
 * Yami Engine Delta - Hospital
 *
 * @plugindesc Provides hospital feature, where party spend their money for
 * recovery.
 * @author Yami Engine Delta [Dr.Yami]
 *
 * @param [Default Price]
 * @default
 *
 * @param HP Price
 * @desc Needed money for each missing HP point.
 * @default 10
 *
 * @param MP Price
 * @desc Needed money for each missing MP point.
 * @default 20
 *
 * @param State Price
 * @desc Needed money for removing each state.
 * @default 100
 *
 * @param [Visual Setting]
 * @default
 *
 * @param Nurse Face
 * @desc Nurse Face in Hospital Scene.
 * Faceset, Index
 * @default People4, 1
 *
 * @param Nurse Name
 * @desc Nurse Name, uses for displaying message.
 * @default Loli
 *
 * @param Nurse Message
 * @desc Nurse Greeting Message
 * @default Hello,\nHow can I halp you?
 *
 * @param Heal One Help
 * @desc Text to display on Help Window for Heal One command.
 * @default Heals members individually.
 *
 * @param Heal All Help (Treat)
 * @desc Text to display on Help Window for Heal All command if
 * someone needs treatment.
 * @default Heals all members at cost %1G.
 *
 * @param Heal All Help (Healthy)
 * @desc Text to display on Help Window for Heal All command if the
 * party is healthy.
 * @default All members are healthy.
 *
 * @param Exit Help
 * @desc Text to display on Help Window for Exit command.
 * @default Go out.
 *
 * @param Actor Help (Treat)
 * @desc Text to display on Help Window for actor selection if needs
 * treatment.
 * @default %1 needs treatment.
 *
 * @param Actor Help (Healthy)
 * @desc Text to display on Help Window for actor selection if
 * is healthy.
 * @default %1 is healthy.
 *
 * @param Heal One Command
 * @desc Text to display for Heal One Command.
 * @default Heal One
 *
 * @param Heal All Command
 * @desc Text to display for Heal All Command.
 * @default Heal All
 *
 * @param Exit Command
 * @desc Text to display for Exit Command.
 * @default Exit
 *
 * @param Text Alignment
 * @desc How to align the text for the command window.
 * left     center     right
 * @default center
 *
 * @help
 * The following are Plugin Commands you may use with events.
 *
 * Plugin Command:
 *   OpenHospital       Opens up the Hospital Scene from the field.
 */

/**
 * @namespace Hospital
 * @memberof YED
 */
/*:ja
 * Yami Engine Delta - Hospital
 *
 * @plugindesc パーティの回復、支払などの
 * 病院機能を追加することができます。
 * @author Yami Engine Delta [Dr.Yami]
 *
 * @param [Default Price]
 * @default
 *
 * @param HP Price
 * @desc HPを1回復するためにかかる費用
 * @default 10
 *
 * @param MP Price
 * @desc MPを1回復するためにかかる費用
 * @default 20
 *
 * @param State Price
 * @desc 状態異常を回復するためにかかる費用
 * @default 100
 *
 * @param [Visual Setting]
 * @default
 *
 * @param Nurse Face
 * @desc 病院のシーンで用いられるナースの顔グラフィック
 * Faceset, Index
 * @default People4, 1
 *
 * @param Nurse Name
 * @desc 表示されるナースの名前
 * @default Loli
 *
 * @param Nurse Message
 * @desc ナースの挨拶のセリフ
 * @default こんにちは、今日はどうされましたか？
 *
 * @param Heal One Help
 * @desc 個別回復のヘルプウィンドウに表示されるテキスト
 * @default メンバーを個別に回復させます
 *
 * @param Heal All Help (Treat)
 * @desc 全員回復のヘルプウィンドウに表示されるテキスト
 * @default %1Gを払ってメンバー全員を回復させます
 *
 * @param Heal All Help (Healthy)
 * @desc 全員が回復不要な際、全員回復のヘルプウィンドウに表示されるテキスト
 * @default 回復が必要なメンバーが居ません
 *
 * @param Exit Help
 * @desc 退出時のヘルプウィンドウに表示されるテキスト
 * @default 外に出る
 *
 * @param Actor Help (Treat)
 * @desc 回復が必要なアクター選択時のヘルプウィンドウに表示されるテキスト
 * @default %1は回復が必要だ
 *
 * @param Actor Help (Healthy)
 * @desc 回復が不要なアクター選択時のヘルプウィンドウに表示されるテキスト
 * @default %1は回復の必要はない
 *
 * @param Heal One Command
 * @desc 個別回復のコマンドテキスト
 * @default 1人を回復する
 *
 * @param Heal All Command
 * @desc 全員回復のコマンドテキスト
 * @default 全員を回復する
 *
 * @param Exit Command
 * @desc 退出のコマンドテキスト
 * @default Exit
 *
 * @param Text Alignment
 * @desc コマンドウィンドウでのテキストの表示位置を調整します
 * left(左)     center(中央)     right(右)
 * @default center
 *
 * @help
 * 以下は、イベントで使えるプラグインコマンドです。
 *
 * Plugin Command:
 *   OpenHospital      →フィールドから病院のシーンを開きます
 */

/**
 * @namespace Hospital
 * @memberof YED
 */

var YED = YED || {};

// init Hospital module
YED.Hospital = {};

/**
 * Contains Windows for module.
 *
 * @namespace Windows
 * @memberof YED.Hospital
 */
YED.Hospital.Windows = {};

/**
 * Contains Scenes for module.
 *
 * @namespace Scenes
 * @memberof YED.Hospital
 */
YED.Hospital.Scenes = {};

/* globals YED: false */

(function () {
  /**
   * Contains utility tools for module.
   *
   * @namespace Utils
   * @memberof YED.Hospital
   */
  var Utils = {};

  /**
   * Contains module parsed parameters.
   *
   * @type {Object}
   * @memberOf  YED.Hospital.Utils
   */
  Utils.parameters = {};

  /**
   * Process parameters function.
   * Should be called with DataManager as current object.
   *
   * @function processParameters
   * @memberof YED.Hospital.Utils
   */
  Utils.processParameters = function () {
    var parameters = PluginManager.parameters("YED_Hospital"),
      result = Utils.parameters,
      nurseFaceStr = String(parameters["Nurse Face"] || "People4, 1"),
      nurseFace = [];

    nurseFace = nurseFaceStr.split(",");

    result["HP Price"] = Number(parameters["HP Price"] || 0);
    result["MP Price"] = Number(parameters["MP Price"] || 0);
    result["State Price"] = Number(parameters["State Price"] || 0);

    result["Nurse Face"] = [nurseFace[0], Number(nurseFace[1])];
    result["Nurse Name"] = String(parameters["Nurse Name"] || "Nurse");
    result["Nurse Message"] = String(parameters["Nurse Message"] || "Hello!");

    result["Heal One Help"] = String(parameters["Heal One Help"] || "");
    result["Heal All Help (Treat)"] = //
      String(parameters["Heal All Help (Treat)"] || "");
    result["Heal All Help (Healthy)"] = //
      String(parameters["Heal All Help (Healthy)"] || "");
    result["Exit Help"] = String(parameters["Exit Help"] || "");

    result["Actor Help (Treat)"] = String(
      parameters["Actor Help (Treat)"] || ""
    );
    result["Actor Help (Healthy)"] = String(
      parameters["Actor Help (Healthy)"] || ""
    );

    result["Heal One Command"] = String(
      parameters["Heal One Command"] || "Heal One"
    );
    result["Heal All Command"] = String(
      parameters["Heal All Command"] || "Heal All"
    );
    result["Exit Command"] = String(parameters["Exit Command"] || "Exit");

    result["Text Alignment"] = String(parameters["Text Alignment"] || "center");
    result["Text Alignment"] = result["Text Alignment"].toLowerCase();
  };

  /**
   * Go to Hospital Scene.
   * Should be called with Game_Interpreter object as current object.
   *
   * @function gotoHospitalScene
   * @memberof YED.Hospital.Utils
   */
  Utils.gotoHospitalScene = function () {
    var scene = YED.Hospital.Scenes.Hospital;

    SceneManager.push(scene);
  };

  YED.Hospital.Utils = Utils;
})();

/* globals YED: false */

/**
 * Pre-processes and notetag parsing
 */
(function () {
  // shorten dependencies
  var Utils = YED.Hospital.Utils;
  // Aliasing: Scene_Boot.start
  var _Scene_Boot_start = Scene_Boot.prototype.start;

  /**
   * Extending: Scene_Boot.prototype.start
   *
   * Add notetags processing for module.
   */
  Scene_Boot.prototype.start = function () {
    _Scene_Boot_start.call(this);

    Utils.processParameters.call(DataManager);
  };
})();

/* globals YED: false */

(function () {
  /**
   * Shorten Dependencies
   */
  var Utils = YED.Hospital.Utils;

  /**
   * Calculate hospital fees for actor.
   *
   * @function external:Game_Actor#hospitalFee
   * @return {number} Total hospital fees
   */
  Game_Actor.prototype.hospitalFee = function () {
    var lostHp = Math.max(this.mhp - this._hp, 0),
      lostMp = Math.max(this.mmp - this._mp, 0),
      fee = 0,
      states = this.getHospitalStates();

    fee = lostHp * this.getHospitalHpFeeRate();
    fee += lostMp * this.getHospitalMpFeeRate();

    for (var i = 0; i < states.length; i++) {
      fee += this.getHospitalStateFeeRate(states[i].id);
    }

    return fee;
  };

  /**
   * Get hospital fee for each HP lost.
   *
   * @function external:Game_Actor#getHospitalHpFeeRate
   * @return {number} Hospital HP Fee Rate
   */
  Game_Actor.prototype.getHospitalHpFeeRate = function () {
    return Utils.parameters["HP Price"];
  };

  /**
   * Get hospital fee for each MP lost.
   *
   * @function external:Game_Actor#getHospitalMpFeeRate
   * @return {number} Hospital MP Fee Rate
   */
  Game_Actor.prototype.getHospitalMpFeeRate = function () {
    return Utils.parameters["MP Price"];
  };

  /**
   * Get hospital fee for each state to be removed.
   *
   * @function external:Game_Actor#getHospitalStateFeeRate
   * @return {number} Hospital State Fee Rate
   */
  Game_Actor.prototype.getHospitalStateFeeRate = function (stateId) {
    /* jshint unused:vars */
    return Utils.parameters["State Price"];
  };

  /**
   * Get states need to be hospitalized.
   *
   * @function external:Game_Actor#getHospitalStates
   * @return {Object[]} States Array
   */
  Game_Actor.prototype.getHospitalStates = function () {
    return this.states();
  };

  /**
   * Recover and pay the hospital fee.
   *
   * @function external:Game_Actor#hospitalize
   */
  Game_Actor.prototype.hospitalize = function () {
    this._hospitalPay();
    this._hospitalRecover();
  };

  /**
   * Check if actor is healthy.
   *
   * @function external:Game_Actor#isHealthy
   * @return {Boolean} Is healthy
   */
  Game_Actor.prototype.isHealthy = function () {
    return (
      this._hp >= this.mhp &&
      this._mp >= this.mmp &&
      this.getHospitalStates().length === 0
    );
  };

  /**
   * Check if actor needs to be hospitalized.
   *
   * @function external:Game_Actor#isHospitalizable
   * @return {Boolean} Need hospitalize
   */
  Game_Actor.prototype.isHospitalizable = function () {
    var notHealthy = !this.isHealthy(),
      enoughMoney = $gameParty.gold() >= this.hospitalFee();

    return notHealthy && enoughMoney;
  };

  /**
   * Hospital Recover method.
   *
   * @function external:Game_Actor#_hospitalRecover
   * @private
   */
  Game_Actor.prototype._hospitalRecover = function () {
    var states = this.getHospitalStates();

    for (var i = 0; i < states.length; i++) {
      this.removeState(states[i].id);
    }

    this._hp = this.mhp;
    this._mp = this.mmp;
  };

  /**
   * Hospital Paying Fee method.
   *
   * @function external:Game_Actor#_hospitalPay
   * @private
   */
  Game_Actor.prototype._hospitalPay = function () {
    $gameParty.loseGold(this.hospitalFee());
  };
})();

(function () {
  /**
   * Calculate hospital fees for the whole party.
   *
   * @function external:Game_Party#hospitalFee
   * @return {number} Total hospital fees
   */
  Game_Party.prototype.hospitalFee = function () {
    var members = this.members(),
      fee = 0;

    for (var i = 0; i < members.length; i++) {
      fee += members[i].hospitalFee();
    }

    return fee;
  };

  /**
   * Recover and pay the hospital fee.
   *
   * @function external:Game_Party#hospitalize
   */
  Game_Party.prototype.hospitalize = function () {
    var members = this.members();

    for (var i = 0; i < members.length; i++) {
      members[i].hospitalize();
    }
  };

  /**
   * Check if party is healthy.
   *
   * @function external:Game_Party#isHealthy
   * @return {Boolean} Is healthy
   */
  Game_Party.prototype.isHealthy = function () {
    var members = this.members();

    for (var i = 0; i < members.length; i++) {
      if (!members[i].isHealthy()) {
        return false;
      }
    }

    return true;
  };

  /**
   * Check if party needs to be hospitalized.
   *
   * @function external:Game_Party#isHospitalizable
   * @return {Boolean} Need hospitalize
   */
  Game_Party.prototype.isHospitalizable = function () {
    var members = this.members();

    if ($gameParty.gold() < this.hospitalFee()) {
      return false;
    }

    for (var i = 0; i < members.length; i++) {
      if (members[i].isHospitalizable()) {
        return true;
      }
    }

    return false;
  };
})();

/* globals YED: false */

(function () {
  /**
   * Window shows actors list for hospital.
   *
   * @class
   * @extends external:Window_Selectable
   * @memberof YED.Hospital.Windows
   *
   * @param {number} wx Window X
   * @param {number} wy Window Y
   * @param {number} [ww] Window Width
   * @param {number} wh Window Height
   */
  var HospitalActors = function () {
    this.initialize.apply(this, arguments);
  };

  /**
   * Inherits from Window_Base
   */
  HospitalActors.prototype = Object.create(Window_Selectable.prototype);
  HospitalActors.prototype.constructor = HospitalActors;

  /**
   * Initialize
   *
   * @constructs HospitalActors
   */
  HospitalActors.prototype.initialize = function (wx, wy, ww, wh) {
    ww = ww || this.windowWidth();

    Window_Selectable.prototype.initialize.call(this, wx, wy, ww, wh);
    this.refresh();
  };

  /**
   * Window height for initialize.
   *
   * @return {number} Window Height
   */
  HospitalActors.prototype.windowWidth = function () {
    return Graphics.boxWidth;
  };

  /**
   * Refresh Window contents.
   */
  HospitalActors.prototype.refresh = function () {
    this.makeItemList();
    this.createContents();
    this.drawAllItems();
  };

  /**
   * Get actors list.
   */
  HospitalActors.prototype.makeItemList = function () {
    this._data = $gameParty.members();
  };

  /**
   * Get current actor.
   *
   * @return {Game_Actor} Current select actor
   */
  HospitalActors.prototype.actor = function () {
    return this._data[this.index()];
  };

  /**
   * Check if current actor is hospitalizable.
   *
   * @return {Boolean} Enabled Flag
   */
  HospitalActors.prototype.isCurrentItemEnabled = function () {
    return this.isEnabled(this.actor());
  };

  /**
   * Check if current actor is hospitalizable.
   *
   * @return {Boolean} Enabled Flag
   */
  HospitalActors.prototype.isEnabled = function (actor) {
    return !!actor ? actor.isHospitalizable() : false;
  };

  /**
   * Get party current size.
   *
   * @return {number} Total actors
   */
  HospitalActors.prototype.maxItems = function () {
    return this._data ? this._data.length : 1;
  };

  /**
   * Draw actor status.
   *
   * @param  {number} index Actor Index
   */
  HospitalActors.prototype.drawItem = function (index) {
    var actor = this._data[index],
      rect = this.itemRect(index),
      gaugeWidth = 0,
      offsetX = 0;

    if (!actor) {
      return;
    }

    gaugeWidth =
      this.contentsWidth() -
      (168 * 2 + Window_Base._iconWidth * 3 + this.textPadding() * 2);
    gaugeWidth = gaugeWidth / 2 - 8;

    offsetX = this.textPadding();
    this.drawActorName(actor, rect.x + offsetX, rect.y, 168);

    offsetX = offsetX + 168;
    this.drawActorIcons(
      actor,
      rect.x + offsetX,
      rect.y,
      Window_Base._iconWidth * 3
    );

    offsetX = offsetX + Window_Base._iconWidth * 3;
    this.drawActorHp(actor, rect.x + offsetX, rect.y, gaugeWidth);

    offsetX = offsetX + gaugeWidth + 8;
    this.drawActorMp(actor, rect.x + offsetX, rect.y, gaugeWidth);

    offsetX = offsetX + gaugeWidth;
    this.drawActorHospital(actor, rect.x + offsetX, rect.y, 168);
  };

  /**
   * Draw actor hospital fees.
   *
   * @param  {Game_Actor} actor Actor
   * @param  {number} x     Draw at X
   * @param  {number} y     Draw at Y
   * @param  {number} width Limit Text Width
   */
  HospitalActors.prototype.drawActorHospital = function (actor, x, y, width) {
    width = width || 168;
    this.drawCurrencyValue(
      actor.hospitalFee(),
      this.currencyUnit(),
      x,
      y,
      width
    );
  };

  /**
   * Get currency unit.
   *
   * @return {String} Currency Unit
   */
  HospitalActors.prototype.currencyUnit = function () {
    return TextManager.currencyUnit;
  };

  /**
   * Update help window
   */
  HospitalActors.prototype.updateHelp = function () {
    var symbol = "";

    if (!this.actor()) {
      return;
    }

    symbol = this._getHelpSymbol();
    this._helpWindow.setSymbol(symbol, this.actor());
  };

  /**
   * Get text symbol for displaying help
   *
   * @private
   */
  HospitalActors.prototype._getHelpSymbol = function () {
    var symbol = "";

    if (this.actor().isHealthy()) {
      symbol = "Actor Help (Healthy)";
    } else {
      symbol = "Actor Help (Treat)";
    }

    return symbol;
  };

  YED.Hospital.Windows.HospitalActors = HospitalActors;
})();

/* globals YED: false */

(function () {
  /**
   * Shorten Dependencies
   */
  var Utils = YED.Hospital.Utils;

  /**
   * Window shows nurse face and her messages.
   *
   * @class
   * @extends external:Window_Base
   * @memberof YED.Hospital.Windows
   *
   * @param {number} wx Window X
   * @param {number} wy Window Y
   * @param {number} ww Window Width
   * @param {number} [wh] Window Height
   */
  var HospitalNurse = function () {
    this.initialize.apply(this, arguments);
  };

  /**
   * Inherits from Window_Base
   */
  HospitalNurse.prototype = Object.create(Window_Base.prototype);
  HospitalNurse.prototype.constructor = HospitalNurse;

  /**
   * Initialize
   *
   * @constructs HospitalNurse
   */
  HospitalNurse.prototype.initialize = function (wx, wy, ww, wh) {
    wh = wh || this.windowHeight();

    Window_Base.prototype.initialize.call(this, wx, wy, ww, wh);
    this.loadImages();
    this.refresh();
  };

  /**
   * Window height for initialize.
   *
   * @return {number} Window Height
   */
  HospitalNurse.prototype.windowHeight = function () {
    return this.fittingHeight(4);
  };

  /**
   * Load and cache Faceset for Nurse Face.
   */
  HospitalNurse.prototype.loadImages = function () {
    var faceName = Utils.parameters["Nurse Face"][0];

    ImageManager.loadFace(faceName);
  };

  /**
   * Refresh window contents.
   */
  HospitalNurse.prototype.refresh = function () {
    this.contents.clear();

    this._drawNurseFace();
    this._drawNurseName();
    this._drawNurseMessage();
  };

  /**
   * Draw nurse face.
   *
   * @private
   */
  HospitalNurse.prototype._drawNurseFace = function () {
    var faceName = Utils.parameters["Nurse Face"][0],
      faceIndex = Utils.parameters["Nurse Face"][1];

    this.drawFace(faceName, faceIndex, 0, 0);
  };

  /**
   * Draw nurse name.
   *
   * @private
   */
  HospitalNurse.prototype._drawNurseName = function () {
    var nurseName = Utils.parameters["Nurse Name"],
      dx = Window_Base._faceWidth + this.textPadding();

    this.drawTextEx(nurseName, dx, 0);
  };

  /**
   * Draw nurse message.
   *
   * @private
   */
  HospitalNurse.prototype._drawNurseMessage = function () {
    var nurseMessage = Utils.parameters["Nurse Message"],
      dx = Window_Base._faceWidth + this.textPadding();

    this.drawTextEx(nurseMessage, dx, this.lineHeight());
  };

  YED.Hospital.Windows.HospitalNurse = HospitalNurse;
})();

/* globals YED: false */

(function () {
  /**
   * Shorten Dependencies
   */
  var Utils = YED.Hospital.Utils;

  /**
   * Window shows commands for Hospital Scene.
   *
   * @class
   * @extends external:Window_Command
   * @memberof YED.Hospital.Windows
   *
   * @param {number} wx Window X
   * @param {number} wy Window Y
   * @param {number} [ww] Window Width
   * @param {number} [wh] Window Height
   */
  var HospitalCommand = function () {
    this.initialize.apply(this, arguments);
  };

  /**
   * Inherits from Window_Command
   */
  HospitalCommand.prototype = Object.create(Window_Command.prototype);
  HospitalCommand.prototype.constructor = HospitalCommand;

  /**
   * Initialize Window when created.
   *
   * @constructs HospitalCommand
   */
  HospitalCommand.prototype.initialize = function (wx, wy, ww, wh) {
    ww = ww || this.windowWidth();
    wh = wh || this.windowHeight();

    Window_Command.prototype.initialize.call(this, wx, wy);

    this.width = ww;
    this.height = wh;
  };

  /**
   * Window width for initialize.
   *
   * @return {number} Window Width
   */
  HospitalCommand.prototype.windowWidth = function () {
    return 240;
  };

  /**
   * Get visible rows for height setting.
   *
   * @return {number} Rows
   */
  HospitalCommand.prototype.numVisibleRows = function () {
    return 4;
  };

  /**
   * Get text align setting.
   *
   * @return {String} Align setting
   */
  HospitalCommand.prototype.itemTextAlign = function () {
    return Utils.parameters["Text Alignment"];
  };

  /**
   * Make commands list for Window.
   */
  HospitalCommand.prototype.makeCommandList = function () {
    this._addHealCommand();
    this._addCustomCommand();
    this._addExitCommand();
  };

  /**
   * Update help window
   */
  HospitalCommand.prototype.updateHelp = function () {
    var symbol = this._getHelpSymbol();
    this._helpWindow.setSymbol(symbol);
  };

  /**
   * Add heal commands to Window.
   *
   * @private
   */
  HospitalCommand.prototype._addHealCommand = function () {
    var healOneText = Utils.parameters["Heal One Command"],
      healAllText = Utils.parameters["Heal All Command"],
      enableHealAll = $gameParty.isHospitalizable();

    this.addCommand(healOneText, "healOne", true);
    this.addCommand(healAllText, "healAll", enableHealAll);
  };

  /**
   * Add custom commands (for any add-on) to Window.
   *
   * @private
   */
  HospitalCommand.prototype._addCustomCommand = function () {
    // made for future add-ons
  };

  /**
   * Add exit command to Window.
   *
   * @private
   */
  HospitalCommand.prototype._addExitCommand = function () {
    var text = Utils.parameters["Exit Command"];

    this.addCommand(text, "cancel", true);
  };

  /**
   * Get text symbol for displaying help
   *
   * @private
   */
  HospitalCommand.prototype._getHelpSymbol = function () {
    var symbol = "";

    switch (this.currentSymbol()) {
      case "healOne":
        symbol = "Heal One Help";
        break;
      case "healAll":
        if ($gameParty.isHealthy()) {
          symbol = "Heal All Help (Healthy)";
        } else {
          symbol = "Heal All Help (Treat)";
        }
        break;
      case "cancel":
        symbol = "Exit Help";
        break;
    }

    return symbol;
  };

  YED.Hospital.Windows.HospitalCommand = HospitalCommand;
})();

/* globals YED: false */

(function () {
  /**
   * Shorten Dependencies
   */
  var Utils = YED.Hospital.Utils;

  /**
   * Window shows command help.
   *
   * @class
   * @extends external:Window_Help
   * @memberof YED.Hospital.Windows
   *
   * @param {number} wx Window X
   * @param {number} wy Window Y
   * @param {number} ww Window Width
   * @param {number} [wh] Window Height
   */
  var HospitalHelp = function () {
    this.initialize.apply(this, arguments);
  };

  /**
   * Inherits from Window_Help
   */
  HospitalHelp.prototype = Object.create(Window_Help.prototype);
  HospitalHelp.prototype.constructor = HospitalHelp;

  /**
   * Initialize
   *
   * @constructs HospitalHelp
   */
  HospitalHelp.prototype.initialize = function (wx, wy, ww, wh) {
    wh = wh || this.windowHeight();

    Window_Help.prototype.initialize.call(this, 1);

    this.x = wx;
    this.y = wy;
    this.width = ww;
    this.height = wh;

    this._textSymbol = "";
    this._windowCommand = null;
    this._windowActors = null;
  };

  /**
   * Window height for initialize.
   *
   * @return {number} Window Height
   */
  HospitalHelp.prototype.windowHeight = function () {
    return this.fittingHeight(1);
  };

  /**
   * Refresh window contents.
   */
  HospitalHelp.prototype.refresh = function () {
    this.contents.clear();
    this._drawHelpText();
  };

  /**
   * Clear window contents.
   */
  HospitalHelp.prototype.clear = function () {
    this.setSymbol("");
  };

  /**
   * Set window symbol for formatting texts.
   */
  HospitalHelp.prototype.setSymbol = function (symbol, actor) {
    this._textSymbol = symbol;
    this._actor = actor;
    this.refresh();
  };

  /**
   * Get help text.
   *
   * @return {String} Help Text
   * @private
   */
  HospitalHelp.prototype._getHelpText = function () {
    var text = Utils.parameters[this._textSymbol],
      actor = this._actor;

    switch (this._textSymbol) {
      case "Heal All Help (Treat)":
        text = text.format($gameParty.hospitalFee());
        break;
      case "Actor Help (Treat)":
        text = text.format(actor.name());
        break;
      case "Actor Help (Healthy)":
        text = text.format(actor.name());
        break;
    }

    return text;
  };

  /**
   * Draw help text.
   *
   * @private
   */
  HospitalHelp.prototype._drawHelpText = function () {
    var text = "";

    if (this._textSymbol !== "") {
      text = this._getHelpText();
      this.drawTextEx(text, this.textPadding(), 0);
    }
  };

  YED.Hospital.Windows.HospitalHelp = HospitalHelp;
})();

/* globals YED: false */

(function () {
  /**
   * Shorten Dependencies
   */
  var Windows = YED.Hospital.Windows;

  /**
   * Scene for Hospital.
   *
   * @class
   * @extends external:Scene_MenuBase
   * @memberof YED.Hospital.Scenes
   */
  var Hospital = function () {
    this.initialize.apply(this, arguments);
  };

  /**
   * Inherits from Scene_MenuBase
   */
  Hospital.prototype = Object.create(Scene_MenuBase.prototype);
  Hospital.prototype.constructor = Hospital;

  /**
   * Initialize
   *
   * @constructs Hospital
   */
  Hospital.prototype.initialize = function () {
    Scene_MenuBase.prototype.initialize.call(this);
  };

  /**
   * Create Windows.
   */
  Hospital.prototype.create = function () {
    Scene_MenuBase.prototype.create.call(this);
    this._createGoldWindow();
    this._createHelpWindow();
    this._createCommandWindow();
    this._createNurseWindow();
    this._createActorsWindow();
  };

  /**
   * Refresh Windows.
   */
  Hospital.prototype.start = function () {
    Scene_MenuBase.prototype.start.call(this);
    this._nurseWindow.refresh();
  };

  /**
   * Create Gold Window.
   *
   * @private
   */
  Hospital.prototype._createGoldWindow = function () {
    this._goldWindow = new Window_Gold(0, 0);
    this._goldWindow.x = Graphics.boxWidth - this._goldWindow.width;
    this._goldWindow.y = Graphics.boxHeight - this._goldWindow.height;
    this.addWindow(this._goldWindow);
  };

  /**
   * Create Help Window.
   *
   * @private
   */
  Hospital.prototype._createHelpWindow = function () {
    var wx = 0,
      wy = this._goldWindow.y,
      ww = Graphics.boxWidth - this._goldWindow.width;

    this._helpWindow = new Windows.HospitalHelp(wx, wy, ww);
    this.addWindow(this._helpWindow);
  };

  /**
   * Create Command Window.
   *
   * @private
   */
  Hospital.prototype._createCommandWindow = function () {
    this._commandWindow = new Windows.HospitalCommand(0, 0);
    this._commandWindow.setHelpWindow(this._helpWindow);

    this._commandWindow.setHandler("healOne", this._commandHealOne.bind(this));
    this._commandWindow.setHandler("healAll", this._commandHealAll.bind(this));
    this._commandWindow.setHandler("cancel", this.popScene.bind(this));

    this.addWindow(this._commandWindow);
  };

  /**
   * Create Nurse Window.
   *
   * @private
   */
  Hospital.prototype._createNurseWindow = function () {
    var wx = this._commandWindow.width,
      wy = this._commandWindow.y,
      ww = Graphics.boxWidth - this._commandWindow.width;

    this._nurseWindow = new Windows.HospitalNurse(wx, wy, ww);
    this.addWindow(this._nurseWindow);
  };

  /**
   * Create Actors Window.
   *
   * @private
   */
  Hospital.prototype._createActorsWindow = function () {
    var wx = 0,
      wy = this._commandWindow.height,
      wh = Graphics.boxHeight - wy - this._goldWindow.height;

    this._actorsWindow = new Windows.HospitalActors(wx, wy, null, wh);
    this._actorsWindow.setHelpWindow(this._helpWindow);

    this._actorsWindow.setHandler("ok", this._onActorOk.bind(this));
    this._actorsWindow.setHandler("cancel", this._onActorCancel.bind(this));

    this.addWindow(this._actorsWindow);
  };

  /**
   * Handler for command healOne
   *
   * @private
   */
  Hospital.prototype._commandHealOne = function () {
    this._actorsWindow.activate();
    this._actorsWindow.select(0);
  };

  /**
   * Handler for command healAll
   *
   * @private
   */
  Hospital.prototype._commandHealAll = function () {
    $gameParty.hospitalize();
    this._actorsWindow.refresh();
    this._goldWindow.refresh();
    this._commandWindow.refresh();
    this._commandWindow.activate();
  };

  /**
   * Handler for actor selection.
   *
   * @private
   */
  Hospital.prototype._onActorOk = function () {
    var actor = this._actorsWindow.actor();

    if (!!actor) {
      actor.hospitalize();

      this._actorsWindow.refresh();
      this._goldWindow.refresh();
      this._commandWindow.refresh();
      this._actorsWindow.activate();
    }
  };

  /**
   * Handler for actor cancel.
   *
   * @private
   */
  Hospital.prototype._onActorCancel = function () {
    this._commandWindow.activate();
    this._actorsWindow.deselect();
  };

  YED.Hospital.Scenes.Hospital = Hospital;
})();

/* globals YED: false */

(function () {
  /**
   * Aliasing methods
   */
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;

  /**
   * Extending: Game_Interpreter.prototype.pluginCommand
   *
   * Add go to Hospital Scene Plugin Command.
   */
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    // actual initialize
    _Game_Interpreter_pluginCommand.call(this, command, args);

    // Hospital Plugin Command
    if (command === "OpenHospital") {
      YED.Hospital.Utils.gotoHospitalScene.call(this);
    }
  };
})();