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

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

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

//=============================================================================
/*:
 * @plugindesc v1.02 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
 * @desc How to align the text for the command window.
 * left     center     right
 * @default center
 *
 * @param Finish Command
 * @desc The command text used for exiting the equip scene.
 * @default Finish
 *
 * @param Remove Text
 * @desc The text used to display the "Remove" command in the equip
 * item list.
 * @default Remove
 *
 * @param Remove Icon
 * @desc The icon used to display next to the "Remove" command in
 * the equip item list.
 * @default 16
 *
 * @param Empty Text
 * @desc The text used to display an "Empty" piece of equipment.
 * @default <Empty>
 *
 * @param Empty Icon
 * @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
 * @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
 * @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.
 *
 * ============================================================================
 * 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.02:
 * - Fixed an issue that did not keep HP and MP rates the same when using the
 * optimize and clear commands.
 * - Fixed an issue that resulted in null object errors.
 *
 * Version 1.01:
 * - Fixed a bug that did not update the stats properly when compared.
 *
 * Version 1.00:
 * - Finished plugin!
 */
/*:ja
 * @plugindesc クラスごとに独自の装備スロットを提供し、
 * 装備のシステムをより柔軟なものにできます。
 * @author Yanfly Engine Plugins
 *
 * @param ---一般---
 * @default
 *
 * @param Text Align
 * @desc コマンドウィンドウでのテキストの配置を変更します。
 * left(左)    center(中央)    right(右)
 * @default center
 *
 * @param Finish Command
 * @desc 装備シーンから出るときのテキストを指定します。
 * @default 終了
 *
 * @param Remove Text
 * @desc 装備アイテムリストで"外す"を表すテキストを指定します。
 * @default 外す
 *
 * @param Remove Icon
 * @desc 装備アイテムリストで"外す"を表すアイコンを指定します。
 * @default 16
 *
 * @param Empty Text
 * @desc 装備リストで、装備品が空であることを表すテキストを指定します。
 * @default <空き>
 *
 * @param Empty Icon
 * @desc 装備リストで、装備品が空であることを表すアイコンを指定します。
 * @default 16
 *
 * @param ---ルール---
 * @default
 *
 * @param Non-Removable Types
 * @desc ここで指定したタイプは常に何かアイテムを装備していなければなりません。
 * 複数のタイプIDを指定する場合はスペースで区切ってください。
 * @default 1
 *
 * @param Non-Optimized Types
 * @desc 最強装備の機能使用時に、ここで指定したタイプを無視させます。
 * 複数のタイプIDを指定する場合はスペースで区切ってください。
 * @default 5
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * このプラグインでは、装備のハンドリングに関するいくつかの要素を変更します。
 * 詳細は下記を参照してください:
 *
 * 1. Scene_Equip
 * Scene_Equipは見た目の変更を行います。主にメインメニューの見た目を統一して
 * プレイヤーにとって親しみやすいものへと変更します。更に、今後リリースされる
 * 拡張プラグインにもきちんと対応できるように、コマンドウィンドウについても
 * 最適化されています。
 *
 * 2. 装備タイプの扱い
 * 職業のノートにいくつかNotetagを加えるだけで、異なる職業がそれぞれの
 * セッティングを持つことができるようになります。以前は、マッチした名前を持った
 * 装備タイプは、単独としてバラバラに扱われていました。このプラグインでは、
 * 同じタイプの物として扱うことができます。
 *
 * 3. 装備ルール
 * 特定の装備タイプは外すことができなくなります。例として、このプラグインでは
 * 「武器スロットには常に何かしら装備していなくてはならない」というような設定が
 * 可能で、プレイヤーは武器を勝手に外すことはできなくなります。(イベントを通して
 * 解除させることもできます。) それに加えて、特定の装備タイプを指定して、
 * 最強装備を制限することもできます。アクセサリーのような装備品タイプに関しては
 * 手動で決定させた方が良いでしょう。
 *
 * 4. パラメータコントロール
 * Notetagを用いることで、装備パラメータに、大きな値やカスタマイズされた値を
 * 付与することができます。(コードを通して実行されます)
 * 装備品は固定の性能を持ったアイテムではなくなり、これにより、ゲームを通して
 * 性能が変動するようなものとなります。
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * 職業の装備設定を変更するには、下記のNotetagを用いてください。
 *
 * 職業のNotetags:
 *   <Equip Slot: x>      例: <Equip Slot: 1, 2, 3, 4, 5, 5, 5, 5>
 *   <Equip Slot: x, x, x>
 *   職業の装備スロットを x に変更してください。繰り返し同じ番号を使うことにより
 *   装備タイプを複製し、その職業は同タイプの装備を複数着けることができます。
 *   タイプIDを見つけるには、データベースのタイプタブを参照してください。
 *
 *   上記の方法が気に入らない場合は、下記のNotetagを代わりに用いてください。
 *
 *   <Equip Slot>            例: <Equip Slot>
 *    string                        Weapon
 *    string                        Armor
 *    string                        Accessory
 *    string                        Accessory
 *   </Equip Slot>                 </Equip Slot>
 *   'string'を装備タイプの名前に変えてください。非常に正確な照合のため、
 *   名前欄が完璧にマッチしない場合は、スロットはその職業と認められません。
 *   複数コピーされた名前欄は、その職業がそのタイプの装備を複数持てることを
 *   表しています。全て、前述のNotetagと同様に動作します。
 *
 * 武器と防具のNotetags:
 *   <stat: +x>
 *   <stat: -x>
 *   武器もしくは防具のステータスを、 x だけ増加・減少させます。
 *   "stat"の部分を"hp", "mp", "atk", "def", "mat", "mdf", "agi", "luk"
 *   のような特定のステータスに変更してください。この機能は、デフォルトの
 *   最大値の上限を無視して使うことができます。
 *   ここで成された変更は、ベースのパラメータを上書きします。
 *
 * ============================================================================
 * Lunatic Mode - Custom Parameters
 * ============================================================================
 *
 *   <Custom Parameters>  　　例: <Custom Parameters>
 *    code                          atk = $gameVariables.value(1);
 *    code                          mat = atk / 2;
 *    code                          all = $gameParty.members().length;
 *    code                         </Custom Parameters>
 *   </Code Parameters>
 *   パラメータに、コードによって適用されたレートを設定することができます。
 *   次のパラメータが定義されます: 'maxhp', 'maxmp', 'atk', 'def', 'mat', 'mdf',
 *   'agi', 'luk', and 'all'
 *   'all' のパラメータは、全てのパラメータに作用します。
 *   ここでの変更はベースのパラメータを上書きしませんが、追加保存されます。
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.02:
 * - Fixed an issue that did not keep HP and MP rates the same when using the
 * optimize and clear commands.
 * - Fixed an issue that resulted in null object errors.
 *
 * 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;
  DataManager.processEquipNotetags1($dataClasses);
  DataManager.processEquipNotetags2($dataWeapons);
  DataManager.processEquipNotetags2($dataArmors);
  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 array = [];
  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];
    }
    array.push(equip);
  }
  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 < array.length; ++i) {
    var equip = array[i];
    if (!equip) continue;
    var etypeId = equip.etypeId;
    if (!slots.contains(etypeId)) continue;
    var slotId = slots.indexOf(etypeId);
    if (this._equips[slotId].isWeapon() && this.isDualWield()) slotId += 1;
    this._equips[slotId].setObject(equip);
  }
  this.releaseUnequippableItems(true);
  this.recoverAll();
  this.refresh();
};

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

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

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 / this.actor().mhp;
  var mpRate = this.actor().mp / this.actor().mmp;
  Yanfly.Equip.Scene_Equip_commandOptimize.call(this);
  $gameTemp._optimizeEquipments = false;
  this.actor().setHp(parseInt(this.actor().mhp * hpRate));
  this.actor().setMp(parseInt(this.actor().mmp * mpRate));
  this._compareWindow.refresh();
  this._statusWindow.refresh();
};

Yanfly.Equip.Scene_Equip_commandClear = Scene_Equip.prototype.commandClear;
Scene_Equip.prototype.commandClear = function () {
  $gameTemp._clearEquipments = true;
  var hpRate = this.actor().hp / this.actor().mhp;
  var mpRate = this.actor().mp / this.actor().mmp;
  Yanfly.Equip.Scene_Equip_commandClear.call(this);
  $gameTemp._clearEquipments = false;
  this.actor().setHp(parseInt(this.actor().mhp * hpRate));
  this.actor().setMp(parseInt(this.actor().mmp * mpRate));
  this._compareWindow.refresh();
  this._statusWindow.refresh();
};

Yanfly.Equip.Scene_Equip_onSlotOk = Scene_Equip.prototype.onSlotOk;
Scene_Equip.prototype.onSlotOk = function () {
  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_onItemOk = Scene_Equip.prototype.onItemOk;
Scene_Equip.prototype.onItemOk = function () {
  var hpRate = this.actor().hp / this.actor().mhp;
  var mpRate = this.actor().mp / this.actor().mmp;
  Yanfly.Equip.Scene_Equip_onItemOk.call(this);
  this.actor().setHp(parseInt(this.actor().mhp * hpRate));
  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._itemWindow.hide();
};

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

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

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

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


code:
//=============================================================================
// Yanfly Engine Plugins - Event Chase Player
// YEP_EventChasePlayer.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.ECP = Yanfly.ECP || {};

//=============================================================================
/*:
 * @plugindesc v1.00 When a player is in the proximity of a certain event,
 * the event will start chasing or fleeing from the player.
 * @author Yanfly Engine Plugins
 *
 * @param Sight Lock
 * @desc This is the number of frames for how long an event chases
 * the player if 'this._seePlayer = true' is used.
 * @default 300
 *
 * @param See Player
 * @desc Does the event have to be able to see the player by default?
 * NO - false     YES - true
 * @default true
 *
 * @param Alert Timer
 * @desc This is the number of frames that must occur before the
 * alert balloon will show up on the same event.
 * @default 120
 *
 * @param Alert Balloon
 * @desc This is the default balloon used when the player is seen.
 * Refer to balloon ID's.
 * @default 1
 *
 * @param Alert Sound
 * @desc This is the default sound played when the player is seen.
 * @default Attack1
 *
 * @param Alert Common Event
 * @desc The default common event played when the player is seen.
 * Use 0 if you do not wish to use a Common Event.
 * @default 0
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin allows you to make events that will chase the player or flee
 * from the player when the player enters within range of the event or when the
 * event sees the player.
 *
 * ============================================================================
 * How to Use
 * ============================================================================
 *
 * Insert these lines into the script call window within the Movement Route
 * event to give an event the chase or flee flag.
 *
 * Note: This doesn’t work with players.
 *
 * Script Call lines
 *  this._chaseRange = x       Event will chase player if reaching x range.
 *  this._fleeRange = x        Event will flee from player if reaching x range.
 *  this._chaseSpeed = x       Event's movement speed when chasing.
 *  this._fleeSpeed = x        Event's movement speed when fleeing.
 *  this._sightLock = x        Event will flee/chase player for x frames.
 *  this._seePlayer = true     Requires the event to be able to see player.
 *  this._seePlayer = false    Doesn't require event to be able to see player.
 *  this._alertBalloon = x     This balloon will play when player is seen.
 *  this._alertSound = x       This sound will play when player is seen.
 *  this._alertCommonEvent = x This event will play when player is seen.
 *
 * It is best to play this inside of a custom move route for the event at a
 * high frequency rate. Keep in mind these effects only occur after the setting
 * is made and ran, which means upon loading a map, if the event with a low
 * frequency hasn't loaded up 'this._chaseRange = x' in its movement queue yet,
 * the event will not chase the player just yet.
 */
/*:ja
 * @plugindesc プレイヤーが近づいた際に、イベントがプレイヤーを追いかけたり
 * プレイヤーから逃げるアクションを取ります
 * @author Yanfly Engine Plugins
 *
 * @param Sight Lock
 * @desc 'seePlayer'がtrueの時、イベントがプレイヤーを追いかける時間を設定します(フレーム単位)
 * @default 300
 *
 * @param See Player
 * @desc イベントがプレイヤーを認識する必要があるか設定します
 * NO - false     YES - true
 * @default true
 *
 * @param Alert Timer
 * @desc イベント上でフキダシを表示するまでにかかるフレーム数を指定します
 * @default 120
 *
 * @param Alert Balloon
 * @desc プレイヤーが認識された際に表示される、フキダシを指定します
 * @default 1
 *
 * @param Alert Sound
 * @desc プレイヤーが認識された際に表示される、サウンドを指定します
 * @default Attack1
 *
 * @param Alert Common Event
 * @desc プレイヤーが認識された際に再生される、コモンイベントを指定します
 * コモンイベントを利用しない場合は、0を指定してください
 * @default 0
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * このプラグインでは、プレイヤーを追いかけるイベント、もしくは
 * プレイヤーから逃げるイベントを作成することができます。
 * プレイヤーがイベントから一定の距離範囲内に入った時や
 * イベントがプレイヤーを認識した際に発動させることができます。
 *
 * ============================================================================
 * How to Use
 * ============================================================================
 *
 * 下記のコードをスクリプトコールウィンドウ内の、
 * Movement Routeイベント内に挿入することで、そのイベントに
 * 追跡もしくは逃走のフラグを付与することができます。
 *
 * 注＊プレイヤーに対しては無効です。
 *
 * <スクリプトコール>
 *  this._chaseRange = x
 *              →x の距離内に入った時、イベントがプレイヤーを追いかけます
 *  this._fleeRange = x
 *              →x の距離内に入った時、イベントはプレイヤーから逃げます
 *  this._chaseSpeed = x
 *              →追いかける時のイベントの速度 x を決定します
 *  this._fleeSpeed = x
 *              →逃げる時のイベントの速度 x を決定します
 *  this._sightLock = x
 *              →追いかける/逃げる際のイベントフレームレート x を決定します
 *  this._seePlayer = true
 *              →イベントはプレイヤーを認識する必要があります
 *  this._seePlayer = false
 *              →イベントはプレイヤーを認識する必要がありません
 *  this._alertBalloon = x
 *              →プレイヤーが認識されると、x というフキダシを表示します
 *  this._alertSound = x
 *              →プレイヤーが認識されると、x というサウンドを再生します
 *  this._alertCommonEvent = x
 *              →プレイヤーが認識されると、x というイベントを再生します
 *
 * カスタムした移動ルート内でイベントを再生させる際は、
 * 移動頻度はなるべく高く設定するようにしてください。
 *
 * 設定が完了し有効になるまでは、これらのエフェクトは発動しません。
 * 移動頻度の低いイベントですと、マップロード中に'this._chaseRange = x'の
 * 読み込みを完了できず、プレイヤーを追いかけなくなってしまう可能性があります。
 *
 */

//=============================================================================

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

Yanfly.Parameters = PluginManager.parameters("YEP_EventChasePlayer");
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.ECPSightLock = Number(Yanfly.Parameters["Sight Lock"]);
Yanfly.Param.ECPSeePlayer = String(Yanfly.Parameters["See Player"]);
Yanfly.Param.ECPAlertTimer = Number(Yanfly.Parameters["Alert Timer"]);
Yanfly.Param.ECPAlertBalloon = Number(Yanfly.Parameters["Alert Balloon"]);
Yanfly.Param.ECPAlertSound = String(Yanfly.Parameters["Alert Sound"]);
Yanfly.Param.ECPAlertEvent = Number(Yanfly.Parameters["Alert Common Event"]);

//=============================================================================
// Main Code
//=============================================================================

Yanfly.ECP.Game_Event_setupPage = Game_Event.prototype.setupPage;
Game_Event.prototype.setupPage = function () {
  Yanfly.ECP.Game_Event_setupPage.call(this);
  this.clearChaseSettings();
};

Game_Event.prototype.clearChaseSettings = function () {
  this._alertBalloon = Yanfly.Param.ECPAlertBalloon;
  this._alertCommonEvent = Yanfly.Param.ECPAlertEvent;
  this._alertLock = 0;
  this._alertPlayer = false;
  this._alertSound = Yanfly.Param.ECPAlertSound;
  this._alertTimer = 0;
  this._chasePlayer = false;
  this._chaseRange = 0;
  this._chaseSpeed = this._moveSpeed;
  this._defaultSpeed = this._moveSpeed;
  this._fleePlayer = false;
  this._fleeRange = 0;
  this._fleeSpeed = this._moveSpeed;
  this._seePlayer = eval(Yanfly.Param.ECPSeePlayer);
  this._sightLock = eval(Yanfly.Param.ECPSightLock);
};

Yanfly.ECP.Game_Event_updateSelfMovement =
  Game_Event.prototype.updateSelfMovement;
Game_Event.prototype.updateSelfMovement = function () {
  if (Imported.YEP_StopAllMove && $gameSystem.isEventMoveStopped()) return;
  this.updateChaseDistance();
  this.updateFleeDistance();
  this.updateChaseMovement();
};

Yanfly.ECP.Game_Event_update = Game_Event.prototype.update;
Game_Event.prototype.update = function () {
  Yanfly.ECP.Game_Event_update.call(this);
  this.updateAlert();
};

Game_Event.prototype.canSeePlayer = function () {
  if (!this._seePlayer) return false;
  var sx = this.deltaXFrom($gamePlayer.x);
  var sy = this.deltaYFrom($gamePlayer.y);
  if (Math.abs(sx) > Math.abs(sy)) {
    var direction = sx > 0 ? 4 : 6;
  } else {
    var direction = sy > 0 ? 8 : 2;
  }
  if (direction === this.direction()) {
    this._alertLock = this._sightLock;
    return true;
  }
  return false;
};

Game_Event.prototype.updateChaseDistance = function () {
  if (this._erased) return;
  if (this._chaseRange <= 0) return;
  var dis = Math.abs(this.deltaXFrom($gamePlayer.x));
  dis += Math.abs(this.deltaYFrom($gamePlayer.y));
  if (this.chaseConditions(dis)) {
    this._chasePlayer = true;
    this.setMoveSpeed(this._chaseSpeed);
  } else if (this._chasePlayer) {
    this._chasePlayer = false;
    this.setMoveSpeed(this._defaultSpeed);
    if (this._alertTimer <= 0) this._alertPlayer = false;
  }
};

Game_Event.prototype.chaseConditions = function (dis) {
  if (this._alertLock > 0) return true;
  if (dis <= this._chaseRange && this.canSeePlayer()) return true;
  if (dis <= this._chaseRange && !this._seePlayer) {
    this._alertLock = this._sightLock;
    return true;
  }
  return false;
};

Game_Event.prototype.updateFleeDistance = function () {
  if (this._erased) return;
  if (this._fleeRange <= 0) return;
  var dis = Math.abs(this.deltaXFrom($gamePlayer.x));
  dis += Math.abs(this.deltaYFrom($gamePlayer.y));
  if (this.fleeConditions(dis)) {
    this._fleePlayer = true;
    this.setMoveSpeed(this._fleeSpeed);
  } else if (this._fleePlayer) {
    this._fleePlayer = false;
    this.setMoveSpeed(this._defaultSpeed);
    if (this._alertTimer <= 0) this._alertPlayer = false;
  }
};

Game_Event.prototype.fleeConditions = function (dis) {
  if (this._alertLock > 0) return true;
  if (dis <= this._fleeRange && this.canSeePlayer()) return true;
  if (dis <= this._fleeRange && !this._seePlayer) {
    this._alertLock = this._sightLock;
    return true;
  }
  return false;
};

Game_Event.prototype.updateChaseMovement = function () {
  if (this._stopCount > 0 && this._chasePlayer) {
    this.moveTowardPlayer();
  } else if (this._stopCount > 0 && this._fleePlayer) {
    this.moveAwayFromPlayer();
  } else {
    Yanfly.ECP.Game_Event_updateSelfMovement.call(this);
  }
};

Game_Event.prototype.updateAlert = function () {
  if (this._erased) return;
  this._alertLock--;
  if (this.alertConditions()) this.activateAlert();
  if (this._alertPlayer) this._alertTimer--;
};

Game_Event.prototype.alertConditions = function () {
  return (this._chasePlayer || this._fleePlayer) && !this._alertPlayer;
};

Game_Event.prototype.activateAlert = function () {
  if (this._alertBalloon >= 0) this.requestBalloon(this._alertBalloon);
  this._alertPlayer = true;
  this._alertTimer = Yanfly.Param.ECPAlertTimer;
  this.playAlertSound();
  this.playAlertCommonEvent();
};

Game_Event.prototype.playAlertSound = function () {
  if (this._alertSound === "") return;
  var sound = {
    name: this._alertSound,
    volume: 100,
    pitch: 100,
    pan: 100,
  };
  AudioManager.playSe(sound);
};

Game_Event.prototype.playAlertCommonEvent = function () {
  if (this._alertCommonEvent <= 0) return;
  $gameTemp.reserveCommonEvent(this._alertCommonEvent);
};

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

repo_name: dazed/translations

license: unknown


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

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

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

//=============================================================================
/*:
 * @plugindesc v1.00 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.
 */
/*:ja
 * @plugindesc タイトル画面やゲーム内から、
 * プレイヤーにWebページを開かせることができます
 * @author Yanfly Engine Plugins
 *
 * @param Home Page URL
 * @desc タイトル画面に設置したいWebサイトのリンクを挿入してください。
 * 不要な場合はブランクにしておいてください。
 * @default https://www.google.com/
 *
 * @param Home Page Text
 * @desc タイトル画面に設置するWebサイトの表示名を指定します
 * @default Home Page
 *
 * @param Popup Blocker Notice
 * @desc ポップアップブロックによってブロックされた際に、
 * プレイヤーにそれを知らせる文章を指定します
 * @default ポップアップブロックによってブロックされました
 *
 * @help
 * ============================================================================
 * Introduction                                                     .
 * ============================================================================
 *
 * このプラグインでは、タイトル画面のコマンドウィンドウ下部に
 * Webページへのリンクを設置することができます。
 * プラグインのパラメーター内でURLを変更することで、
 * リンク先を変更することができます。
 *
 * ============================================================================
 * Plugin Commands
 * ============================================================================
 *
 * プレイヤーに任意のリンクを開かせたいときは、下記のコマンドを用いてください。
 *
 * <プラグインコマンド>
 *   OpenNewTab http://www.google.com/     新規タブでリンクを開きます
 *   OpenNewWindow http://www.google.com/  新規ウィンドウでリンクを開きます
 *
 * ブラウザによっては上記2種類のコマンドがうまく識別されない場合があります。
 */

//=============================================================================

//=============================================================================
// 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 () {
  if (Yanfly.Param.HomePageUrl.length <= 0) return;
  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 () {
  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();
  var win = window.open(Yanfly.Param.HomePageUrl, "_blank");
  if (win) {
    win.focus();
  } else {
    SceneManager.openPopupBlockerMessage();
  }
};

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