code:
//=============================================================================
// Yanfly Engine Plugins - Equip Core
// YEP_EquipCore.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.Equip = Yanfly.Equip || {};
Yanfly.Equip.version = 1.18;

//=============================================================================
 /*:
 * @plugindesc v1.18 Allows for the equipment system to be more flexible to
 * allow for unique equipment slots per class.
 * @author Yanfly Engine Plugins
 *
 * @param ---General---
 * @default
 *
 * @param Text Align
 * @parent ---General---
 * @type combo
 * @option left
 * @option center
 * @option right
 * @desc How to align the text for the command window.
 * left     center     right
 * @default center
 *
 * @param Finish Command
 * @parent ---General---
 * @desc The command text used for exiting the equip scene.
 * Leave empty to not include this command.
 * @default Finish
 *
 * @param Remove Text
 * @parent ---General---
 * @desc The text used to display the "Remove" command in the equip
 * item list.
 * @default Remove
 *
 * @param Remove Icon
 * @parent ---General---
 * @type number
 * @min 0
 * @desc The icon used to display next to the "Remove" command in
 * the equip item list.
 * @default 16
 *
 * @param Empty Text
 * @parent ---General---
 * @desc The text used to display an "Empty" piece of equipment.
 * @default <Empty>
 *
 * @param Empty Icon
 * @parent ---General---
 * @type number
 * @min 0
 * @desc The icon used to display next to the "Empty" piece of
 * equipment in the equipment list.
 * @default 16
 *
 * @param ---Rules---
 * @default
 *
 * @param Non-Removable Types
 * @parent ---Rules---
 * @type number
 * @min 1
 * @max 100
 * @desc These types must always have an item equipped and cannot
 * be empty. Separate the type ID's by a space.
 * @default 1
 *
 * @param Non-Optimized Types
 * @parent ---Rules---
 * @type number
 * @min 1
 * @max 100
 * @desc These types will be ignored when the actor optimizes
 * equips. Separate the type ID's by a space.
 * @default 5
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin alters various aspects regarding equipment handling. The changes
 * are as listed:
 *
 * 1. Scene_Equip
 * Scene_Equip has been modified to look differently. This is primarily done to
 * make the main menu scenes look uniform and keep everything familiar for
 * players. Furthermore, the command window has been adjusted to be better fit
 * for extension plugins in the future that may add commands to the command
 * window and/or the scene.
 *
 * 2. Equipment Type Handling
 * Characters will no longer have one universal equipment slot setting. Now,
 * different classes can use different setups by simply adding a few notetags
 * to the class notebox. Furthermore, equipment types in the past with matching
 * names would be treated as separate types. Now, equipment types with matching
 * names will be treated as the same type.
 *
 * 3. Equipment Rulings
 * Now, certain equipment types can or cannot be removed. For example, this
 * plugin can set it so that the Weapon slot must always have something
 * equipped and that the player cannot manually leave it empty (the game, on
 * the other hand, can achieve this through events). In addition to that,
 * optimizing equipment can be restricted for certain equipment types, which
 * are better off being decided manually (such as accessories).
 *
 * 4. Parameter Control
 * Equipment parameters can now to be adjusted through notetags to have a large
 * value or customized value (through code). This allows for equipment to no
 * longer be static items, but instead, equipment can now be dynamic and may
 * change over the course of the game.
 *
 * Note: Item Core Users
 * For users using the Item Core plugin and the new Item Scene layout option,
 * the Item Info Window is now added to the Equip Scene. Pressing Left/Right
 * will toggle the stat comparison window with the info window. Pressing Tab on
 * the keyboard will also switch them as well as clicking on those windows.
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * You can use the following notetags to change a class's equipment setup.
 *
 * Class Notetags:
 *   <Equip Slot: x>      Example: <Equip Slot: 1, 2, 3, 4, 5, 5, 5, 5>
 *   <Equip Slot: x, x, x>
 *   Changes this class's equipment slots to x. Using repeating numbers makes
 *   it so that equipment type is duplicated and that the class can equip
 *   multiple equipment of that type. To find the Equipment Type ID, go to your
 *   database's Types tab and look for the ID type.
 *
 *   If you don't like the above method for setting equipment slots, you can
 *   use the following notetags instead:
 *
 *   <Equip Slot>         Example: <Equip Slot>
 *    string                        Weapon
 *    string                        Armor
 *    string                        Accessory
 *    string                        Accessory
 *   </Equip Slot>                 </Equip Slot>
 *   Replace 'string' with the Equipment type's name entry. This is case
 *   sensitive so if the string does not match a name entry perfectly, the slot
 *   will not be granted to the class. Multiple copies of a name entry would
 *   mean the class can equip multiple equipment of that type. Everything works
 *   the same as the previous notetag.
 *
 * Weapon and Armor Notetags:
 *   <stat: +x>
 *   <stat: -x>
 *   Allows the piece of weapon or armor to gain or lose x amount of stat.
 *   Replace "stat" with "hp", "mp", "atk", "def", "mat", "mdf", "agi", or
 *   "luk" to alter that specific stat. This allows the piece of equipment
 *   to go past the editor's default limitation so long as the maximum value
 *   allows for it. Changes made here alter the base parameters.
 *
 * ============================================================================
 * Lunatic Mode - Custom Parameters
 * ============================================================================
 *
 *   <Custom Parameters>  Example: <Custom Parameters>
 *    code                          atk = $gameVariables.value(1);
 *    code                          mat = atk / 2;
 *    code                          all = $gameParty.members().length;
 *    code                         </Custom Parameters>
 *   </Code Parameters>
 *   Allows for parameters to have custom rates adjusted by code. The following
 *   parameters are defined: 'maxhp', 'maxmp', 'atk', 'def', 'mat', 'mdf',
 *   'agi', 'luk', and 'all'. The 'all' parameter will affect all parameters.
 *   Changes made here do not alter the base parameters, but instead, are added
 *   onto the base parameters.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.18:
 * - Bypass the isDevToolsOpen() error when bad code is inserted into a script
 * call or custom Lunatic Mode code segment due to updating to MV 1.6.1.
 *
 * Version 1.17:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.16:
 * - Lunatic Mode fail safes added.
 *
 * Version 1.15:
 * - Optimization update.
 *
 * Version 1.14:
 * - Added an actor refresh upon listing the various equip slots to ensure that
 * all slots are updated in case any cache'd instances may have been missed.
 *
 * Version 1.13:
 * - Fixed a bug that caused a crash for those who weren't using the Item Core
 * in addition to this plugin.
 *
 * Version 1.12:
 * - Added optional functionality. Leaving 'Finish Command' empty will remove
 * it from being added to the command list.
 *
 * Version 1.11:
 * - Updated for RPG Maker MV version 1.1.0.
 *
 * Version 1.10:
 * - Fixed a bug that did not clear changes made to an actor's stats after
 * having unequipped them and then switching actors.
 *
 * Version 1.09:
 * - For users using the Item Core plugin and the new Item Scene layout option,
 * the Item Info Window is now added to the Equip Scene. Pressing Left/Right
 * will toggle the stat comparison window with the info window. Pressing Tab on
 * the keyboard will also switch them as well as clicking on those windows.
 *
 * Version 1.08:
 * - Fixed a bug where changing an actor's equips would revive them if dead.
 *
 * Version 1.07:
 * - Fixed a bug with 'Optimize' and 'Remove All' not refreshing windows.
 *
 * Version 1.06:
 * - Fixed a bug with 'Change Equipment' event where it would only change the
 * slot of the marked equipment rather than the slot type.
 *
 * Version 1.05:
 * - Fixed an issue where unequipping items can kill actors.
 *
 * Version 1.04a:
 * - Fixed a bug and rewrote the initializing equipment process.
 *
 * Version 1.03:
 * - Fixed an bug that resulted in null object errors.
 *
 * Version 1.02:
 * - Fixed an issue that did not keep HP and MP rates the same when using the
 * optimize and clear commands.
 *
 * Version 1.01:
 * - Fixed a bug that did not update the stats properly when compared.
 *
 * Version 1.00:
 * - Finished plugin!
 */
//=============================================================================

//=============================================================================
// Parameter Variables
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_EquipCore');
Yanfly.Param = Yanfly.Param || {};
Yanfly.Icon = Yanfly.Icon || {};

Yanfly.Param.EquipTextAlign = String(Yanfly.Parameters['Text Align']);
Yanfly.Param.EquipFinishCmd = String(Yanfly.Parameters['Finish Command']);
Yanfly.Param.EquipRemoveText = String(Yanfly.Parameters['Remove Text']);
Yanfly.Icon.RemoveEquip = Number(Yanfly.Parameters['Remove Icon']);
Yanfly.Param.EquipEmptyText = String(Yanfly.Parameters['Empty Text']);
Yanfly.Icon.EmptyEquip = Number(Yanfly.Parameters['Empty Icon']);
Yanfly.Data = String(Yanfly.Parameters['Non-Removable Types']);
Yanfly.Data = Yanfly.Data.split(' ');
Yanfly.Param.EquipNonRemove = [];
for (Yanfly.i = 0; Yanfly.i < Yanfly.Data.length; ++Yanfly.i) {
  Yanfly.Param.EquipNonRemove.push(parseInt(Yanfly.Data[Yanfly.i]));
};
Yanfly.Data = String(Yanfly.Parameters['Non-Optimized Types']);
Yanfly.Data = Yanfly.Data.split(' ');
Yanfly.Param.EquipNonOptimized = [];
for (Yanfly.i = 0; Yanfly.i < Yanfly.Data.length; ++Yanfly.i) {
  Yanfly.Param.EquipNonOptimized.push(parseInt(Yanfly.Data[Yanfly.i]));
};

//=============================================================================
// DataManager
//=============================================================================

Yanfly.Equip.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
  if (!Yanfly.Equip.DataManager_isDatabaseLoaded.call(this)) return false;
  if (!Yanfly._loaded_YEP_EquipCore) {
    DataManager.processEquipNotetags1($dataClasses);
    DataManager.processEquipNotetags2($dataWeapons);
    DataManager.processEquipNotetags2($dataArmors);
    Yanfly._loaded_YEP_EquipCore = true;
  }
  return true;
};

DataManager.processEquipNotetags1 = function(group) {
  var note1 = /<(?:EQUIP SLOT|equip slots):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var note2 = /<(?:EQUIP SLOT|equip slots)>/i;
  var note3 = /<\/(?:EQUIP SLOT|equip slots)>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.equipSlots = [];
    var equipSlots = false;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(note1)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        obj.equipSlots = obj.equipSlots.concat(array);
      } else if (line.match(note2)) {
        equipSlots = true;
      } else if (line.match(note3)) {
        equipSlots = false;
      } else if (equipSlots && line.match(/[ ]*(.*)/i)) {
        var name = String(RegExp.$1);
        var slotId = $dataSystem.equipTypes.indexOf(name);
        if (slotId >= 0) obj.equipSlots.push(slotId);
      }
    }
    if (obj.equipSlots.length <= 0) this.setDefaultEquipSlots(obj);
  }
};

DataManager.setDefaultEquipSlots = function(obj) {
    for (var i = 1; i < $dataSystem.equipTypes.length; ++i) {
      var name = $dataSystem.equipTypes[i];
      var slotId = $dataSystem.equipTypes.indexOf(name);
      if (slotId >= 0) obj.equipSlots.push(slotId);
    }
};

DataManager.processEquipNotetags2 = function(group) {
  var note1 = /<(?:PARAMETER EVAL|custom parameter|custom parameters)>/i;
  var note2 = /<\/(?:PARAMETER EVAL|custom parameter|custom parameters)>/i;
  var note3 = /<(.*):[ ]([\+\-]\d+)>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.parameterEval = '';
    var parameterEval = false;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(note1)) {
        parameterEval = true;
      } else if (line.match(note2)) {
        parameterEval = false;
      } else if (parameterEval) {
        obj.parameterEval = obj.parameterEval + line + '\n';
      } else if (line.match(note3)) {
        var stat = String(RegExp.$1).toUpperCase();
        var value = parseInt(RegExp.$2);
        switch (stat) {
          case 'HP':
          case 'MAXHP':
          case 'MAX HP':
            obj.params[0] = value;
            break;
          case 'MP':
          case 'MAXMP':
          case 'MAX MP':
          case 'SP':
          case 'MAXSP':
          case 'MAX SP':
            obj.params[1] = value;
            break;
          case 'ATK':
          case 'STR':
            obj.params[2] = value;
            break;
          case 'DEF':
            obj.params[3] = value;
            break;
          case 'MAT':
          case 'INT' || 'SPI':
            obj.params[4] = value;
            break;
          case 'MDF':
          case 'RES':
            obj.params[5] = value;
            break;
          case 'AGI':
          case 'SPD':
            obj.params[6] = value;
            break;
          case 'LUK':
            obj.params[7] = value;
            break;
          }
      }
    }
  }
};

//=============================================================================
// Game_Actor
//=============================================================================

Game_Actor.prototype.initEquips = function(equips) {
    var equips = this.convertInitEquips(equips);
    this.equipInitEquips(equips);
    this.releaseUnequippableItems(true);
    this.recoverAll();
    this.refresh();
};

Game_Actor.prototype.convertInitEquips = function(equips) {
    var items = [];
    for (var i = 0; i < equips.length; ++i) {
      var equipId = equips[i];
      if (equipId <= 0) continue;
      var equipType = $dataSystem.equipTypes[i + 1];
      if (equipType === $dataSystem.equipTypes[1] ||
      (i === 1 && this.isDualWield())) {
        var equip = $dataWeapons[equipId];
      } else {
        var equip = $dataArmors[equipId];
      }
      items.push(equip);
    }
    return items;
};

Game_Actor.prototype.equipInitEquips = function(equips) {
    var slots = this.equipSlots();
    var maxSlots = slots.length;
    this._equips = [];
    for (var i = 0; i < maxSlots; ++i) {
      this._equips[i] = new Game_Item();
    }
    for (var i = 0; i < maxSlots; ++i) {
      var slotType = slots[i];
      var equip = this.grabInitEquips(equips, slotType);
      if (this.canEquip(equip)) this._equips[i].setObject(equip);
    }
};

Game_Actor.prototype.grabInitEquips = function(equips, slotType) {
    var item = null;
    for (var i = 0; i < equips.length; ++i) {
      var equip = equips[i];
      if (!equip) continue;
      if (slotType === 1 && DataManager.isWeapon(equip)) {
        item = equip;
        break;
      } else if (equip.etypeId === slotType) {
        item = equip;
        break;
      }
    }
    if (item) equips[i] = null;
    return item;
};

Game_Actor.prototype.equipSlots = function() {
    var slots = this.currentClass().equipSlots.slice();
    if (slots.length >= 2 && this.isDualWield()) slots[1] = 1;
    return slots;
};

Yanfly.Equip.Game_Actor_equips = Game_Actor.prototype.equips;
Game_Actor.prototype.equips = function() {
    for (var i = 0; i < this.currentClass().equipSlots.length; ++i) {
      if (this._equips[i] === undefined || this._equips[i] === null) {
        this._equips[i] = new Game_Item();
      }
    }
    return Yanfly.Equip.Game_Actor_equips.call(this);
};

Yanfly.Equip.Game_Actor_changeEquip = Game_Actor.prototype.changeEquip;
Game_Actor.prototype.changeEquip = function(slotId, item) {
    if (!this._equips[slotId]) this._equips[slotId] = new Game_Item();
    Yanfly.Equip.Game_Actor_changeEquip.call(this, slotId, item);
};

Yanfly.Equip.Game_Actor_forceChangeEquip =
    Game_Actor.prototype.forceChangeEquip;
Game_Actor.prototype.forceChangeEquip = function(slotId, item) {
    if (!this._equips[slotId]) {
      this._equips[slotId] = new Game_Item();
      this._equips[slotId].setEquip(this.equipSlots()[slotId] === 1, 0);
    }
    Yanfly.Equip.Game_Actor_forceChangeEquip.call(this, slotId, item);
};

Yanfly.Equip.Game_Actor_isEquipChangeOk = Game_Actor.prototype.isEquipChangeOk;
Game_Actor.prototype.isEquipChangeOk = function(slotId) {
    if ($gameTemp._clearEquipments) {
      var typeId = this.equipSlots()[slotId];
      if (Yanfly.Param.EquipNonRemove.contains(typeId)) return false;
    }
    if ($gameTemp._optimizeEquipments) {
      var typeId = this.equipSlots()[slotId];
      if (Yanfly.Param.EquipNonOptimized.contains(typeId)) return false;
    }
    return Yanfly.Equip.Game_Actor_isEquipChangeOk.call(this, slotId);
};

Yanfly.Equip.Game_Actor_paramPlus = Game_Actor.prototype.paramPlus;
Game_Actor.prototype.paramPlus = function(paramId) {
    value = Yanfly.Equip.Game_Actor_paramPlus.call(this, paramId);
    var equips = this.equips();
    for (var i = 0; i < equips.length; i++) {
      var item = equips[i];
      if (!item) continue;
      value += this.customParamPlus(item, paramId);
      value += this.evalParamPlus(item, paramId);
    }
    return value;
};

Game_Actor.prototype.customParamPlus = function(item, paramId) {
    return 0;
};

Game_Actor.prototype.evalParamPlus = function(item, paramId) {
    if (!item) return 0;
    if (!item.parameterEval || item.parameterEval === '') return 0;
    var value = 0;
    var hp = 0;
    var maxhp = 0;
    var mhp = 0;
    var mp = 0;
    var maxmp = 0;
    var mmp = 0;
    var sp = 0;
    var maxsp = 0;
    var msp = 0;
    var atk = 0;
    var str = 0;
    var def = 0;
    var mat = 0;
    var int = 0;
    var spi = 0;
    var mdf = 0;
    var res = 0;
    var agi = 0;
    var spd = 0;
    var luk = 0;
    var all = 0;
    var a = this;
    var user = this;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = item.parameterEval;
    try {
      eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'CUSTOM PARAMETER FORMULA ERROR');
    }
    switch (paramId) {
      case 0:
        value += hp + maxhp + mhp;
        break;
      case 1:
        value += mp + maxmp + mmp + sp + maxsp + msp;
        break;
      case 2:
        value += atk + str;
        break;
      case 3:
        value += def;
        break;
      case 4:
        value += mat + int + spi;
        break;
      case 5:
        value += mdf + res;
        break;
      case 6:
        value += agi + spd;
        break;
      case 7:
        value += luk;
        break;
    }
    return value + all;
};

//=============================================================================
// Game_Interpreter
//=============================================================================

// Change Equipment
Game_Interpreter.prototype.command319 = function() {
    var actor = $gameActors.actor(this._params[0]);
    if (!actor) return true;
    var index = actor.equipSlots().indexOf(this._params[1]) + 1;
    actor.changeEquipById(index, this._params[2]);
    return true;
};

//=============================================================================
// Window_EquipCommand
//=============================================================================

Window_EquipCommand.prototype.windowWidth = function() {
    return 240;
};

Window_EquipCommand.prototype.maxCols = function() {
    return 1;
};

Window_EquipCommand.prototype.windowHeight = function() {
    return this.fittingHeight(this.numVisibleRows());
};

Window_EquipCommand.prototype.numVisibleRows = function() {
    return 4;
};

Window_EquipCommand.prototype.itemTextAlign = function() {
    return Yanfly.Param.EquipTextAlign;
};

Yanfly.Equip.Window_EquipCommand_makeCommandList =
    Window_EquipCommand.prototype.makeCommandList;
Window_EquipCommand.prototype.makeCommandList = function() {
    Yanfly.Equip.Window_EquipCommand_makeCommandList.call(this);
    this.addCustomCommand();
    this.addFinishCommand();
};

Window_EquipCommand.prototype.addCustomCommand = function() {
};

Window_EquipCommand.prototype.addFinishCommand = function() {
    if (Yanfly.Param.EquipFinishCmd === '') return;
    this.addCommand(Yanfly.Param.EquipFinishCmd, 'cancel');
};

//=============================================================================
// Window_EquipSlot
//=============================================================================

Yanfly.Equip.Window_EquipSlot_setActor = Window_EquipSlot.prototype.setActor;
Window_EquipSlot.prototype.setActor = function(actor) {
    this.setSlotNameWidth(actor);
    Yanfly.Equip.Window_EquipSlot_setActor.call(this, actor);
};

Window_EquipSlot.prototype.refresh = function() {
    if (this._actor) this._actor.refresh();
    Window_Selectable.prototype.refresh.call(this);
};

Window_EquipSlot.prototype.isEnabled = function(index) {
    if (this._actor) {
      return Yanfly.Equip.Game_Actor_isEquipChangeOk.call(this._actor, index);
    } else {
      return false;
    }
};

Window_EquipSlot.prototype.drawItem = function(index) {
    if (!this._actor) return;
    var rect = this.itemRectForText(index);
    this.changeTextColor(this.systemColor());
    this.changePaintOpacity(this.isEnabled(index));
    var ww1 = this._nameWidth;
    this.drawText(this.slotName(index), rect.x, rect.y, ww1);
    var ww2 = rect.width - ww1;
    var item = this._actor.equips()[index];
    if (item) {
      this.drawItemName(item, rect.x + ww1, rect.y, ww2);
    } else {
      this.drawEmptySlot(rect.x + ww1, rect.y, ww2);
    }
    this.changePaintOpacity(true);
};

Window_EquipSlot.prototype.setSlotNameWidth = function(actor) {
    if (!actor) return;
    this._nameWidth = 0;
    for (var i = 0; i < actor.equipSlots().length; ++i) {
      var text = $dataSystem.equipTypes[actor.equipSlots()[i]] + ' ';
      this._nameWidth = Math.max(this._nameWidth, this.textWidth(text));
    }
};

Window_EquipSlot.prototype.drawEmptySlot = function(wx, wy, ww) {
    this.changePaintOpacity(false);
    var ibw = Window_Base._iconWidth + 4;
    this.resetTextColor();
    this.drawIcon(Yanfly.Icon.EmptyEquip, wx + 2, wy + 2);
    var text = Yanfly.Param.EquipEmptyText;
    this.drawText(text, wx + ibw, wy, ww - ibw);
};

Window_EquipSlot.prototype.setInfoWindow = function(infoWindow) {
    this._infoWindow = infoWindow;
    this.update();
};

Yanfly.Equip.Window_EquipSlot_updateHelp = Window_EquipSlot.prototype.updateHelp;
Window_EquipSlot.prototype.updateHelp = function() {
    Yanfly.Equip.Window_EquipSlot_updateHelp.call(this);
    if (SceneManager._scene instanceof Scene_Equip && this._infoWindow) {
      this._infoWindow.setItem(this.item());
    }
};

//=============================================================================
// Window_EquipItem
//=============================================================================

Window_EquipItem.prototype.maxCols = function() {
    return 1;
};

Yanfly.Equip.Window_EquipItem_setSlotId = Window_EquipItem.prototype.setSlotId;
Window_EquipItem.prototype.setSlotId = function(slotId) {
    // do nothing
};

Yanfly.Equip.Window_EquipItem_includes = Window_EquipItem.prototype.includes;
Window_EquipItem.prototype.includes = function(item) {
    if (item === null && this._actor && this._data.length > 0) {
      var typeId = this._actor.equipSlots()[this._slotId];
      if (Yanfly.Param.EquipNonRemove.contains(typeId)) return false;
    }
    return Yanfly.Equip.Window_EquipItem_includes.call(this, item);
};

Yanfly.Equip.Window_EquipItem_isEnabled =
    Window_EquipItem.prototype.isEnabled;
Window_EquipItem.prototype.isEnabled = function(item) {
    if (item === null && this._actor) {
      var typeId = this._actor.equipSlots()[this._slotId];
      if (Yanfly.Param.EquipNonRemove.contains(typeId)) return false;
    }
    return Yanfly.Equip.Window_EquipItem_isEnabled.call(this, item);
};

Yanfly.Equip.Window_EquipItem_drawItem = Window_EquipItem.prototype.drawItem;
Window_EquipItem.prototype.drawItem = function(index) {
    var item = this._data[index];
    if (item === null) {
      this.drawRemoveEquip(index);
    } else {
      Yanfly.Equip.Window_EquipItem_drawItem.call(this, index);
    }
};

Window_EquipItem.prototype.drawRemoveEquip = function(index) {
    if (!this.isEnabled(null)) return;
    var rect = this.itemRect(index);
    rect.width -= this.textPadding();
    this.changePaintOpacity(true);
    var ibw = Window_Base._iconWidth + 4;
    this.resetTextColor();
    this.drawIcon(Yanfly.Icon.RemoveEquip, rect.x + 2, rect.y + 2);
    var text = Yanfly.Param.EquipRemoveText;
    this.drawText(text, rect.x + ibw, rect.y, rect.width - ibw);
};

Window_EquipItem.prototype.setInfoWindow = function(infoWindow) {
    this._infoWindow = infoWindow;
    this.update();
};

Yanfly.Equip.Window_EquipItem_updateHelp = Window_EquipItem.prototype.updateHelp;
Window_EquipItem.prototype.updateHelp = function() {
    Yanfly.Equip.Window_EquipItem_updateHelp.call(this);
    if (SceneManager._scene instanceof Scene_Equip && this._infoWindow) {
      this._infoWindow.setItem(this.item());
    }
};

//=============================================================================
// Window_StatCompare
//=============================================================================

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

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

Window_StatCompare.prototype.initialize = function(wx, wy, ww, wh) {
    Window_Base.prototype.initialize.call(this, wx, wy, ww, wh);
    this._actor = null;
    this._tempActor = null;
    this.refresh();
};

Window_StatCompare.prototype.createWidths = function() {
    this._paramNameWidth = 0;
    this._paramValueWidth = 0;
    this._arrowWidth = this.textWidth('\u2192' + ' ');
    var buffer = this.textWidth(' ');
    for (var i = 0; i < 8; ++i) {
      var value1 = this.textWidth(TextManager.param(i));
      var value2 = this.textWidth(Yanfly.Util.toGroup(this._actor.paramMax(i)));
      this._paramNameWidth = Math.max(value1, this._paramNameWidth);
      this._paramValueWidth = Math.max(value2, this._paramValueWidth);
    }
    this._bonusValueWidth = this._paramValueWidth;
    this._bonusValueWidth += this.textWidth('(+)') + buffer;
    this._paramNameWidth += buffer;
    this._paramValueWidth;
    if (this._paramNameWidth + this._paramValueWidth * 2 + this._arrowWidth +
      this._bonusValueWidth > this.contents.width) this._bonusValueWidth = 0;
};

Window_StatCompare.prototype.setActor = function(actor) {
    if (this._actor === actor) return;
    this._actor = actor;
    this.createWidths();
    this.refresh();
};

Window_StatCompare.prototype.refresh = function() {
    this.contents.clear();
    if (!this._actor) return;
    for (var i = 0; i < 8; ++i) {
        this.drawItem(0, this.lineHeight() * i, i);
    }
};

Window_StatCompare.prototype.setTempActor = function(tempActor) {
    if (this._tempActor === tempActor) return;
    this._tempActor = tempActor;
    this.refresh();
};

Window_StatCompare.prototype.drawItem = function(x, y, paramId) {
    this.drawDarkRect(x, y, this.contents.width, this.lineHeight());
    this.drawParamName(y, paramId);
    this.drawCurrentParam(y, paramId);
    this.drawRightArrow(y);
    if (!this._tempActor) return;
    this.drawNewParam(y, paramId);
    this.drawParamDifference(y, paramId);
};

Window_StatCompare.prototype.drawDarkRect = function(dx, dy, dw, dh) {
    var color = this.gaugeBackColor();
    this.changePaintOpacity(false);
    this.contents.fillRect(dx + 1, dy + 1, dw - 2, dh - 2, color);
    this.changePaintOpacity(true);
};

Window_StatCompare.prototype.drawParamName = function(y, paramId) {
    var x = this.textPadding();
    this.changeTextColor(this.systemColor());
    this.drawText(TextManager.param(paramId), x, y, this._paramNameWidth);
};

Window_StatCompare.prototype.drawCurrentParam = function(y, paramId) {
    var x = this.contents.width - this.textPadding();
    x -= this._paramValueWidth * 2 + this._arrowWidth + this._bonusValueWidth;
    this.resetTextColor();
    var actorparam = Yanfly.Util.toGroup(this._actor.param(paramId));
    this.drawText(actorparam, x, y, this._paramValueWidth, 'right');
};

Window_StatCompare.prototype.drawRightArrow = function(y) {
    var x = this.contents.width - this.textPadding();
    x -= this._paramValueWidth + this._arrowWidth + this._bonusValueWidth;
    var dw = this.textWidth('\u2192' + ' ');
    this.changeTextColor(this.systemColor());
    this.drawText('\u2192', x, y, dw, 'center');
};

Window_StatCompare.prototype.drawNewParam = function(y, paramId) {
    var x = this.contents.width - this.textPadding();
    x -= this._paramValueWidth + this._bonusValueWidth;
    var newValue = this._tempActor.param(paramId);
    var diffvalue = newValue - this._actor.param(paramId);
    var actorparam = Yanfly.Util.toGroup(newValue);
    this.changeTextColor(this.paramchangeTextColor(diffvalue));
    this.drawText(actorparam, x, y, this._paramValueWidth, 'right');
};

Window_StatCompare.prototype.drawParamDifference = function(y, paramId) {
    var x = this.contents.width - this.textPadding();
    x -= this._bonusValueWidth;
    var newValue = this._tempActor.param(paramId);
    var diffvalue = newValue - this._actor.param(paramId);
    if (diffvalue === 0) return;
    var actorparam = Yanfly.Util.toGroup(newValue);
    this.changeTextColor(this.paramchangeTextColor(diffvalue));
    var text = Yanfly.Util.toGroup(diffvalue);
    if (diffvalue > 0) {
      text = ' (+' + text + ')';
    } else {
      text = ' (' + text + ')';
    }
    this.drawText(text, x, y, this._bonusValueWidth, 'left');
};

//=============================================================================
// Scene_Equip
//=============================================================================

Scene_Equip.prototype.create = function() {
    Scene_MenuBase.prototype.create.call(this);
    this.createHelpWindow();
    this.createCommandWindow();
    this.createStatusWindow();
    this.createSlotWindow();
    this.createItemWindow();
    this.createCompareWindow();
    this._lowerRightVisibility = true;
    this.updateLowerRightWindows();
    this.refreshActor();
};

Scene_Equip.prototype.createCommandWindow = function() {
    var wy = this._helpWindow.height;
    this._commandWindow = new Window_EquipCommand(0, wy, 240);
    this._commandWindow.setHelpWindow(this._helpWindow);
    this._commandWindow.setHandler('equip', this.commandEquip.bind(this));
    this._commandWindow.setHandler('optimize', this.commandOptimize.bind(this));
    this._commandWindow.setHandler('clear', this.commandClear.bind(this));
    this._commandWindow.setHandler('cancel', this.popScene.bind(this));
    this._commandWindow.setHandler('pagedown', this.nextActor.bind(this));
    this._commandWindow.setHandler('pageup', this.previousActor.bind(this));
    this.addWindow(this._commandWindow);
};

Scene_Equip.prototype.createStatusWindow = function() {
    var wx = this._commandWindow.width;
    var wy = this._helpWindow.height;
    var ww = Graphics.boxWidth - wx;
    var wh = this._commandWindow.height;
    this._statusWindow = new Window_SkillStatus(wx, wy, ww, wh);
    this.addWindow(this._statusWindow);
};

Scene_Equip.prototype.createSlotWindow = function() {
    var wy = this._commandWindow.y + this._commandWindow.height;
    var ww = Graphics.boxWidth / 2;
    var wh = Graphics.boxHeight - wy;
    this._slotWindow = new Window_EquipSlot(0, wy, ww, wh);
    this._slotWindow.setHelpWindow(this._helpWindow);
    this._slotWindow.setHandler('ok',       this.onSlotOk.bind(this));
    this._slotWindow.setHandler('cancel',   this.onSlotCancel.bind(this));
    this.addWindow(this._slotWindow);
};

Scene_Equip.prototype.createItemWindow = function() {
    var wy = this._slotWindow.y;
    var ww = Graphics.boxWidth / 2;
    var wh = Graphics.boxHeight - wy;
    this._itemWindow = new Window_EquipItem(0, wy, ww, wh);
    this._itemWindow.setHelpWindow(this._helpWindow);
    this._itemWindow.setHandler('ok',     this.onItemOk.bind(this));
    this._itemWindow.setHandler('cancel', this.onItemCancel.bind(this));
    this._slotWindow.setItemWindow(this._itemWindow);
    this.addWindow(this._itemWindow);
    this._itemWindow.hide();
};

Scene_Equip.prototype.createCompareWindow = function() {
    this._lowerRightWindows = [];
    var wx = this._itemWindow.width;
    var wy = this._itemWindow.y;
    var ww = Graphics.boxWidth - wx;
    var wh = Graphics.boxHeight - wy;
    this._compareWindow = new Window_StatCompare(wx, wy, ww, wh);
    this._slotWindow.setStatusWindow(this._compareWindow);
    this._itemWindow.setStatusWindow(this._compareWindow);
    this.addWindow(this._compareWindow);
    this._lowerRightWindows.push(this._compareWindow);
    if (Imported.YEP_ItemCore && eval(Yanfly.Param.ItemSceneItem)) {
      this.createItemInfoWindow();
    }
};

Scene_Equip.prototype.createItemInfoWindow = function() {
    var wx = this._itemWindow.width;
    var wy = this._itemWindow.y;
    var ww = Graphics.boxWidth - wx;
    var wh = this._itemWindow.height;
    this._infoWindow = new Window_ItemInfo(wx, wy, ww, wh);
    this._slotWindow.setInfoWindow(this._infoWindow);
    this._itemWindow.setInfoWindow(this._infoWindow);
    this.addWindow(this._infoWindow);
    this._lowerRightWindows.push(this._infoWindow);
};

Yanfly.Equip.Scene_Equip_refreshActor = Scene_Equip.prototype.refreshActor;
Scene_Equip.prototype.refreshActor = function() {
    Yanfly.Equip.Scene_Equip_refreshActor.call(this);
    this._compareWindow.setActor(this.actor());
};

Yanfly.Equip.Scene_Equip_commandOptimize =
    Scene_Equip.prototype.commandOptimize;
Scene_Equip.prototype.commandOptimize = function() {
    $gameTemp._optimizeEquipments = true;
    var hpRate = this.actor().hp / Math.max(1, this.actor().mhp);
    var mpRate = this.actor().mp / Math.max(1, this.actor().mmp);
    Yanfly.Equip.Scene_Equip_commandOptimize.call(this);
    $gameTemp._optimizeEquipments = false;
    var max = this.actor().isDead() ? 0 : 1;
    var hpAmount = Math.max(max, parseInt(this.actor().mhp * hpRate));
    this.actor().setHp(hpAmount);
    this.actor().setMp(parseInt(this.actor().mmp * mpRate));
    this._compareWindow.refresh();
    this._statusWindow.refresh();
    this.refreshActor();
};

Yanfly.Equip.Scene_Equip_commandClear = Scene_Equip.prototype.commandClear;
Scene_Equip.prototype.commandClear = function() {
    $gameTemp._clearEquipments = true;
    var hpRate = this.actor().hp / Math.max(1, this.actor().mhp);
    var mpRate = this.actor().mp / Math.max(1, this.actor().mmp);
    Yanfly.Equip.Scene_Equip_commandClear.call(this);
    $gameTemp._clearEquipments = false;
    var max = this.actor().isDead() ? 0 : 1;
    var hpAmount = Math.max(max, parseInt(this.actor().mhp * hpRate));
    this.actor().setHp(hpAmount);
    this.actor().setMp(parseInt(this.actor().mmp * mpRate));
    this._compareWindow.refresh();
    this._statusWindow.refresh();
    this.refreshActor();
};

Yanfly.Equip.Scene_Equip_onSlotOk = Scene_Equip.prototype.onSlotOk;
Scene_Equip.prototype.onSlotOk = function() {
    this._itemWindow._slotId = -1;
    var slotId = this._slotWindow.index();
    Yanfly.Equip.Window_EquipItem_setSlotId.call(this._itemWindow, slotId);
    Yanfly.Equip.Scene_Equip_onSlotOk.call(this);
    this._itemWindow.show();
};

Yanfly.Equip.Scene_Equip_onSlotCancel = Scene_Equip.prototype.onSlotCancel;
Scene_Equip.prototype.onSlotCancel = function() {
    Yanfly.Equip.Scene_Equip_onSlotCancel.call(this);
    if (this._infoWindow) this._infoWindow.setItem(null);
    this._compareWindow.setTempActor(null);
};

Yanfly.Equip.Scene_Equip_onItemOk = Scene_Equip.prototype.onItemOk;
Scene_Equip.prototype.onItemOk = function() {
    var hpRate = this.actor().hp / Math.max(1, this.actor().mhp);
    var mpRate = this.actor().mp / Math.max(1, this.actor().mmp);
    Yanfly.Equip.Scene_Equip_onItemOk.call(this);
    var max = this.actor().isDead() ? 0 : 1;
    var hpAmount = Math.max(max, parseInt(this.actor().mhp * hpRate));
    this.actor().setHp(hpAmount);
    this.actor().setMp(parseInt(this.actor().mmp * mpRate));
    this._itemWindow.hide();
    this._statusWindow.refresh();
};

Yanfly.Equip.Scene_Equip_onItemCancel = Scene_Equip.prototype.onItemCancel;
Scene_Equip.prototype.onItemCancel = function() {
    Yanfly.Equip.Scene_Equip_onItemCancel.call(this);
    this._compareWindow.setTempActor(null);
    this._itemWindow.hide();
};

Scene_Equip.prototype.update = function() {
    Scene_MenuBase.prototype.update.call(this);
    if (this.isActive()) this.updateLowerRightWindowTriggers();
};

Scene_Equip.prototype.updateLowerRightWindowTriggers = function() {
    if (!this._lowerRightVisibility) return;
    if (Input.isRepeated('right')) {
      this.shiftLowerRightWindows();
    } else if (Input.isRepeated('left')) {
      this.unshiftLowerRightWindows();
    } else if (Input.isRepeated('tab')) {
      this.shiftLowerRightWindows();
    } else if (this.isLowerWindowTouched()) {
      this.shiftLowerRightWindows();
    }
};

Scene_Equip.prototype.isLowerWindowTouched = function() {
    if (!TouchInput.isTriggered()) return false;
    var x = TouchInput.x;
    var y = TouchInput.y;
    var rect = new Rectangle();
    rect.x = this._compareWindow.x;
    rect.y = this._compareWindow.y;
    rect.width = this._compareWindow.x + this._compareWindow.width;
    rect.height = this._compareWindow.y + this._compareWindow.height;
    return (x >= rect.x && y >= rect.y && x < rect.width && y < rect.height);
};

Scene_Equip.prototype.updateLowerRightWindows = function() {
    var length = this._lowerRightWindows.length;
    for (var i = 0; i < length; ++i) {
      var win = this._lowerRightWindows[i];
      win.visible = false;
    }
    this._lowerRightWindows[0].visible = this._lowerRightVisibility;
};

Scene_Equip.prototype.shiftLowerRightWindows = function() {
    var win = this._lowerRightWindows.shift();
    this._lowerRightWindows.push(win);
    this.updateLowerRightWindows();
    this.playLowerRightWindowSound();
};

Scene_Equip.prototype.unshiftLowerRightWindows = function() {
    var win = this._lowerRightWindows.pop();
    this._lowerRightWindows.unshift(win);
    this.updateLowerRightWindows();
    this.playLowerRightWindowSound();
};

Scene_Equip.prototype.playLowerRightWindowSound = function() {
    if (this._lowerRightWindows.length <= 1) return;
    SoundManager.playCursor();
};

Yanfly.Equip.Scene_Equip_onActorChange = Scene_Equip.prototype.onActorChange;
Scene_Equip.prototype.onActorChange = function() {
    Yanfly.Equip.Scene_Equip_onActorChange.call(this);
    this._compareWindow.setTempActor(null);
    if (this._infoWindow) this._infoWindow.setItem(null);
};

//=============================================================================
// Utilities
//=============================================================================

Yanfly.Util = Yanfly.Util || {};

if (!Yanfly.Util.toGroup) {
    Yanfly.Util.toGroup = function(inVal) {
        return inVal;
    }
};

Yanfly.Util.displayError = function(e, code, message) {
  console.log(message);
  console.log(code || 'NON-EXISTENT');
  console.error(e);
  if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") return;
  if (Utils.isNwjs() && Utils.isOptionValid('test')) {
    if (!require('nw.gui').Window.get().isDevToolsOpen()) {
      require('nw.gui').Window.get().showDevTools();
    }
  }
};

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

license: unknown


code:
//=============================================================================
// Yanfly Engine Plugins - Event Mini Label
// YEP_EventMiniLabel.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.EML = Yanfly.EML || {};
Yanfly.EML.version = 1.12

//=============================================================================
 /*:
 * @plugindesc v1.12 Creates miniature-sized labels over events to allow
 * you to insert whatever text you'd like in them.
 * @author Yanfly Engine Plugins
 *
 * @param Default Show
 * @desc Show mini labels by default?
 * @type boolean
 * @on YES
 * @off NO
 * NO - false     YES - true
 * @default true
 *
 * @param Minimum Width
 * @type number
 * @min 1
 * @desc What is the minimum width in pixels for mini labels?
 * @default 136
 *
 * @param Font Size
 * @type number
 * @min 1
 * @desc What is the font size used for text inside a mini label?
 * Default: 28
 * @default 20
 *
 * @param X Buffer
 * @type number
 * @desc Alter the X position of the label by this much.
 * @default 0
 *
 * @param Y Buffer
 * @type number
 * @desc Alter the Y position of the label by this much.
 * @default 36
 *
 * @param Battle Transition
 * @type boolean
 * @on YES
 * @off NO
 * @desc Show Event Mini label during battle transition?
 * NO - false     YES - true
 * @default false
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin lets you place text above the heads of various events using a
 * miniature label through a comment tag.
 *
 * ============================================================================
 * Comment Tags
 * ============================================================================
 *
 * Comment tags are 'notetags' used within the lines of an event's comments.
 * The reason I'm using the comment tags instead of the notetags is because
 * each page of an event can yield a different potential name.
 *
 * To use this, make a comment within the event you wish to make the mini
 * label for and insert the following:
 *
 *   <Mini Label: text>
 *   This will display the 'text' above the event. You can use text codes for
 *   this comment tag and it will create dynamic messages.
 *
 *   <Mini Label Font Size: x>
 *   This will change the font size used for the mini label to x. If this tag
 *   isn't used, the font size will be the default value in the parameters.
 *
 *   <Mini Label X Buffer: +x>
 *   <Mini Label X Buffer: -x>
 *   This will adjust the X buffer for the mini label by x value. If this tag
 *   isn't used, the X buffer will be the default value in the parameters.
 *
 *   <Mini Label Y Buffer: +x>
 *   <Mini Label Y Buffer: -x>
 *   This will adjust the Y buffer for the mini label by x value. If this tag
 *   isn't used, the Y buffer will be the default value in the parameters.
 *
 *   <Always Show Mini Label>
 *   This will make the mini label to always be shown, even when the plugin
 *   command to hide mini labels is used.
 *
 *   <Mini Label Range: x>
 *   The player will have to be within x tiles of this event in order for the
 *   mini label to appear visibly.
 *
 *   <Mini Label Require Facing>
 *   This will require the player to be facing the direction of the event in
 *   order for the mini label to appear.
 *
 * ============================================================================
 * Plugin Commands
 * ============================================================================
 *
 * If you would like to shut off the Event Mini Label mid-game or turn it on,
 * you can use the following plugin commands:
 *
 * Plugin Command:
 *
 *   HideMiniLabel
 *   Hides all Event Mini Label.
 *
 *   ShowMiniLabel
 *   Shows all Event Mini Label.
 *
 *   RefreshMiniLabel
 *   Refreshes all Event Mini Labels on the map.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.12:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.11:
 * - Added 'Battle Transition' plugin parameter. Enabling this will allow you
 * to show the Event Mini Labels during the battle transition. Keeping it
 * disabled will hide them during the transition.
 *
 * Version 1.10:
 * - Mini Windows will now readjust their size to show at normal scale if the
 * map is zoomed in.
 *
 * Version 1.09:
 * - Fixed a bug that caused Mini Labels that started off as hidden to remain
 * hidden even after turning the Mini Labels on.
 *
 * Version 1.08:
 * - Added <Mini Label Require Facing> comment tag.
 * - Moved the priority of the Mini Labels to be later added to the spriteset
 * so they can stay on top of more effects.
 *
 * Version 1.07:
 * - Added more padding space so text doesn't get cut off.
 *
 * Version 1.06:
 * - Fixed a bug that caused some mini labels to show if the event was loaded
 * onto the map without any currently active pages.
 *
 * Version 1.05:
 * - Added 'X Buffer' plugin parameter and the <Mini Label X Buffer: +x> and
 * <Mini Label X Buffer: -x> comment tags to alter the X position of the event
 * mini label.
 *
 * Version 1.04:
 * - Added 'RefreshMiniLabel' plugin command to allow you to manually refresh
 * all mini labels on the map.
 *
 * Version 1.03:
 * - Optimized updating performance to reduce lag on maps with many events.
 *
 * Version 1.01:
 * - Fixed a bug that didn't update event labels under certain page conditions.
 * - Added <Mini Label Range: x> notetag.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

//=============================================================================
// Parameter Variables
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_EventMiniLabel');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.EMWDefaultShow = eval(String(Yanfly.Parameters['Default Show']));
Yanfly.Param.EMWMinWidth = Number(Yanfly.Parameters['Minimum Width']);
Yanfly.Param.EMWFontSize = Number(Yanfly.Parameters['Font Size']);
Yanfly.Param.EMWBufferX = Number(Yanfly.Parameters['X Buffer']);
Yanfly.Param.EMWBufferY = Number(Yanfly.Parameters['Y Buffer']);
Yanfly.Param.EMWBatTran = eval(String(Yanfly.Parameters['Battle Transition']));

//=============================================================================
// Game_System
//=============================================================================

Yanfly.EML.Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
    Yanfly.EML.Game_System_initialize.call(this);
    this.initEventMiniLabel();
};

Game_System.prototype.initEventMiniLabel = function() {
    this._showEventMiniLabel = Yanfly.Param.EMWDefaultShow;
};

Game_System.prototype.isShowEventMiniLabel = function() {
    if (this._showEventMiniLabel === undefined) this.initEventMiniLabel();
    return this._showEventMiniLabel;
};

Game_System.prototype.setEventMiniLabel = function(value) {
    this._showEventMiniLabel = value;
    Game_Interpreter.prototype.refreshEventMiniLabel.call(this);
};

//=============================================================================
// Game_Interpreter
//=============================================================================

Yanfly.EML.Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
  Yanfly.EML.Game_Interpreter_pluginCommand.call(this, command, args)
  if (command === 'HideMiniLabel') $gameSystem.setEventMiniLabel(false);
  if (command === 'ShowMiniLabel') $gameSystem.setEventMiniLabel(true);
  if (command === 'RefreshMiniLabel') this.refreshEventMiniLabel();
};

Game_Interpreter.prototype.refreshEventMiniLabel = function() {
    if ($gameParty.inBattle()) return;
    var scene = SceneManager._scene;
    if (scene instanceof Scene_Map) {
      scene.refreshAllMiniLabels();
    }
};

//=============================================================================
// Window_EventMiniLabel
//=============================================================================

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

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

Window_EventMiniLabel.prototype.initialize = function() {
    this._bufferX = Yanfly.Param.EMWBufferX;
    this._bufferY = Yanfly.Param.EMWBufferY;
    this._fontSize = Yanfly.Param.EMWFontSize;
    this._alwaysShow = false;
    var width = Yanfly.Param.EMWMinWidth;
    var height = this.windowHeight();
    this._range = 500;
    this._reqFacing = false;
    Window_Base.prototype.initialize.call(this, 0, 0, width, height);
    this.opacity = 0;
    this.contentsOpacity = 0;
    this._character = null;
    this._page = 0;
    this._text = '';
};

Window_EventMiniLabel.prototype.standardFontSize = function() {
    if (this._fontSize !== undefined) return this._fontSize;
    return Yanfly.Param.EMWFontSize;
};

Window_EventMiniLabel.prototype.windowHeight = function() {
    var height = this.fittingHeight(1)
    height = Math.max(height, 36 + this.standardPadding() * 2);
    return height;
};

Window_EventMiniLabel.prototype.lineHeight = function() {
    return this.standardFontSize() + 8;
};

Window_EventMiniLabel.prototype.bufferX = function() {
    if (this._bufferX !== undefined) return this._bufferX;
    return Yanfly.Param.EMWBufferX;
};

Window_EventMiniLabel.prototype.bufferY = function() {
    if (this._bufferY !== undefined) return this._bufferY;
    return Yanfly.Param.EMWBufferY;
};

Window_EventMiniLabel.prototype.setCharacter = function(character) {
    this.setText('');
    this._character = character;
    if (character._eventId) this.gatherDisplayData();
};

Window_EventMiniLabel.prototype.gatherDisplayData = function() {
    this._page = this._character.page();
    this._pageIndex = this._character._pageIndex;
    this._range = 500;
    this._bufferY = Yanfly.Param.EMWBufferY;
    this._fontSize = Yanfly.Param.EMWFontSize;
    this._alwaysShow = false;
    this._reqFacing = false;
    if (!this._character.page()) {
      return this.visible = false;
    }
    var list = this._character.list();
    var max = list.length;
    var comment = '';
    for (var i = 0; i < max; ++i) {
      var ev = list[i];
      if ([108, 408].contains(ev.code)) comment += ev.parameters[0] + '\n';
    }
    this.extractNotedata(comment);
};

Window_EventMiniLabel.prototype.extractNotedata = function(comment) {
  if (comment === '') return;
  var tag1 = /<(?:MINI WINDOW|MINI LABEL):[ ](.*)>/i;
  var tag2 = /<(?:MINI WINDOW FONT SIZE|MINI LABEL FONT SIZE):[ ](\d+)>/i;
  var tag3 = /<(?:MINI WINDOW Y BUFFER|MINI LABEL Y BUFFER):[ ]([\+\-]\d+)>/i;
  var tag4 = /<(?:ALWAYS SHOW MINI WINDOW|ALWAYS SHOW MINI LABEL)>/i;
  var tag5 = /<(?:MINI WINDOW RANGE|MINI LABEL RANGE):[ ](\d+)>/i;
  var tag6 = /<(?:MINI WINDOW X BUFFER|MINI LABEL X BUFFER):[ ]([\+\-]\d+)>/i;
  var tag7 = /<(?:MINI WINDOW REQUIRE FACING|MINI LABEL REQUIRE FACING)>/i;
  var notedata = comment.split(/[\r\n]+/);
  var text = '';
  for (var i = 0; i < notedata.length; ++i) {
    var line = notedata[i];
    if (line.match(tag1)) {
      text = String(RegExp.$1);
    } else if (line.match(tag2)) {
      this._fontSize = parseInt(RegExp.$1);
    } else if (line.match(tag3)) {
      this._bufferY = parseInt(RegExp.$1);
    } else if (line.match(tag4)) {
      this._alwaysShow = true;
    } else if (line.match(tag5)) {
      this._range = parseInt(RegExp.$1);
    } else if (line.match(tag6)) {
      this._bufferX = parseInt(RegExp.$1);
    } else if (line.match(tag7)) {
      this._reqFacing = true;
    }
  }
  this.setText(text);
  if (this._text === '' || !$gameSystem.isShowEventMiniLabel()) {
    this.visible = false;
    this.contentsOpacity = 0;
  } else {
    this.visible = true;
    if (this._reqFacing) {
      this.contentsOpacity = 0;
    } else {
      this.contentsOpacity = 255;
    }
  }

};

Window_EventMiniLabel.prototype.setText = function(text) {
    if (this._text === text) return;
    this._text = text;
    this.refresh();
};

Window_EventMiniLabel.prototype.refresh = function() {
    if (Imported.YEP_SelfSwVar) {
      $gameTemp.setSelfSwVarEvent(this._character._mapId, this._character._eventId);
    }
    this.contents.clear();
    var txWidth = this.textWidthEx(this._text);
    txWidth += this.textPadding() * 2;
    var width = txWidth;
    this.width = Math.max(width, Yanfly.Param.EMWMinWidth);
    this.width += this.standardPadding() * 2;
    this.height = this.windowHeight();
    this.createContents();
    var wx = (this.contents.width - txWidth) / 2;
    var wy = 0;
    this.drawTextEx(this._text, wx + this.textPadding(), wy);
    if (Imported.YEP_SelfSwVar) $gameTemp.clearSelfSwVarEvent();
};

Window_EventMiniLabel.prototype.forceRefresh = function() {
    this.refresh();
    this.updateOpacity();
};

Window_EventMiniLabel.prototype.textWidthEx = function(text) {
    return this.drawTextEx(text, 0, this.contents.height);
};

Window_EventMiniLabel.prototype.update = function() {
    Window_Base.prototype.update.call(this);
    if (!this._character) return;
    if (!this._character._eventId) return;
    this.updatePage();
    if (this._text === '') return;
    this.updateOpacity();
};

Window_EventMiniLabel.prototype.updatePage = function() {
    if (this._pageIndex === this._character._pageIndex) return;
    this._pageIndex = this._character._pageIndex;
    this.contents.clear();
    this._text = '';
    this.gatherDisplayData();
};

Window_EventMiniLabel.prototype.updateOpacity = function() {
    if (this.showMiniLabel()) {
      this.show();
    } else {
      this.hide();
    }
};

Window_EventMiniLabel.prototype.show = function() {
    if (this.contentsOpacity >= 255) return;
    this.contentsOpacity += 16;
    this.visible = true;
};

Window_EventMiniLabel.prototype.hide = function() {
    if (this.contentsOpacity <= 0) {
      if (this.visible) this.visible = false;
      return;
    }
    this.contentsOpacity -= 16;
};

Window_EventMiniLabel.prototype.showMiniLabel = function() {
    if (this._alwaysShow) return true;
    if (!this.withinRange()) return false;
    if (!this.meetsFacingRequirements()) return false;
    if (!Yanfly.Param.EMWBatTran) {
      if (SceneManager._scene._encounterEffectDuration > 0) {
        this.contentsOpacity = 0;
        return false;
      }
    }
    return $gameSystem.isShowEventMiniLabel();
};

Window_EventMiniLabel.prototype.withinRange = function() {
    if (this._range >= 500) return true;
    var player = $gamePlayer;
    var chara = this._character;
    if (this._range >= Math.abs(player.x - chara.x)) {
      if (this._range >= Math.abs(player.y - chara.y)) {
        return true;
      }
    }
    return false;
};

Window_EventMiniLabel.prototype.meetsFacingRequirements = function() {
  if (!this._character) return true;
  if (!this._reqFacing) return true;
  var direction = $gamePlayer.direction();
  var playerX = $gamePlayer.x;
  var playerY = $gamePlayer.y;
  var eventX = this._character.x;
  var eventY = this._character.y;
  switch (direction) {
  case 1:
    return playerX >= eventX && playerY <= eventY;
    break;
  case 2:
    return playerY <= eventY;
    break;
  case 3:
    return playerX <= eventX && playerY <= eventY;
    break;
  case 4:
    return playerX >= eventX;
    break;
  case 6:
    return playerX <= eventX;
    break;
  case 7:
    return playerX >= eventX && playerY >= eventY;
    break;
  case 8:
    return playerY >= eventY;
    break;
  case 9:
    return playerX <= eventX && playerY >= eventY;
    break;
  default:
    return true;
    break;
  }
};

//=============================================================================
// Sprite_Character
//=============================================================================

Yanfly.EML.Sprite_Character_update = Sprite_Character.prototype.update;
Sprite_Character.prototype.update = function() {
    Yanfly.EML.Sprite_Character_update.call(this);
    this.updateMiniLabel();
    this.updateMiniLabelZoom();
};

Sprite_Character.prototype.updateMiniLabel = function() {
    this.setupMiniLabel();
    if (!this._miniLabel) return;
    this.positionMiniLabel();
};

Sprite_Character.prototype.setupMiniLabel = function() {
    if (this._miniLabel) return;
    if (!SceneManager._scene._spriteset) return;
    this._miniLabel = new Window_EventMiniLabel();
    this._miniLabel.setCharacter(this._character);
    //this.parent.parent.addChild(this._miniLabel);
    SceneManager._scene._spriteset.addChild(this._miniLabel);
};

Sprite_Character.prototype.positionMiniLabel = function() {
    var win = this._miniLabel;
    var width = win.width * win.scale.x;
    win.x = this.x + width / -2 + win.bufferX();
    var height = win.height * win.scale.y;
    var buffer = win.bufferY() * win.scale.y;
    win.y = this.y + (this.height * -1) - height + buffer;
};

Sprite_Character.prototype.updateMiniLabelZoom = function() {
  if (!this._miniLabel) return;
  var spriteset = SceneManager._scene._spriteset;
  this._miniLabel.scale.x = 1 / spriteset.scale.x;
  this._miniLabel.scale.y = 1 / spriteset.scale.y;
};

Sprite_Character.prototype.refreshMiniLabel = function() {
    if (this._miniLabel) this._miniLabel.forceRefresh();
};

//=============================================================================
// Scene_Map
//=============================================================================

Scene_Map.prototype.refreshAllMiniLabels = function() {
	if(!this._spriteset)
		this.createDisplayObjects();
    let length = this._spriteset._characterSprites.length;
    for (let i = 0; i < length; ++i) {
      let sp = this._spriteset._characterSprites[i];
      sp.refreshMiniLabel();
    }
};

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


code:
//=============================================================================
// Yanfly Engine Plugins - Event Region Trigger
// YEP_EventRegionTrigger.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.EvReTr = Yanfly.EvReTr || {};
Yanfly.EvReTr.version = 1.02;

//=============================================================================
 /*:
 * @plugindesc v1.02 Allows events to trigger by being in specific regions
 * instead of needing to exactly next to or on top of them.
 * @author Yanfly Engine Plugins
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * In RPG Maker MV, events can only trigger when you are either standing next
 * to them or on top of them. This plugin lets you bind their activation to
 * different events onto regions, making them trigger if the player is standing
 * on the designated region first before talking to them through the Action
 * Button, Player Touch, Event Touch, Autorun, and/or Parallels giving them
 * multitudes of ways to trigger events. All of these can be done by simply
 * adding Comment Tags into an event's page.
 *
 * This is different from Region Events, which causes a Common Event to autorun
 * once the player has stepped onto one of those regions. This plugin binds
 * actual map events to regions instead.
 *
 * ============================================================================
 * Comment Tags
 * ============================================================================
 *
 * By default, event pages have no Region Triggers. They have to be added
 * manually per event page using comment tags. You can use the following
 * comment tags to give each event page a region trigger.
 *
 * ---
 *
 * Comment Tags:
 *
 *   <Region Trigger: x>
 *   <Region Triggers: x, x, x>
 *   - Replace 'x' with the ID's of the regions you wish to let the event
 *   trigger if the player is standing within a tile with that region ID and
 *   triggering the event page's activation trigger requirements.
 *
 * ---
 *
  * Event region triggers behave differently depending on the event page's
 * trigger type. Here is how the event page will activate based on the trigger:
 *
 *   Action Button
 *   - As long as the player is within the matching region ID, pressing
 *   the OK button will activate the event.
 *
 *   Player Touch
 *   - If the player moves within the matching region ID, the event will
 *   automatically activate. The player can also press the OK button to trigger
 *   the event.
 *
 *   Event Touch
 *   - If the player moves within the matching region ID, the event will
 *   automatically activate. The player can also press the OK button to trigger
 *   the event.
 *
 *   Autorun
 *   - If the player moves within the matching region ID, the event will
 *   automatically activate. There is no escaping this autorun unless you have
 *   a way of turning it off.
 *
 *   Parallel
 *   - If the player moves within the matching region ID, the event will
 *   automatically activate. The player is granted a few frames of movement
 *   each time the parallel process loops.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.02:
 * - Fixed a bug where parallels don't loop.
 *
 * Version 1.01:
 * - Fixed a bug where Autorun and Parallel triggers won't run unless they had
 * a region associated with them.
 *
 * Version 1.00:
 * - Finished Plugin!
 *
 * ============================================================================
 * End of Helpfile
 * ============================================================================
 */
//=============================================================================

//=============================================================================
// Game_CharacterBase
//=============================================================================

Yanfly.EvReTr.Game_CharacterBase_increaseSteps =
  Game_CharacterBase.prototype.increaseSteps;
Game_CharacterBase.prototype.increaseSteps = function() {
  Yanfly.EvReTr.Game_CharacterBase_increaseSteps.call(this);
  this.eventProximityIncreaseSteps();
};

Game_CharacterBase.prototype.eventProximityIncreaseSteps = function() {
};

//=============================================================================
// Game_Player
//=============================================================================

Yanfly.EvReTr.Game_Player_startMapEvent = Game_Player.prototype.startMapEvent;
Game_Player.prototype.startMapEvent = function(x, y, triggers, normal) {
  Yanfly.EvReTr.Game_Player_startMapEvent.call(this, x, y, triggers, normal);
  if (!$gameMap.isEventRunning() && !$gameMap.isAnyEventStarting()) {
    this.startEventRegionTrigger(triggers, normal);
  }
};

Game_Player.prototype.startEventRegionTrigger = function(triggers, normal) {
  var events = $gameMap.events();
  var length = events.length;
  for (var i = 0; i < length; ++i) {
    var ev = events[i];
    if (!ev) continue;
    if (!ev.isTriggerIn(triggers)) continue;
    if (!ev._regionTriggerList) continue;
    if (ev._regionTriggerList.length <= 0) continue;
    if (this.meetPlayerRegionTriggerConditions(ev)) ev.start();
  }
};

Game_Player.prototype.meetPlayerRegionTriggerConditions = function(ev) {
  var regionId = this.regionId();
  return ev._regionTriggerList && ev._regionTriggerList.contains(regionId);
};

//=============================================================================
// Game_Event
//=============================================================================

Yanfly.EvReTr.Game_Event_setupPage = Game_Event.prototype.setupPage;
Game_Event.prototype.setupPage = function() {
  this._initialAutoRegionTriggerBypass = true;
  Yanfly.EvReTr.Game_Event_setupPage.call(this);
  this._initialAutoRegionTriggerBypass = false;
  this.setupEventRegionTriggerSettings();
};

Game_Event.prototype.setupEventRegionTriggerSettings = function() {
  this.initEventRegionTriggerSettings();
  this.setupEventRegionTriggerCommentTags();
};

Game_Event.prototype.initEventRegionTriggerSettings = function() {
  this._regionTriggerList = [];
};

Game_Event.prototype.setupEventRegionTriggerCommentTags = function() {
  if (!this.page()) return;
  var note1 = /<REGION (?:TRIGGER|TRIGGERS):[ ](\d+)>/i;
  var note2 = /<REGION (?:TRIGGER|TRIGGERS):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var list = this.list();
  var length = list.length;
  for (var i = 0; i < length; ++i) {
    var ev = list[i];
    if ([108, 408].contains(ev.code)) {
      if (ev.parameters[0].match(note1)) {
        this._regionTriggerList.push(parseInt(RegExp.$1));
      } else if (ev.parameters[0].match(note2)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        this._regionTriggerList = this._regionTriggerList.concat(array);
      }
    }
  }
};

Game_Event.prototype.eventProximityIncreaseSteps = function() {
  if (!$gameMap.isEventRunning() && !$gameMap.isAnyEventStarting()) {
    $gamePlayer.startEventRegionTrigger([2], this.isNormalPriority());
  }
};

Yanfly.EvReTr.Game_Event_checkEventTriggerAuto =
  Game_Event.prototype.checkEventTriggerAuto;
Game_Event.prototype.checkEventTriggerAuto = function() {
  if (this._trigger !== 3) return;
  if (this._initialAutoRegionTriggerBypass) return;
  if (!this.meetEventRegionTriggerConditions(false)) return;
  Yanfly.EvReTr.Game_Event_checkEventTriggerAuto.call(this);
};

Yanfly.EvReTr.Game_Event_updateParallel = Game_Event.prototype.updateParallel;
Game_Event.prototype.updateParallel = function() {
  if (!this._interpreter) return;
  if (!this.meetEventRegionTriggerConditions(true)) return;
  Yanfly.EvReTr.Game_Event_updateParallel.call(this);
};

Game_Event.prototype.meetEventRegionTriggerConditions = function(parallel) {
  if (!parallel && $gameMap.isEventRunning()) return false;
  if (!parallel && $gameMap.isAnyEventStarting()) return false;
  if (!this._regionTriggerList) return true;
  if (this._regionTriggerList.length <= 0) return true;
  return $gamePlayer.meetPlayerRegionTriggerConditions(this);
};

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


code:
var yanflyParamNormalEndSwitch = 0;
var yanflyParamAbnormalEndSwitch = 0;

//=============================================================================
// Yanfly Engine Plugins - External Links
// YEP_ExternalLinks.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.LINK = Yanfly.LINK || {};
Yanfly.LINK.version = 1.00

//=============================================================================
 /*:
 * @plugindesc v1.01 Link back to your home page through the title screen
 * and also be able to link your players from within the game.
 * @author Yanfly Engine Plugins
 *
 * @param Home Page URL
 * @desc Places a link to your website homepage at the title screen.
 * Leave this blank if you don't wish to enable this feature.
 * @default https://www.google.com/
 *
 * @param Home Page Text
 * @desc This is how 'Home Page' will appear on the title screen.
 * @default Home Page
 *
 * @param Popup Blocker Notice
 * @desc This is a window to notify the player the link was blocked
 * by a pop-up blocker.
 * @default The link was blocked by a pop-up blocker.
 *
 * @help
 * ============================================================================
 * Introduction                                                     .
 * ============================================================================
 * This plugin allows you to place a "link" to your home page at the title
 * screen's command window towards the bottom. To adjust where the link goes,
 * change the Home Page URL in the plugin's parameters.
 *
 * ============================================================================
 * Plugin Commands
 * ============================================================================
 *
 * If you wish to send players to other links, you can use the following
 * plugin commands.
 *
 * Plugin Command
 *   OpenNewTab http://www.google.com/     Opens link in a new tab.
 *   OpenNewWindow http://www.google.com/  Opens link in a new window.
 *
 * Some web browsers may not differentiate these commands too much.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.01:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

//=============================================================================
// Parameter Variables
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_ExternalLinks');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.HomePageUrl = String(Yanfly.Parameters['Home Page URL']);
Yanfly.Param.HomePageText = String(Yanfly.Parameters['Home Page Text']);
Yanfly.Param.PopupMessage = String(Yanfly.Parameters['Popup Blocker Notice']);

//=============================================================================
// SceneManager
//=============================================================================

SceneManager.openPopupBlockerMessage = function() {
	this._scene.openPopupBlockerMessage();
};

//=============================================================================
// Game_Interpreter
//=============================================================================

Yanfly.LINK.Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    Yanfly.LINK.Game_Interpreter_pluginCommand.call(this, command, args)
    if (command === 'OpenNewTab') this.openNewTab(args);
		if (command === 'OpenNewWindow') this.openNewWindow(args);
};

Game_Interpreter.prototype.openNewTab = function(args) {
	TouchInput.clear();
	Input.clear();
	var url = String(args[0]);
	var win = window.open(url, '_blank');
	if (win) {
		win.focus();
	} else {
		SceneManager.openPopupBlockerMessage();
	}
};

Game_Interpreter.prototype.openNewWindow = function(args) {
	TouchInput.clear();
	Input.clear();
	var url = String(args[0]);
	var win = window.open(url);
	if (win) {
		win.focus();
	} else {
		SceneManager.openPopupBlockerMessage();
	}
};

//=============================================================================
// Window_TitleCommand
//=============================================================================

Yanfly.LINK.Window_TitleCommand_makeCommandList =
		Window_TitleCommand.prototype.makeCommandList;
Window_TitleCommand.prototype.makeCommandList = function() {
    Yanfly.LINK.Window_TitleCommand_makeCommandList.call(this);
		//this.addHomePageCommand();
};

Window_TitleCommand.prototype.addHomePageCommand = function() {
	this.addCommand(Yanfly.Param.HomePageText, 'homePage');
};

//=============================================================================
// Window_PopupBlocker
//=============================================================================

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

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

Window_PopupBlocker.prototype.initialize = function() {
    var width = Graphics.boxWidth;
    var height = this.fittingHeight(1);
    Window_Base.prototype.initialize.call(this, 0, 0, width, height);
		this.resizeWindow();
		this.refresh();
		this.openness = 0;
};

Window_PopupBlocker.prototype.resizeWindow = function() {
		this.width = this.windowWidth();
		this.createContents();
		this.x = (Graphics.boxWidth - this.width) / 2;
		this.y = (Graphics.boxHeight - this.height) / 2;
};

Window_PopupBlocker.prototype.windowWidth = function() {
		return this.textWidth(Yanfly.Param.PopupMessage);
};

Window_PopupBlocker.prototype.refresh = function() {
		this.contents.clear();
		this.drawText(Yanfly.Param.PopupMessage, 0, 0, this.contents.width);
};

//=============================================================================
// Scene_Base
//=============================================================================

Yanfly.LINK.Scene_Base_createWindowLayer =
		Scene_Base.prototype.createWindowLayer;
Scene_Base.prototype.createWindowLayer = function() {
		Yanfly.LINK.Scene_Base_createWindowLayer.call(this);
		this.createPopupBlockerMessage();
};

Scene_Base.prototype.createPopupBlockerMessage = function() {
    if (this._popupBlockerWindow) return;
		this._popupBlockerWindow = new Window_PopupBlocker();
		this.addWindow(this._popupBlockerWindow);
		this._popupCounter = 0;
};

Yanfly.LINK.Scene_Base_update = Scene_Base.prototype.update;
Scene_Base.prototype.update = function() {
    Yanfly.LINK.Scene_Base_update.call(this);
		this.updatePopupBlockerMessage();
};

Scene_Base.prototype.updatePopupBlockerMessage = function() {
		if (!this._popupBlockerWindow) return;
		if (this._popupBlockerWindow.isClosed()) return;
		if (--this._popupCounter > 0) return;
		this.closePopupBlockerMessage();
};

Scene_Base.prototype.openPopupBlockerMessage = function() {
		this._popupBlockerWindow.open();
		this._popupBlockerWindow.activate();
		this._popupCounter = 180;
};

Scene_Base.prototype.closePopupBlockerMessage = function() {
		if (!this._popupBlockerWindow) return;
		if (this._popupBlockerWindow.isClosed()) return;
		this._popupBlockerWindow.close();
		this._popupBlockerWindow.deactivate();
};

//=============================================================================
// Scene_Base
//=============================================================================

Yanfly.LINK.Scene_Title_createCommandWindow =
		Scene_Title.prototype.createCommandWindow;
Scene_Title.prototype.createCommandWindow = function() {
    Yanfly.LINK.Scene_Title_createCommandWindow.call(this);
		this._commandWindow.setHandler('homePage', this.commandHomePage.bind(this));
};

Scene_Title.prototype.commandHomePage = function() {
	TouchInput.clear();
	Input.clear();
	this._commandWindow.activate();

	const commander = GameStartUpWebSite.getInstance();
    commander.execute(Yanfly.Param.HomePageUrl);
	return;

	var win = window.open(Yanfly.Param.HomePageUrl, '_blank');
	if (win) {
		win.focus();
	} else {
		SceneManager.openPopupBlockerMessage();
	}
};

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

//=============================================================================
    // GameChildProcess
    //  node.jsのchild_processを用いてコマンド実行を実現する基底クラスです。
    //=============================================================================
    class GameChildProcess {
        constructor() {
            this._normalSwitchId   = yanflyParamNormalEndSwitch;
            this._abnormalSwitchId = yanflyParamAbnormalEndSwitch;
        }

        setResultSwitchId(normalSwitchId, abnormalSwitchId) {
            this.setNormalSwitchId(normalSwitchId || yanflyParamNormalEndSwitch);
            this.setAbnormalSwitchId(abnormalSwitchId || yanflyParamAbnormalEndSwitch);
        }

        setNormalSwitchId(switchId) {
            this._normalSwitchId = switchId;
        }

        setAbnormalSwitchId(switchId) {
            this._abnormalSwitchId = switchId;
        }

        execute() {
            this.executeChildProcess(this.getCommand.apply(this, arguments));
        }

        executeChildProcess(command) {
            this.outputDebugLog('*** Execute Command : ' + command);
            this.setResultSwitch(this._normalSwitchId, false);
            this.setResultSwitch(this._abnormalSwitchId, false);
            const childProcess = require('child_process');
            const promise = new Promise(function(resolve, reject) {
                childProcess.exec(command, function(error, stdout, stderr) {
                    if (stdout) this.outputDebugLog(stdout);
                    if (stderr) this.outputDebugLog(stderr);
                    return error ? reject(error) : resolve();
                }.bind(this));
            }.bind(this));
            promise.then(this.onNormalEnd.bind(this), this.onAbnormalEnd.bind(this));
        }

        onNormalEnd() {
            this.setResultSwitch(this._normalSwitchId, true);
            this.outputDebugLog('*** Command Normal End ***');
        }

        onAbnormalEnd(error) {
            this.setResultSwitch(this._abnormalSwitchId, true);
            this.outputErrorLog(error);
            this.outputDebugLog('*** Command Abnormal End ***');
        };

        setResultSwitch(switchId, value) {
            if (switchId > 0) {
                $gameSwitches.setValue(switchId, value);
            }
        }

        outputDebugLog() {
            this.outputLog(false, arguments);
        };

        outputErrorLog() {
            this.outputLog(true, arguments);
        };

        outputLog(errorFlg, args) {
            if (!$gameTemp.isPlaytest() && !errorFlg) return;
            //this.showDevTool();
            //console[errorFlg ? 'error' : 'log'].apply(console, args);
        }

        showDevTool() {
            const gameWindow = require('nw.gui').Window.get();
            if (gameWindow.isDevToolsOpen()) return;
            const devTool = gameWindow.showDevTools();
            devTool.moveTo(0, 0);
            devTool.resizeTo(gameWindow.screenX + gameWindow.outerWidth, gameWindow.screenY + gameWindow.outerHeight);
            gameWindow.focus();
        };

        getCommand() {
            return '';
        }

        static getInstance() {
            return this.isNwjs() ? (this.isWindows() ? this.getWindowsInstance() : this.getMacInstance()) :
                this.getNoNwjsInstance();
        }

        static getDefaultInstance() {
            return new GameEmptyProcess();
        }

        static getWindowsInstance() {
            return this.getDefaultInstance();
        }

        static getMacInstance() {
            return this.getDefaultInstance();
        }

        static getNoNwjsInstance() {
            return this.getDefaultInstance();
        }

        static isWindows() {
            return process.platform === 'win32';
        }

        static isNwjs() {
            return Utils.isNwjs();
        }
    }

    //=============================================================================
    // GameEmptyProcess
    //  実行不可能な環境では何も実行しません。
    //=============================================================================
    class GameEmptyProcess extends GameChildProcess {
        execute() {
            console.log('指定した動作はこの環境では実行できません。');
        }
    }

	//=============================================================================
    // GameFileDownload
    //  ファイルダウンロードを実現します。
    //=============================================================================
    class GameFileDownload extends GameChildProcess {
        execute(url, localDir) {
            const path        = require('path');
            const projectBase = path.dirname(process.mainModule.filename);
            const localPath   = path.join(projectBase, localDir) + path.basename(url, true);
            super.execute(url, localPath);
        }

        static getWindowsInstance() {
            return new GameFileDownloadWindows();
        }

        static getMacInstance() {
            return new GameFileDownloadMac();
        }
    }

    //=============================================================================
    // GameFileDownloadWindows
    //  Windowsでファイルダウンロードを実現します。
    //=============================================================================
    class GameFileDownloadWindows extends GameFileDownload {
        getCommand(url, localPath) {
            return `bitsadmin.exe /TRANSFER FILE_DOWNLOAD ${url} ${localPath}`;
        }
    }

    //=============================================================================
    // GameFileDownloadMac
    //  Macでファイルダウンロードを実現します。
    //=============================================================================
    class GameFileDownloadMac extends GameFileDownload {
        getCommand(url, localPath) {
            return `curl ${url} -o ${localPath}`;
        }
    }

    //=============================================================================
    // GameStartUpWebSite
    //  ウェブサイトを開きます。
    //=============================================================================
    class GameStartUpWebSite extends GameChildProcess {
        static getWindowsInstance() {
            return new GameStartUpWebSiteWindows();
        }

        static getMacInstance() {
            return new GameStartUpWebSiteMac();
        }

        static getNoNwjsInstance() {
            return new GameStartUpWebSiteNoNwjs();
        }
    }

    //=============================================================================
    // GameStartUpWebSiteWindows
    //  Windowsでウェブサイトを開きます。
    //=============================================================================
    class GameStartUpWebSiteWindows extends GameStartUpWebSite {
        getCommand(url) {
            return `rundll32.exe url.dll,FileProtocolHandler "${url}"`;
        }
    }

    //=============================================================================
    // GameStartUpWebSiteMac
    //  Macでファイルダウンロードを実現します。
    //=============================================================================
    class GameStartUpWebSiteMac extends GameStartUpWebSite {
        getCommand(url) {
            return `open "${url}"`
        }
    }

    //=============================================================================
    // GameStartUpWebSiteNoNwjs
    //  ブラウザでウェブサイトを開きます。
    //=============================================================================
    class GameStartUpWebSiteNoNwjs extends GameStartUpWebSite {
        execute(url) {
            window.open(url);
        }
    }