code:
//=============================================================================
// Yanfly Engine Plugins - Extra Enemy Drops
// YEP_ExtraEnemyDrops.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.EED = Yanfly.EED || {};
Yanfly.EED.version = 1.08;

//=============================================================================
 /*:
 * @plugindesc v1.08 Allows your enemies to drop more than just three
 * items as per the editor's limit.
 * @author Yanfly Engine Plugins
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * By default, RPG Maker MV limits enemies to only drop up to 3 items max and
 * at very limited drop rates. This plugin allows you to add more than 3 items
 * at drop. In addition to having more than 3 drops, this plugin also allows
 * you to expand the enemy drops to have conditional drops, drops that will
 * only appear before the player if certain conditions are met.
 *
 * ============================================================================
 * Generic Drop - Notetags
 * ============================================================================
 *
 * Use the following notetags to determine extra enemy drops. These drops will
 * drop normally without any special conditions other than having to go through
 * and pass a random number generator.
 *
 * Enemy Notetags:
 *   <Item x: y%>
 *   <Weapon x: y%>
 *   <Armor x: y%>
 *   Adds item, weapon, or armor ID of x to the enemy's drop pool with a y%
 *   chance of dropping the item. Insert multiples of this notetag to add more
 *   drop items for the enemy drop pool.
 *
 *   <Enemy Drops>
 *    Item x: y%
 *    Weapon x: y%
 *    Armor x: y%
 *   </Enemy Drops>
 *   Alternatively, using the above notetag format will allow you to group a
 *   large number of enemy drops together. Replace x with the item, weapon, or
 *   armor ID to give the item a drop rate of y%.
 *
 *   <Drop Potion: x%>
 *   <Drop Short Sword: x%>
 *   <Drop Feather Cap: x%>
 *   If you prefer to use names instead, you can use the above format for the
 *   notetags. This will make the named item have a drop rate of x%. If you
 *   have multiple items in your database with the same name, priority will be
 *   given to the item with the highest ID in the order of item, weapons, then
 *   armors. Insert multiple multiples of this notetag to add more drop items
 *   for the enemy drop pool.
 *
 *   <Enemy Drops>
 *    Potion: x%
 *    Short Sword: x%
 *    Feather Cap: x%
 *   </Enemy Drops>
 *   Alternatively, you can write your notetag like such to group together a
 *   list of named items. This will make the named item have a drop rate of x%.
 *   If you have multiple items in your database with the same name, priority
 *   will be given to the item with the highest ID in the order of item,
 *   weapons, then armors. Insert multiple multiples of this notetag to add
 *   more drop items for the enemy drop pool.
 *
 * ============================================================================
 * Conditional Drop - Notetags
 * ============================================================================
 *
 * Sometimes, you want certain conditions to be met before enemies will drop a
 * specific item. These conditional drops would have a 0% chance otherwise. For
 * each condition met, you can increase or decrease the drop rate. Use the
 * below format to create a conditional drop.
 *
 * Enemy Notetags:
 *   <Conditional Item x Drop>
 *    condition: +y%
 *    condition: -y%
 *   </Conditional Item x Drop>
 *
 *   <Conditional Weapon x Drop>
 *    condition: +y%
 *    condition: -y%
 *   </Conditional Weapon x Drop>
 *
 *   <Conditional Armor x Drop>
 *    condition: +y%
 *    condition: -y%
 *   </Conditional Armor x Drop>
 *   The above notetags will create the conditions for item, weapon, or armor x
 *   to drop. Insert various conditions in between the notetags to produce the
 *   conditional rate increases or decreases of y% for the drop.
 *
 *   <Conditional Named Drop>
 *    condition: +y%
 *    condition: -y%
 *   </Conditional Named Drop>
 *   If you prefer to name your drop, use the above format. If database entries
 *   have matching names, priority will be given to the item with the highest
 *   ID in the order of items, weapons, then armor. Insert various conditions
 *   in between the notetags to produce the conditional rate increases or
 *   decreases for y% for the drop.
 *
 * The following are various conditions you may use:
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * ALIVE MEMBERS EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This checks the number of alive party members the player has when the drops
 * are being calculated and made and runs it against an eval check.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Alive Members > 1: +20%
 *            Alive Members === 2: +25%
 *            Alive Members <= 3: -30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * ALWAYS
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This condition will always pass. This can be used as setting a base rate for
 * the item drop.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Always: +50%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * item x COUNT EVAL
 * weapon x COUNT EVAL
 * armor x COUNT EVAL
 * named item COUNT EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This checks the quantity of specific items, weapons, armors, and/or named
 * items you have. If you choose a named item and multiple database entries
 * share the name of that named item, priority will be given to the highest ID
 * in the order of items, weapons, and then armor.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Item 1 Count > 1: +20%
 *            Weapon 2 Count === 2: +25%
 *            Armor 3 Count <= 3: -30%
 *            Potion Count >= 4: +35%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * DEAD MEMBERS EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This checks the number of dead party members the player has when the drops
 * are being calculated and made and runs it against an eval check.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Dead Members > 1: +20%
 *            Dead Members === 2: +25%
 *            Dead Members <= 3: -30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * DEATH TURN EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This will run an eval check to compare the turn number the enemy has died.
 * This effect requires the Battle Engine Core.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Death Turn > 5: +10%
 *            Death Turn === 5: +20%
 *            Death Turn <= 4: +30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * ENEMY LEVEL EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This will run an eval check to compare the enemy's level. This effect
 * requires the YEP Enemy Levels plugin.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Enemy Level === 10: +30%
 *            Enemy Level <= 5: -20%
 *            Enemy Level >= 15: +10%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * EVAL code
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This will run an eval check for the code you've inserted. If it returns true
 * then the condition is met.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Eval user.name() === 'Bat A': +30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * LAST STRIKE SKILL X
 * LAST STRIKE ITEM X
 * LAST STRIKE named
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This checks to see if the last strike on the enemy is item x, skill x, or a
 * named action. If a named action is used and multiple database entries share
 * the name of the action, priority will be given to the highest ID in the
 * order of skills then items.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Last Strike Skill 40: +20%
 *            Last Strike Item 50: -30%
 *            Last Strike Firaga: +40%
 *            Last Strike Ice Bomb: -50%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * PARTY MEMBERS EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This checks the number of party members (dead or alive) the player has when
 * the drops are being calculated and made and runs it against an eval check.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Party Members > 1: +20%
 *            Party Members === 2: +25%
 *            Party Members <= 3: -30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * RANDOM X%
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This condition has a random x% chance to pass.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Random 20%: +40%
 *            Random 30%: -60%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * TIMES ELEMENT X STRUCK EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This compares the number of times the enemy has been struck by element x.
 * You can also replace x with the name of the item.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Times Element Fire Struck > 6: +10%
 *            Times Element 3 Struck === 5: -10%
 *            Times Element Thunder <= 4: +20%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * TIMES ITEM X STRUCK EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This compares the number of times the enemy has been struck by item x. You
 * can also replace x with the name of the item.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Times Item Bomb Struck > 6: +10%
 *            Times Item 42 Struck === 5: -10%
 *            Times Item Uni Struck <= 4: +20%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * TIMES SKILL X STRUCK EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This compares the number of times the enemy has been struck by skill x. You
 * can also replace x with the name of the skill.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Times Skill Firaga Struck > 6: +10%
 *            Times Skill 40 Struck === 5: -10%
 *            Times Skill Thundaga Struck <= 4: +20%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * TIMES STATE X STRUCK EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This compares the number of times the enemy has been struck by state x.
 * You can also replace x with the name of the state.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Times State 4 Struck > 6: +10%
 *            Times State Blind Struck === 5: -10%
 *            Times State Silence Struck <= 4: +20%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * TIMES STYPE X STRUCK EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This compares the number of times the enemy has been struck by skill type x.
 * You can also replace x with the name of the skill type.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Times SType 1 Struck > 6: +10%
 *            Times SType Magic Struck === 5: -10%
 *            Times SType Special Struck <= 4: +20%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * SWITCH X ON
 * SWITCH X OFF
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Replace X with a switch ID. If switch X is ON or OFF, the condition is met.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Switch 5 ON: +10%
 *            Switch 6 OFF: -10%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * TURN EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This will run an eval check to compare the number of turns the battle has
 * gone on for until the time the drops have been made.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Turn > 5: +10%
 *            Turn === 5: +20%
 *            Turn <= 4: +30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 * VARIABLE X EVAL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Replace X with a variable ID. This will run an eval check to compare the
 * variable's value to see if it meets the conditions.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Example:   Variable 5 > 10: +20%
 *            Variable 6 === 11: +25%
 *            Variable 7 <= 12: -30%
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 *
 * ============================================================================
 * Lunatic Mode - New JavaScript Functions~
 * ============================================================================
 *
 * For those with JavaScript proficiency, you can make use of some of these
 * newly added functions when you do an eval check for the enemy:
 *
 * enemy.deathTurn()
 * This will return the turn the enemy died as an integer.
 *
 * enemy.killer()
 * This will return the enemy's killer. If you would like to reference the
 * killer's HP, it'd be enemy.killer().hp
 *
 * enemy.lastStruckAction()
 * This will return either a skill or item that the enemy was last struck with.
 *
 * enemy.timesStruckSkill(skill ID)
 * This will return a number value for the number of times it was struck by
 * the skill referenced by the skill ID.
 *
 * enemy.timesStruckItem(item ID)
 * This will return a number value for the number of times it was struck by
 * the item referenced by the item ID.
 *
 * enemy.timesStruckSType(skill type ID)
 * This will return a number value for the number of times it was struck by
 * skills of the skill type ID.
 *
 * enemy.timesStruckState(state ID)
 * This will return a number value for the number of times it was struck by
 * the state referenced by the state ID.
 *
 * enemy.timesStruckElement(element ID)
 * This will return a number value for the number of times it was struck by
 * the element referenced by the element ID.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.08:
 * - Plugin compatibility update with Element Core to count multiple elemental
 * skills from counting the times struck by each element.
 *
 * Version 1.07:
 * - Lunatic Mode fail safes added.
 *
 * Version 1.06:
 * - New Conditional Drop line: Enemy Level. If you are using the
 * YEP Enemy Level plugin, this will allow conditional drops to check around
 * the enemy's level at death.
 *
 * Version 1.05:
 * - Eval condition is given more priority as to not be triggered by other
 * conditions.
 *
 * Version 1.04:
 * - Updated for RPG Maker MV version 1.1.0.
 *
 * Version 1.03:
 * - Fixed documentation errors.
 * - Fixed a bug with the Turn Count condition.
 *
 * Version 1.02:
 * - Fixed a bug that crashed the game when a conditional drop is made based
 * off of an item count.
 *
 * Version 1.01:
 * - Added a new section: Lunatic Mode - New JavaScript Functions to allow
 * easier reference for the eval condition.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

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

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

Yanfly.Param.Variables = String(Yanfly.Parameters['Variables']);

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

Yanfly.EED.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
  if (!Yanfly.EED.DataManager_isDatabaseLoaded.call(this)) return false;
  if (!Yanfly._loaded_YEP_ExtraEnemyDrops) {
    this.processEEDNotetagsI($dataItems);
    this.processEEDNotetagsW($dataWeapons);
    this.processEEDNotetagsA($dataArmors);
    this.processEEDNotetagsS($dataSkills);
    this.processEEDNotetagsT($dataStates);
    this.processEEDNotetagsSys($dataSystem);
    this.processEEDNotetags1($dataEnemies);
    Yanfly._loaded_YEP_ExtraEnemyDrops = true;
  }
  return true;
};

DataManager.processEEDNotetagsI = function(group) {
  if (Yanfly.ItemIdRef) return;
  Yanfly.ItemIdRef = {};
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    if (obj.name.length <= 0) continue;
    Yanfly.ItemIdRef[obj.name.toUpperCase()] = n;
  }
};

DataManager.processEEDNotetagsW = function(group) {
  if (Yanfly.WeaponIdRef) return;
  Yanfly.WeaponIdRef = {};
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    if (obj.name.length <= 0) continue;
    Yanfly.WeaponIdRef[obj.name.toUpperCase()] = n;
  }
};

DataManager.processEEDNotetagsA = function(group) {
  if (Yanfly.ArmorIdRef) return;
  Yanfly.ArmorIdRef = {};
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    if (obj.name.length <= 0) continue;
    Yanfly.ArmorIdRef[obj.name.toUpperCase()] = n;
  }
};

DataManager.processEEDNotetagsS = function(group) {
  if (Yanfly.SkillIdRef) return;
  Yanfly.SkillIdRef = {};
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    if (obj.name.length <= 0) continue;
    Yanfly.SkillIdRef[obj.name.toUpperCase()] = n;
  }
};

DataManager.processEEDNotetagsT = function(group) {
  if (Yanfly.StateIdRef) return;
  Yanfly.StateIdRef = {};
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    if (obj.name.length <= 0) continue;
    Yanfly.StateIdRef[obj.name.toUpperCase()] = n;
  }
};

DataManager.processEEDNotetagsSys = function(group) {
  Yanfly.STypeIdRef = {};
  for (var i = 1; i < group.skillTypes.length; ++i) {
    var name = group.skillTypes[i].toUpperCase();
    name = name.replace(/\\I\[(\d+)\]/gi, '');
    Yanfly.STypeIdRef[name] = i;
  }
  Yanfly.ElementIdRef = {};
  for (var i = 1; i < group.elements.length; ++i) {
    var name = group.elements[i].toUpperCase();
    name = name.replace(/\\I\[(\d+)\]/gi, '');
    Yanfly.ElementIdRef[name] = i;
  }
};

DataManager.processEEDNotetags1 = function(group) {
  var noteD1 = /<(?:ITEM|DROP ITEM)[ ](\d+):[ ](\d+)([%％])>/i;
  var noteD2 = /<(?:WEAPON|DROP WEAPON)[ ](\d+):[ ](\d+)([%％])>/i;
  var noteD3 = /<(?:ARMOR|DROP armor)[ ](\d+):[ ](\d+)([%％])>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    if (obj.dropsMade) continue;
    var notedata = obj.note.split(/[\r\n]+/);

    obj.dropsMade = true;
    obj.conditionalDropItems = [];
    var conditionalLines = [];
    var evalMode = 'none';

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(noteD1)) {
        var id = parseInt(RegExp.$1);
        var rate = parseFloat(RegExp.$2) * 0.01;
        this.createEnemyDrop(obj, id, rate, 1);
      } else if (line.match(noteD2)) {
        var id = parseInt(RegExp.$1);
        var rate = parseFloat(RegExp.$2) * 0.01;
        this.createEnemyDrop(obj, id, rate, 2);
      } else if (line.match(noteD3)) {
        var id = parseInt(RegExp.$1);
        var rate = parseFloat(RegExp.$2) * 0.01;
        this.createEnemyDrop(obj, id, rate, 3);
      } else if (line.match(/<DROP[ ](.*):[ ](\d+)([%％])>/i)) {
        var name = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(RegExp.$2) * 0.01;
        if (Yanfly.ItemIdRef[name]) {
          var id = Yanfly.ItemIdRef[name];
          var kind = 1;
        } else if (Yanfly.WeaponIdRef[name]) {
          var id = Yanfly.WeaponIdRef[name];
          var kind = 2;
        } else if (Yanfly.ArmorIdRef[name]) {
          var id = Yanfly.ArmorIdRef[name];
          var kind = 3;
        } else {
          continue;
        }
        this.createEnemyDrop(obj, id, rate, kind);
      } else if (line.match(/<(?:ENEMY DROP|ENEMY DROPS)>/i)) {
        var evalMode = 'drops';
      } else if (line.match(/<\/(?:ENEMY DROP|ENEMY DROPS)>/i)) {
        var evalMode = 'none';
      } else if (evalMode === 'drops') {
        if (line.match(/ITEM[ ](\d+):[ ](\d+)([%％])/i)) {
          var id = parseInt(RegExp.$1);
          var rate = parseFloat(RegExp.$2) * 0.01;
          this.createEnemyDrop(obj, id, rate, 1);
        } else if (line.match(/WEAPON[ ](\d+):[ ](\d+)([%％])/i)) {
          var id = parseInt(RegExp.$1);
          var rate = parseFloat(RegExp.$2) * 0.01;
          this.createEnemyDrop(obj, id, rate, 2);
        } else if (line.match(/ARMOR[ ](\d+):[ ](\d+)([%％])/i)) {
          var id = parseInt(RegExp.$1);
          var rate = parseFloat(RegExp.$2) * 0.01;
          this.createEnemyDrop(obj, id, rate, 3);
        } else if (line.match(/(.*):[ ](\d+)([%％])/i)) {
          var name = String(RegExp.$1).toUpperCase();
          var rate = parseFloat(RegExp.$2) * 0.01;
          if (Yanfly.ItemIdRef[name]) {
            var id = Yanfly.ItemIdRef[name];
            var kind = 1;
          } else if (Yanfly.WeaponIdRef[name]) {
            var id = Yanfly.WeaponIdRef[name];
            var kind = 2;
          } else if (Yanfly.ArmorIdRef[name]) {
            var id = Yanfly.ArmorIdRef[name];
            var kind = 3;
          } else {
            continue;
          }
          this.createEnemyDrop(obj, id, rate, kind);
        }
      } else if (line.match(/<CONDITIONAL[ ](.*)[ ]DROP>/i)) {
        var evalMode = 'conditionalDrop';
        conditionalLines = [];
      } else if (line.match(/<\/CONDITIONAL[ ](.*)[ ]DROP>/i)) {
        var evalMode = 'none';
        var name = String(RegExp.$1).toUpperCase();
        if (name.match(/ITEM[ ](\d+)/i)) {
          var item = $dataItems[parseInt(RegExp.$1)];
        } else if (name.match(/WEAPON[ ](\d+)/i)) {
          var item = $dataWeapons[parseInt(RegExp.$1)];
        } else if (name.match(/ARMOR[ ](\d+)/i)) {
          var item = $dataArmors[parseInt(RegExp.$1)];
        } else if (Yanfly.ItemIdRef[name]) {
          var id = Yanfly.ItemIdRef[name];
          var item = $dataItems[id];
        } else if (Yanfly.WeaponIdRef[name]) {
          var id = Yanfly.WeaponIdRef[name];
          var item = $dataWeapons[id];
        } else if (Yanfly.ArmorIdRef[name]) {
          var id = Yanfly.ArmorIdRef[name];
          var item = $dataArmors[id];
        } else {
          continue;
        }
        if (!item) continue;
        var arr = [item, conditionalLines];
        obj.conditionalDropItems.push(arr);
        conditionalLines = [];
      } else if (evalMode === 'conditionalDrop') {
        conditionalLines.push(line);
      }
    }
  }
};

DataManager.createEnemyDrop = function(obj, dataId, rate, kind) {
    var dropItem = {
      dataId: dataId,
      denominator: 1 / rate,
      kind: kind
    }
    obj.dropItems.push(dropItem);
};

//=============================================================================
// Game_BattlerBase
//=============================================================================

Yanfly.EED.Game_BattlerBase_addNewState =
    Game_BattlerBase.prototype.addNewState;
Game_BattlerBase.prototype.addNewState = function(stateId) {
    Yanfly.EED.Game_BattlerBase_addNewState.call(this, stateId);
    if (this.isEnemy()) this.markStruckState(stateId);
    if (stateId === this.deathStateId() && this.isEnemy()) {
        this.markDeathTurn();
    }
};

//=============================================================================
// Game_Enemy
//=============================================================================

Yanfly.EED.Game_Enemy_makeDropItems = Game_Enemy.prototype.makeDropItems;
Game_Enemy.prototype.makeDropItems = function() {
    var drops = Yanfly.EED.Game_Enemy_makeDropItems.call(this);
    drops = drops.concat(this.makeConditionalDropItems());
    return drops;
};

Game_Enemy.prototype.makeConditionalDropItems = function() {
    var drops = DropManager.setup(this);
    return drops;
};

Game_Enemy.prototype.markDeathTurn = function() {
    if (this._selfTurnCount !== undefined) {
      this._deathTurn = this._selfTurnCount;
    } else {
      this._deathTurn = $gameTroop.turnCount();
    }
};

Game_Enemy.prototype.markStruckState = function(id) {
    this.createTimesStruck();
    this._struckStates[id] = this._struckStates[id] || 0;
    this._struckStates[id] = this._struckStates[id] + 1;
};

Game_Enemy.prototype.deathTurn = function() {
    return this._deathTurn || 0;
};

Game_Enemy.prototype.createTimesStruck = function() {
    if (this._struckSkills === undefined) this._struckSkills = {};
    if (this._struckSType === undefined) this._struckSType = {};
    if (this._struckItems === undefined) this._struckItems = {};
    if (this._struckStates === undefined) this._struckStates = {};
    if (this._struckElements === undefined) this._struckElements = {};
    if (this._lastStruckId === undefined) this._lastStruckId = 0;
    if (this._lastStruckSkill === undefined) this._lastStruckSkill = false;
    if (this._lastStruckActor === undefined) this._lastStruckActor = null;
};

Game_Enemy.prototype.lastStruckAction = function() {
    if (this._lastStruckId === undefined) this.createTimesStruck();
    if (this._lastStruckSkill === undefined) this.createTimesStruck();
    if (this._lastStruckSkill) {
      return $dataSkills[this._lastStruckId];
    } else {
      return $dataItems[this._lastStruckId];
    }
};

Game_Enemy.prototype.markStruckActions = function(item, subject, action) {
    if (!item) return;
    this.createTimesStruck();
    this._lastStruckId = item.id;
    this._lastStruckSkill = DataManager.isSkill(item);
    this.markLastStruckActor(subject);
    if (DataManager.isSkill(item)) {
      this._struckSkills[item.id] = this._struckSkills[item.id] || 0;
      this._struckSkills[item.id] = this._struckSkills[item.id] + 1;
      this._struckSType[item.stypeId] = this._struckSType[item.stypeId] || 0;
      this._struckSType[item.stypeId] = this._struckSType[item.stypeId] + 1;
    }
    if (DataManager.isItem(item)) {
      this._struckItems[item.id] = this._struckItems[item.id] || 0;
      this._struckItems[item.id] = this._struckItems[item.id] + 1;
    }
    this.markStruckElements(item, subject, action);
};

Game_Enemy.prototype.killer = function() {
    if (this._lastStruckActor > 0) {
      return $gameActors.actor(this._lastStruckActor);
    } else {
      return this;
    }
};

Game_Enemy.prototype.markLastStruckActor = function(subject) {
  if (subject && subject.isActor()) this._lastStruckActor = subject.actor().id;
};

Game_Enemy.prototype.markStruckElements = function(item, subject, action) {
  if (Imported.YEP_ElementCore && action) {
    var elements = action.getItemElements();
  } else if (item.damage.elementId < 0) {
    var elements = subject.attackElements();
  } else {
    var elements = [item.damage.elementId];
  }
  var length = elements.length;
  for (var i = 0; i < length; ++i) {
    var eleId = elements[i];
    if (eleId <= 0) continue;
    this._struckElements[eleId] = this._struckElements[eleId] || 0;
    this._struckElements[eleId] = this._struckElements[eleId] + 1;
  }
};

Game_Enemy.prototype.timesStruckSkill = function(id) {
    this.createTimesStruck();
    return this._struckSkills[id] || 0;
};

Game_Enemy.prototype.timesStruckItem = function(id) {
    this.createTimesStruck();
    return this._struckItems[id] || 0;
};

Game_Enemy.prototype.timesStruckSType = function(id) {
    this.createTimesStruck();
    return this._struckSType[id] || 0;
};

Game_Enemy.prototype.timesStruckState = function(id) {
    this.createTimesStruck();
    return this._struckStates[id] || 0;
};

Game_Enemy.prototype.timesStruckElement = function(id) {
    this.createTimesStruck();
    return this._struckElements[id] || 0;
};

//=============================================================================
// Game_Action
//=============================================================================

Yanfly.EED.Game_Action_applyItemUserEffect =
    Game_Action.prototype.applyItemUserEffect;
Game_Action.prototype.applyItemUserEffect = function(target) {
    Yanfly.EED.Game_Action_applyItemUserEffect.call(this, target);
    if (target && target.isEnemy()) {
      target.markStruckActions(this.item(), this.subject(), this);
    }
};

//=============================================================================
// DropManager
//=============================================================================

function DropManager() {
    throw new Error('This is a static class');
}

DropManager.setup = function(enemy) {
    this._enemy = enemy;
    this._data = this._enemy.enemy().conditionalDropItems;
    this._drops = [];
    this.makeConditionalDropItems();
    return this._drops;
};

DropManager.makeConditionalDropItems = function() {
    var length = this._data.length;
    if (length <= 0) return;
    for (var i = 0; i < length; ++i) {
      var data = this._data[i];
      var item = data[0];
      var conditions = data[1];
      if (Math.random() < this.getConditionalRate(conditions)) {
        this._drops.push(item);
      }
    }
};

DropManager.getConditionalRate = function(conditions) {
    var rate = 0;
    var length = conditions.length;
    for (var i = 0; i < length; ++i) {
      var condition = conditions[i];
      if (condition.match(/(.*):[ ]([\+\-]\d+)([%％])/i)) {
        var line = String(RegExp.$1);
        var value = parseFloat(RegExp.$2) * 0.01;
        if (this.meetsLineCondition(line)) rate += value;
      }
    }
    return rate;
};

DropManager.meetsLineCondition = function(line) {
    // EVAL
    if (line.match(/EVAL[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionEval(line);
    }
    // ALIVE MEMBERS
    if (line.match(/ALIVE MEMBERS[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionAliveMembers(line);
    }
    // ALWAYS
    if (line.toUpperCase() === 'ALWAYS') {
      return this.conditionAlways();
    }
    // COUNT
    if (line.match(/(.*)[ ]COUNT[ ](.*)/i)) {
      var line1 = String(RegExp.$1);
      var line2 = String(RegExp.$2);
      return this.conditionCount(line1, line2);
    }
    // DEAD MEMBERS
    if (line.match(/DEAD MEMBERS[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionDeadMembers(line);
    }
    // DEATH TURN EVAL
    if (line.match(/DEATH TURN[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionDeathTurn(line);
    }
    // ENEMY LEVEL
    if (line.match(/ENEMY LEVEL[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionEnemyLevel(line);
    }
    // LAST STRIKE
    if (line.match(/LAST STRIKE[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionLastStrike(line);
    }
    // PARTY MEMBERS
    if (line.match(/PARTY MEMBERS[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionPartyMembers(line);
    }
    // RANDOM X%
    if (line.match(/RANDOM[ ](\d+)([%％])/i)) {
      var rate = parseFloat(RegExp.$1) * 0.01;
      return this.conditionRandom(rate);
    }
    // TIMES STRUCK
    if (line.match(/TIMES[ ](.*)[ ]STRUCK[ ](.*)/i)) {
      var line1 = String(RegExp.$1);
      var line2 = String(RegExp.$2);
      return this.conditionTimesStruck(line1, line2);
    }
    // SWITCH EVAL
    if (line.match(/SWITCH[ ](\d+)[ ](.*)/i)) {
      var switchId = parseInt(RegExp.$1);
      var switchCase = String(RegExp.$2).toUpperCase();
      return this.conditionSwitch(switchId, switchCase);
    }
    // TURN EVAL
    if (line.match(/TURN[ ](.*)/i)) {
      var line = String(RegExp.$1);
      return this.conditionTurn(line);
    }
    // VARIABLE EVAL
    if (line.match(/VARIABLE[ ](\d+)[ ](.*)/i)) {
      var varId = parseInt(RegExp.$1);
      var varLine = String(RegExp.$2).toUpperCase();
      return this.conditionVariable(varId, varLine);
    }
    return false;
};

DropManager.conditionAliveMembers = function(line) {
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = '$gameParty.aliveMembers().length ' + line;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP ALIVE CONDITION ERROR');
      return false;
    }
};

DropManager.conditionAlways = function() {
    return true;
};

DropManager.conditionCount = function(line1, line2) {
    var item = null;
    if (line1.match(/ITEM[ ](\d+)/i)) {
      item = $dataItems[parseInt(RegExp.$1)];
    } else if (line1.match(/WEAPON[ ](\d+)/i)) {
      item = $dataWeapons[parseInt(RegExp.$1)];
    } else if (line1.match(/ARMOR[ ](\d+)/i)) {
      item = $dataArmors[parseInt(RegExp.$1)];
    } else if (Yanfly.ItemIdRef[line1.toUpperCase()]) {
      item = $dataItems[Yanfly.ItemIdRef[line1.toUpperCase()]];
    } else if (Yanfly.WeaponIdRef[line1.toUpperCase()]) {
      item = $dataWeapons[Yanfly.WeaponIdRef[line1.toUpperCase()]];
    } else if (Yanfly.ArmorIdRef[line1.toUpperCase()]) {
      item = $dataArmors[Yanfly.ArmorIdRef[line1.toUpperCase()]];
    }
    if (!item) return false;
    if (Imported.YEP_ItemCore && DataManager.isIndependent(item)) {
      var quantity = $gameParty.numIndependentItems(item);
    } else {
      var quantity = $gameParty.numItems(item);
    }
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = 'quantity ' + line2;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP COUNT ERROR');
      return false;
    }
};

DropManager.conditionDeadMembers = function(line) {
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = '$gameParty.deadMembers().length ' + line;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP DEAD MEMBERS ERROR');
      return false;
    }
};

DropManager.conditionDeathTurn = function(line) {
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = 'user.deathTurn() ' + line;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP DEATH TURN ERROR');
      return false;
    }
};

DropManager.conditionEnemyLevel = function(line) {
    if (!Imported.YEP_EnemyLevels) return false;
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = 'enemy.level ' + line;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP ENEMY LEVEL ERROR');
      return false;
    }
};

DropManager.conditionLastStrike = function(line) {
    if (line.match(/SKILL[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      return this._enemy.lastStruckAction() === $dataSkills[id];
    } else if (line.match(/ITEM[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      return this._enemy.lastStruckAction() === $dataItems[id];
    } else if (Yanfly.SkillIdRef[line.toUpperCase()]) {
      var id = Yanfly.SkillIdRef[line.toUpperCase()];
      return this._enemy.lastStruckAction() === $dataSkills[id];
    } else if (Yanfly.ItemIdRef[line.toUpperCase()]) {
      var id = Yanfly.ItemIdRef[line.toUpperCase()];
      return this._enemy.lastStruckAction() === $dataItems[id];
    }
    return false;
};

DropManager.conditionPartyMembers = function(line) {
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = '$gameParty.battleMembers().length ' + line;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP PARTY SIZE ERROR');
      return false;
    }
};

DropManager.conditionRandom = function(rate) {
    return Math.random() < rate;
};

DropManager.conditionSwitch = function(switchId, switchCase) {
    var condition = false;
    if (['ON', 'TRUE'].contains(switchCase)) condition = true;
    return $gameSwitches.value(switchId) === condition;
};

DropManager.conditionTimesStruck = function(line1, line2) {
    var times = this.getTimesStruck(line1);
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = 'times ' + line2;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP TIMES STRUCK ERROR');
      return false;
    }
};

DropManager.getTimesStruck = function(line) {
    var times = 0;
    if (line.match(/SKILL[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      times = this._enemy.timesStruckSkill(id);
    } else if (line.match(/SKILL[ ](.*)/i)) {
      var name = String(RegExp.$1).toUpperCase();
      if (Yanfly.SkillIdRef[name]) {
        var id = Yanfly.SkillIdRef[name];
        times = this._enemy.timesStruckSkill(id);
      }
    } else if (line.match(/ITEM[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      times = this._enemy.timesStruckItem(id);
    } else if (line.match(/ITEM[ ](.*)/i)) {
      var name = String(RegExp.$1).toUpperCase();
      if (Yanfly.ItemIdRef[name]) {
        var id = Yanfly.ItemIdRef[name];
        times = this._enemy.timesStruckItem(id);
      }
    } else if (line.match(/STYPE[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      times = this._enemy.timesStruckSType(id);
    } else if (line.match(/STYPE[ ](.*)/i)) {
      var name = String(RegExp.$1).toUpperCase();
      if (Yanfly.STypeIdRef[name]) {
        var id = Yanfly.STypeIdRef[name];
        times = this._enemy.timesStruckSType(id);
      }
    } else if (line.match(/STATE[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      times = this._enemy.timesStruckState(id);
    } else if (line.match(/STATE[ ](.*)/i)) {
      var name = String(RegExp.$1).toUpperCase();
      if (Yanfly.StateIdRef[name]) {
        var id = Yanfly.StateIdRef[name];
        times = this._enemy.timesStruckState(id);
      }
    } else if (line.match(/ELEMENT[ ](\d+)/i)) {
      var id = parseInt(RegExp.$1);
      times = this._enemy.timesStruckElement(id);
    } else if (line.match(/ELEMENT[ ](.*)/i)) {
      var name = String(RegExp.$1).toUpperCase();
      if (Yanfly.ElementIdRef[name]) {
        var id = Yanfly.ElementIdRef[name];
        times = this._enemy.timesStruckElement(id);
      }
    }
    return times;
};

DropManager.conditionTurn = function(line) {
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = '$gameTroop.turnCount() ' + line;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP TURN ERROR');
      return false;
    }
};

DropManager.conditionVariable = function(varId, varLine) {
    var value = false;
    var code = '$gameVariables.value(varId) ' + varLine;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP VARIABLE ERROR');
      return false;
    }
};

DropManager.conditionEval = function(code) {
    var user = this._enemy;
    var enemy = this._enemy;
    var a = this._enemy;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    try {
      return eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'ENEMY DROP EVAL ERROR');
      return false;
    }
};

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

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

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

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


code:
//=============================================================================
// Yanfly Engine Plugins - Extra Parameter Formula
// YEP_ExtraParamFormula.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.XParam = Yanfly.XParam || {};
Yanfly.XParam.version = 1.04;

//=============================================================================
 /*:
 * @plugindesc v1.04 Control the formulas of the extra parameters for
 * HIT, EVA, CRI, CEV, MEV, MRF, CNT, HRG, MRG, and TRG.
 * @author Yanfly Engine Plugins
 *
 * @param HIT Formula
 * @desc The formula used to determine HIT: Hit%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param EVA Formula
 * @desc The formula used to determine EVA: Evasion%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param CRI Formula
 * @desc The formula used to determine CRI: Critical Hit%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param CEV Formula
 * @desc The formula used to determine CEV: Critical Evasion%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param MEV Formula
 * @desc The formula used to determine MEV: Magic Evasion%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param MRF Formula
 * @desc The formula used to determine MRF: Magic Reflect%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param CNT Formula
 * @desc The formula used to determine CNT: Counter Attack%
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param HRG Formula
 * @desc The formula used to determine HRG: HP% Regen
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param MRG Formula
 * @desc The formula used to determine MRG: MP% Regen
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @param TRG Formula
 * @desc The formula used to determine TRG: Target Rate
 * This is a formula.
 * @default (base + plus) * rate + flat
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * The values for the Extra Parameters: HIT, EVA, CRI, CEV, MEV, MRF, CNT, HRG,
 * MRG, and TRG, in RPG Maker MV are only able to be ever modified by traits by
 * the various database objects. While it is flexible, RPG Maker MV does not
 * enable you to utilize custom formulas to make things such as ATK and AGI
 * influence HIT rate or LUK influence CRItical hits. With this plugin, now you
 * can along with a few more goodies!
 *
 * ============================================================================
 * Instructions - Extra Parameter Explanation
 * ============================================================================
 *
 * For those who aren't familiar with what the Extra Parameters (xparams) do,
 * this is a list that will explain their standard functions in an RPG Maker MV
 * project.
 *
 * ---
 *
 * HIT - Hit Rate%
 * - This determines the physical hit success rate of the any physical action.
 * All physical attacks make a check through the HIT rate to see if the attack
 * will connect. If the HIT value passes the randomizer check, the attack will
 * connect. If the HIT value fails to pass the randomizer check, the attack
 * will be considered a MISS.
 *
 * ---
 *
 * EVA - Evasion Rate%
 * - This determines the physical evasion rate against any incoming physical
 * actions. If the HIT value passes, the action is then passed to the EVA check
 * through a randomizer check. If the randomizer check passes, the physical
 * attack is evaded and will fail to connect. If the randomizer check passes,
 * the attempt to evade the action will fail and the action connects.
 *
 * ---
 *
 * CRI - Critical Hit Rate%
 * - Any actions that enable Critical Hits will make a randomizer check with
 * this number. If the randomizer check passes, extra damage will be carried
 * out by the initiated action. If the randomizer check fails, no extra damage
 * will be added upon the action.
 *
 * ---
 *
 * CEV - Critical Evasion Rate%
 * - This value is put against the Critical Hit Rate% in a multiplicative rate.
 * If the Critical Hit Rate is 90% and the Critical Evasion Rate is
 * 20%, then the randomizer check will make a check against 72% as the values
 * are calculated by the source code as CRI * (1 - CEV), therefore, with values
 * as 0.90 * (1 - 0.20) === 0.72.
 *
 * ---
 *
 * MEV - Magic Evasion Rate%
 * - Where EVA is the evasion rate against physical actions, MEV is the evasion
 * rate against magical actions. As there is not magical version of HIT, the
 * MEV value will always be bit against when a magical action is initiated. If
 * the randomizer check passes for MEV, the magical action will not connect. If
 * the randomizer check fails for MEV, the magical action will connect.
 *
 * ---
 *
 * MRF - Magic Reflect Rate%
 * - If a magical action connects and passes, there is a chance the magical
 * action can be bounced back to the caster. That chance is the Magic Reflect
 * Rate. If the randomizer check for the Magic Reflect Rate passes, then the
 * magical action is bounced back to the caster, ignoring the caster's Magic
 * Evasion Rate. If the randomizer check for the Magic Reflect Rate fails, then
 * the magical action will connect with its target.
 *
 * ---
 *
 * CNT - Counter Attack Rate%
 * - If a physical action connects and passes, there is a chance the physical
 * action can be avoided and a counter attack made by the user will land on the
 * attacking unit. This is the Counter Attack Rate. If the randomizer check for
 * the Counter Attack Rate passes, the physical action is evaded and the target
 * will counter attack the user. If the randomizer check fails, the physical
 * action will connect to the target.
 *
 * ---
 *
 * HRG - HP% Regeneration
 * - During a battler's regeneration phase, the battler will regenerate this
 * percentage of its MaxHP as gained HP with a 100% success rate.
 *
 * ---
 *
 * MRG - MP% Regeneration
 * - During a battler's regeneration phase, the battler will regenerate this
 * percentage of its MaxMP as gained MP with a 100% success rate.
 *
 * ---
 *
 * TRG - TP% Regeneration
 * - During a battler's regeneration phase, the battler will regenerate this
 * percentage of its MaxTP as gained TP with a 100% success rate.
 *
 * ---
 *
 * ============================================================================
 * Instructions - Custom Formulas
 * ============================================================================
 *
 * The values calculated by the formulas in the plugin parameters are to come
 * out as float values. If the result value comes out as 0.1 for CRI, it will
 * be 10% CRI. Here is an example:
 *
 *   (base + plus) * rate + flat + user.luk / 1000
 *
 * The 'user.luk / 1000' is inserted at the end. Assuming everything else comes
 * out to be 10% and the user's LUK parameter is at 500, it will be 0.1 + 0.5
 * which means the total comes out to 0.6, hence a 60% CRItical hit rate.
 *
 * ============================================================================
 * Instructions - Understanding Formula Variables
 * ============================================================================
 *
 * So, what does the 'base', 'plus', 'rate', and 'flat' mean in the formulas?
 * This section will answer that in detail.
 *
 * Default plugin formula: (base + plus) * rate + flat
 *
 * BASE
 * - This value is determined by the default way RPG Maker MV determines the
 * value for that stat, and the way RPG Maker MV determines it is by adding up
 * the total trait values of that stat. If a battler would have a mixture of
 * +95%, -10%, and +5% HIT traits, then the base stat value would be +90%.
 *
 * PLUS
 * - This is a new variable added by this plugin. Its purpose is to function as
 * an addition to the base value. This addition can be done independently of
 * database items as you can do a user.addXParam to alter the base value of the
 * extra parameter. If using the default formula, this value is added to the
 * base before any rates are multiplied by it and any flats added to the total.
 *
 * RATE
 * - This is a new variable added by this plugin. Its purpose is to function as
 * a multiplicative modifier for the extra parameter value. This multiplicative
 * value is determined by various database objects through notetags. If using
 * the default formula, this value is multipled to the sum of the base and plus
 * values of the extra parameter before the flat is added to the total.
 *
 * FLAT
 * - This is a new variable added by this plugin. Its purpose is to function as
 * an additive modifier for the extra parameter value. This additive value is
 * determined by various database objects through notetags. If using the plugin
 * default formula, this value is added after the sum of the base and plus
 * values of the extra parameter stat are multiplied by the rate value.
 *
 * ============================================================================
 * Examples - Sample Formulas
 * ============================================================================
 *
 * The following are some sample formulas you can use to make extra parameters
 * a bit more dynamic:
 *
 * --- HIT ---
 * (base + plus) * rate + flat + ((user.atk + user.agi) / 2000)
 * - This will cause the HIT rate to gain bonus accuracy from ATK and AGI.
 *
 * --- EVA ---
 * (base + plus) * rate + flat + ((user.def + user.agi) / 2000)
 * - This will cause the EVA rate to gain bonus evasion from DEF and AGI.
 *
 * --- CRI ---
 * (base + plus) * rate + flat + (user.luk / 1000)
 * - This will cause the CRI rate to gain bonus success from LUK.
 *
 * --- CEV ---
 * (base + plus) * rate + flat + ((user.agi + user.luk) / 2000)
 * - This will cause the CEV rate to gain more critical evade from LUK and AGI.
 *
 * --- MEV ---
 * (base + plus) * rate + flat + ((user.mdf + user.agi) / 2000)
 * - This will cause the MEV rate to gain extra magic evasion from MDF and AGI.
 *
 * The above are some examples on how you can make your extra parameters to be
 * affected by the other stats from the user.
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * You can use the following notetags to alter the various aspects that modify
 * the extra parameter values:
 *
 * Actor, Class, Enemy, Weapon, Armor, and State Notetags:
 *
 *   <stat Plus: +x%>
 *   <stat Plus: -x%>
 *   <stat Plus: +x.y>
 *   <stat Plus: -x.y>
 *   Replace 'stat' with 'hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt',
 *   'hrg', 'mrg', or 'trg'. This is the value added to the base parameter
 *   before the rate and flat values contribute to the total parameter value
 *   assuming the plugin's default formula is utilized.
 *
 *   <stat Rate: x%>
 *   <stat Rate: x.y>
 *   Replace 'stat' with 'hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt',
 *   'hrg', 'mrg', or 'trg'. This is the value multipled to the sum of the base
 *   and plus values of the parameter before added by the flat value assuming
 *   the plugin's default formula is utilized.
 *
 *   <stat Flat: +x%>
 *   <stat Flat: -x%>
 *   <stat Flat: +x.y>
 *   <stat Flat: -x.y>
 *   Replace 'stat' with 'hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt',
 *   'hrg', 'mrg', or 'trg'. This is the value added finally to the sum of the
 *   base and plus values after being multiplied by the rate value assuming the
 *   plugin's default formula is utilized.
 *
 * ============================================================================
 * Lunatic Mode - New JavaScript Functions
 * ============================================================================
 *
 * You can use the following JavaScript functions to alter the extra parameter
 * values of actors. In these listed functions, the 'actor' variable is to be
 * referenced by an actor:
 *
 * ie. actor = $gameActors.actor(3));
 *
 * Function:
 *
 *   actor.clearXParamPlus()
 *   - Clears all of the actor's extra parameter plus bonuses.
 *
 *   actor.setHit(x)
 *   actor.setEva(x)
 *   actor.setCri(x)
 *   actor.setCev(x)
 *   actor.setMev(x)
 *   actor.setMrf(x)
 *   actor.setCnt(x)
 *   actor.setHrg(x)
 *   actor.setMrg(x)
 *   actor.setTrg(x)
 *   - Sets the actor's respective extra parameter value to x. Keep in mind
 *   that 1 is equal to 100% and 0.1 would be equal to 10%. Negative values
 *   will apply here, too.
 *
 *   actor.setHitPlus(x)
 *   actor.setEvaPlus(x)
 *   actor.setCriPlus(x)
 *   actor.setCevPlus(x)
 *   actor.setMevPlus(x)
 *   actor.setMrfPlus(x)
 *   actor.setCntPlus(x)
 *   actor.setHrgPlus(x)
 *   actor.setMrgPlus(x)
 *   actor.setTrgPlus(x)
 *   - Sets the actor's respective extra parameter plus value to x. Keep in
 *   mind that 1 is equal to 100% and 0.1 would be equal to 10%. Negative
 *   values will apply here, too.
 *
 *   actor.addHit(x)
 *   actor.addEva(x)
 *   actor.addCri(x)
 *   actor.addCev(x)
 *   actor.addMev(x)
 *   actor.addMrf(x)
 *   actor.addCnt(x)
 *   actor.addHrg(x)
 *   actor.addMrg(x)
 *   actor.addTrg(x)
 *   - Adds x to the actor's respective extra parameter value. Keep in mind
 *   that 1 is equal to 100% and 0.1 would be equal to 10%. Negative values
 *   will decrease the extra parameter.
 *
 *   actor.minusHit(x)
 *   actor.minusEva(x)
 *   actor.minusCri(x)
 *   actor.minusCev(x)
 *   actor.minusMev(x)
 *   actor.minusMrf(x)
 *   actor.minusCnt(x)
 *   actor.minusHrg(x)
 *   actor.minusMrg(x)
 *   actor.minusTrg(x)
 *   - Subtracts x from the actor's respective extra parameter value. Keep in
 *   mind that 1 is equal to 100% and 0.1 would be equal to 10%. Negative
 *   values will add to the extra parameter.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.04:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.03a:
 * - Lunatic Mode fail safe added.
 * - Documentation update to fix typos.
 *
 * Version 1.02:
 * - Fixed an issue with the battler.setXParam functions that made them take
 * the wrong value due caching issues.
 *
 * Version 1.01:
 * - Updated for RPG Maker MV version 1.1.0.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

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

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

Yanfly.Param.XParamFormula = [];
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['HIT Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['EVA Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['CRI Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['CEV Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['MEV Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['MRF Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['CNT Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['HRG Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['MRG Formula']));
Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters['TRG Formula']));

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

Yanfly.XParam.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
  if (!Yanfly.XParam.DataManager_isDatabaseLoaded.call(this)) return false;
  if (!Yanfly._loaded_YEP_ExtraParamFormula) {
    this.processXParamNotetags($dataActors);
    this.processXParamNotetags($dataClasses);
    this.processXParamNotetags($dataEnemies);
    this.processXParamNotetags($dataWeapons);
    this.processXParamNotetags($dataArmors);
    this.processXParamNotetags($dataStates);
    Yanfly._loaded_YEP_ExtraParamFormula = true;
  }
  return true;
};

DataManager.processXParamNotetags = function(group) {
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.plusXParams = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    obj.rateXParams = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
    obj.flatXParams = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<(.*) PLUS:[ ]([\+\-]\d+)([%％])>/i)) {
        var text = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(RegExp.$2) * 0.01;
        var id = this.getXParamId(text);
        if (id !== null) obj.plusXParams[id] = rate;
      } else if (line.match(/<(.*) PLUS:[ ]([\+\-]\d+).(\d+)>/i)) {
        var text = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(String(RegExp.$2) + '.' + String(RegExp.$3));
        var id = this.getXParamId(text);
        if (id !== null) obj.plusXParams[id] = rate;
      } else if (line.match(/<(.*) RATE:[ ](\d+)([%％])>/i)) {
        var text = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(RegExp.$2) * 0.01;
        var id = this.getXParamId(text);
        if (id !== null) obj.rateXParams[id] = rate;
      } else if (line.match(/<(.*) RATE:[ ](\d+).(\d+)>/i)) {
        var text = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(String(RegExp.$2) + '.' + String(RegExp.$3));
        var id = this.getXParamId(text);
        if (id !== null) obj.rateXParams[id] = rate;
      } else if (line.match(/<(.*) FLAT:[ ]([\+\-]\d+)([%％])>/i)) {
        var text = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(RegExp.$2) * 0.01;
        var id = this.getXParamId(text);
        if (id !== null) obj.flatXParams[id] = rate;
      } else if (line.match(/<(.*) FLAT:[ ]([\+\-]\d+).(\d+)>/i)) {
        var text = String(RegExp.$1).toUpperCase();
        var rate = parseFloat(String(RegExp.$2) + '.' + String(RegExp.$3));
        var id = this.getXParamId(text);
        if (id !== null) obj.flatXParams[id] = rate;
      }
    }
  }
};

DataManager.getXParamId = function(string) {
    if (['HIT', 'HIT RATE'].contains(string)) {
      return 0;
    } else if (['EVA', 'EVADE', 'EVASION'].contains(string)) {
      return 1;
    } else if (['CRI', 'CRITICAL', 'CRITICAL HIT'].contains(string)) {
      return 2;
    } else if (['CEV', 'CRITICAL EVADE', 'CRITICAL EVASION'].contains(string)) {
      return 3;
    } else if (['MEV', 'MAGIC EVADE', 'MAGIC EVASION', 'GRAZE'].contains(string)) {
      return 4;
    } else if (['MRF', 'MAGIC REFLECT', 'MAGIC REFLECTION'].contains(string)) {
      return 5;
    } else if (['CNT', 'COUNTER', 'COUNTERATTACK'].contains(string)) {
      return 6;
    } else if (['HRG', 'HP REGEN', 'HP REGENERATION'].contains(string)) {
      return 7;
    } else if (['MRG', 'MP REGEN', 'MP REGENERATION'].contains(string)) {
      return 8;
    } else if (['TRG', 'TP REGEN', 'TP REGENERATION'].contains(string)) {
      return 9;
    } else {
      return null;
    }
};

//=============================================================================
// Game_BattlerBase
//=============================================================================

Yanfly.XParam.Game_BattlerBase_initMembers =
    Game_BattlerBase.prototype.initMembers;
Game_BattlerBase.prototype.initMembers = function() {
    Yanfly.XParam.Game_BattlerBase_initMembers.call(this);
    this.clearXParamPlus();
};

Game_BattlerBase.prototype.clearXParamPlus = function(id) {
    this._xparamPlus = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
};

Yanfly.XParam.Game_BattlerBase_refresh = Game_BattlerBase.prototype.refresh;
Game_BattlerBase.prototype.refresh = function() {
    this._xparam = undefined;
    Yanfly.XParam.Game_BattlerBase_refresh.call(this);
};

Yanfly.XParam.Game_BattlerBase_xparam = Game_BattlerBase.prototype.xparam;
Game_BattlerBase.prototype.xparam = function(id) {
    if (this._xparam && this._xparam[id] !== undefined) return this._xparam[id];
    if (this._xparam === undefined) this._xparam = {};
    var base = Yanfly.XParam.Game_BattlerBase_xparam.call(this, id);
    var plus = this.xparamPlus(id);
    var rate = this.xparamRate(id);
    var flat = this.xparamFlat(id);;
    var a = this;
    var user = this;
    var subject = this;
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = Yanfly.Param.XParamFormula[id];
    try {
      this._xparam[id] = eval(code);
    } catch (e) {
      this._xparam[id] = 0;
      Yanfly.Util.displayError(e, code, 'EXTRA PARAM FORMULA ERROR');
    }
    return this._xparam[id];
};

Game_BattlerBase.prototype.xparamPlus = function(id) {
    if (this._xparamPlus === undefined) this.clearXParamPlus();
    return this._xparamPlus[id];
};

Game_BattlerBase.prototype.xparamRate = function(id) {
    return 1;
};

Game_BattlerBase.prototype.xparamFlat = function(id) {
    return 0;
};

Game_BattlerBase.prototype.setXParam = function(id, value) {
    if (this._xparamPlus === undefined) this.clearXParamPlus();
    this._xparam = {};
    this._xparamPlus[id] = 0;
    this._xparamPlus[id] = value - this.xparam(id);
    this.refresh();
};

Game_BattlerBase.prototype.setHit = function(value) {
    this.setXParam(0, value);
};

Game_BattlerBase.prototype.setEva = function(value) {
    this.setXParam(1, value);
};

Game_BattlerBase.prototype.setCri = function(value) {
    this.setXParam(2, value);
};

Game_BattlerBase.prototype.setCev = function(value) {
    this.setXParam(3, value);
};

Game_BattlerBase.prototype.setMev = function(value) {
    this.setXParam(4, value);
};

Game_BattlerBase.prototype.setMrf = function(value) {
    this.setXParam(5, value);
};

Game_BattlerBase.prototype.setCnt = function(value) {
    this.setXParam(6, value);
};

Game_BattlerBase.prototype.setHrg = function(value) {
    this.setXParam(7, value);
};

Game_BattlerBase.prototype.setMrg = function(value) {
    this.setXParam(8, value);
};

Game_BattlerBase.prototype.setTrg = function(value) {
    this.setXParam(9, value);
};

Game_BattlerBase.prototype.setXParamPlus = function(id, value) {
    if (this._xparamPlus === undefined) this.clearXParamPlus();
    this._xparamPlus[id] = value;
    this.refresh();
};

Game_BattlerBase.prototype.setHitPlus = function(value) {
    this.setXParamPlus(0, value);
};

Game_BattlerBase.prototype.setEvaPlus = function(value) {
    this.setXParamPlus(1, value);
};

Game_BattlerBase.prototype.setCriPlus = function(value) {
    this.setXParamPlus(2, value);
};

Game_BattlerBase.prototype.setCevPlus = function(value) {
    this.setXParamPlus(3, value);
};

Game_BattlerBase.prototype.setMevPlus = function(value) {
    this.setXParamPlus(4, value);
};

Game_BattlerBase.prototype.setMrfPlus = function(value) {
    this.setXParamPlus(5, value);
};

Game_BattlerBase.prototype.setCntPlus = function(value) {
    this.setXParamPlus(6, value);
};

Game_BattlerBase.prototype.setHrgPlus = function(value) {
    this.setXParamPlus(7, value);
};

Game_BattlerBase.prototype.setMrgPlus = function(value) {
    this.setXParamPlus(8, value);
};

Game_BattlerBase.prototype.setTrgPlus = function(value) {
    this.setXParamPlus(9, value);
};

Game_BattlerBase.prototype.addXParam = function(id, value) {
    if (this._xparamPlus === undefined) this.clearXParamPlus();
    this._xparamPlus[id] += value;
    this.refresh();
};

Game_BattlerBase.prototype.addHit = function(value) {
    this.addXParam(0, value);
};

Game_BattlerBase.prototype.addEva = function(value) {
    this.addXParam(1, value);
};

Game_BattlerBase.prototype.addCri = function(value) {
    this.addXParam(2, value);
};

Game_BattlerBase.prototype.addCev = function(value) {
    this.addXParam(3, value);
};

Game_BattlerBase.prototype.addMev = function(value) {
    this.addXParam(4, value);
};

Game_BattlerBase.prototype.addMrf = function(value) {
    this.addXParam(5, value);
};

Game_BattlerBase.prototype.addCnt = function(value) {
    this.addXParam(6, value);
};

Game_BattlerBase.prototype.addHrg = function(value) {
    this.addXParam(7, value);
};

Game_BattlerBase.prototype.addMrg = function(value) {
    this.addXParam(8, value);
};

Game_BattlerBase.prototype.addTrg = function(value) {
    this.addXParam(9, value);
};

Game_BattlerBase.prototype.minusHit = function(value) {
    this.addXParam(0, -value);
};

Game_BattlerBase.prototype.minusEva = function(value) {
    this.addXParam(1, -value);
};

Game_BattlerBase.prototype.minusCri = function(value) {
    this.addXParam(2, -value);
};

Game_BattlerBase.prototype.minusCev = function(value) {
    this.addXParam(3, -value);
};

Game_BattlerBase.prototype.minusMev = function(value) {
    this.addXParam(4, -value);
};

Game_BattlerBase.prototype.minusMrf = function(value) {
    this.addXParam(5, -value);
};

Game_BattlerBase.prototype.minusCnt = function(value) {
    this.addXParam(6, -value);
};

Game_BattlerBase.prototype.minusHrg = function(value) {
    this.addXParam(7, -value);
};

Game_BattlerBase.prototype.minusMrg = function(value) {
    this.addXParam(8, -value);
};

Game_BattlerBase.prototype.minusTrg = function(value) {
    this.addXParam(9, -value);
};

//=============================================================================
// Game_Battler
//=============================================================================

Game_Battler.prototype.xparamPlus = function(id) {
    var value = Game_BattlerBase.prototype.xparamPlus.call(this, id);
    var length = this.states().length;
    for (var i = 0; i < length; ++i) {
      var obj = this.states()[i];
      if (obj && obj.plusXParams) value += obj.plusXParams[id];
    }
    return value;
};

Game_Battler.prototype.xparamRate = function(id) {
    var value = Game_BattlerBase.prototype.xparamRate.call(this, id);
    var length = this.states().length;
    for (var i = 0; i < length; ++i) {
      var obj = this.states()[i];
      if (obj && obj.rateXParams) value *= obj.rateXParams[id];
    }
    return value;
};

Game_Battler.prototype.xparamFlat = function(id) {
    var value = Game_BattlerBase.prototype.xparamFlat.call(this, id);
    var length = this.states().length;
    for (var i = 0; i < length; ++i) {
      var obj = this.states()[i];
      if (obj && obj.flatXParams) value += obj.flatXParams[id];
    }
    return value;
};

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

Yanfly.XParam.Game_Actor_setup = Game_Actor.prototype.setup;
Game_Actor.prototype.setup = function(actorId) {
    Yanfly.XParam.Game_Actor_setup.call(this, actorId);
    this.clearXParamPlus();
};

Game_Actor.prototype.xparamPlus = function(id) {
    var value = Game_Battler.prototype.xparamPlus.call(this, id);
    var length = this.equips().length;
    for (var i = 0; i < length; ++i) {
      var obj = this.equips()[i];
      if (obj && obj.plusXParams) value += obj.plusXParams[id];
    }
    value += this.actor().plusXParams[id];
    value += this.currentClass().plusXParams[id];
    return value;
};

Game_Actor.prototype.xparamRate = function(id) {
    var value = Game_Battler.prototype.xparamRate.call(this, id);
    var length = this.equips().length;
    for (var i = 0; i < length; ++i) {
      var obj = this.equips()[i];
      if (obj && obj.rateXParams) value *= obj.rateXParams[id];
    }
    value *= this.actor().rateXParams[id];
    value *= this.currentClass().rateXParams[id];
    return value;
};

Game_Actor.prototype.xparamFlat = function(id) {
    var value = Game_Battler.prototype.xparamFlat.call(this, id);
    var length = this.equips().length;
    for (var i = 0; i < length; ++i) {
      var obj = this.equips()[i];
      if (obj && obj.flatXParams) value += obj.flatXParams[id];
    }
    value += this.actor().flatXParams[id];
    value += this.currentClass().flatXParams[id];
    return value;
};

//=============================================================================
// Game_Enemy
//=============================================================================

Game_Enemy.prototype.xparamPlus = function(id) {
    var value = Game_Battler.prototype.xparamPlus.call(this, id);
    value += this.enemy().plusXParams[id];
    return value;
};

Game_Enemy.prototype.xparamRate = function(id) {
    var value = Game_Battler.prototype.xparamRate.call(this, id);
    value *= this.enemy().rateXParams[id];
    return value;
};

Game_Enemy.prototype.xparamFlat = function(id) {
    var value = Game_Battler.prototype.xparamFlat.call(this, id);
    value += this.enemy().flatXParams[id];
    return value;
};

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

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

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

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

repo_name: Deltras/karryn

license: unknown


code:
//=============================================================================
// Yanfly Engine Plugins - Floor Damage
// YEP_FloorDamage.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.FloorDmg = Yanfly.FloorDmg || {};
Yanfly.FloorDmg.version = 1.01;

//=============================================================================
 /*:
 * @plugindesc v1.01 Allows you to modify floor damage based on terrain tags.
 * You can also change the color of the flash when damaged, too.
 * @author Yanfly Engine Plugins
 *
 * @param Default Damage
 * @type number
 * @min 1
 * @desc This is the default amount of damage dealt by damage floors.
 * @default 10
 *
 * @param Flash Color
 * @desc This is the flash color used for all floor damage by default.
 * Insert them by red, green, blue, opacity with values from 0-255
 * @default 255, 0, 0, 128
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * For those who would like to make different tiles deal different amount of
 * damage, this plugin will allow you to accomplish such a thing. This way,
 * some tiles can deal more damage than others instead of dealing a static 10
 * damage each character. In addition to that, you are also able to change the
 * color of the damage flash, too!
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * Insert the following notetags into the noteboxes for your tilesets:
 *
 * Tileset Notetag:
 *
 *   <Floor Damage x: y>
 *   - 'x' is the terrain tag to mark the tileset with. By default, terrain
 *   tags are set to 0. They will go up as high as 7. 'y' will be the amount of
 *   damage dealt to each actor in the party. For example, <Floor Damage 2: 50>
 *   will cause all damage tiles marked with terrain tag 2 to deal 50 damage.
 *   * Note: You will still need to mark the tile itself as a damage tile in
 *   the database editor.
 *
 *   <Floor Flash x: r, g, b, o>
 *   - 'x' is the terrain tag to mark the tileset with. Replace 'r', 'g', 'b',
 *   and 'o' with values between 0-255 to indicate the red, green, blue, and
 *   opacity values respectively. This will make the screen flash this color
 *   combination when the player takes damage from this tile.
 *   * Note: You will still need to mark the tile itself as a damage tile in
 *   the database editor.
 *
 * ============================================================================
 * Lunatic Mode - Custom Floor Damage
 * ============================================================================
 *
 * For those with JavaScript experience, you can make certain terrain tags deal
 * custom amounts of damage to your actors.
 *
 * Tileset Notetag:
 *
 *   <Custom Floor Damage x>
 *    value = actor.level;
 *   </Custom Floor Damage x>
 *   - 'x' is the terrain tag to mark the tileset with. By default, terrain
 *   tags are set to 0. They will go up as high as 7. 'y' will be the amount of
 *   damage dealt to each actor in the party. 'value' is the final damage value
 *   that will be added upon the <Floor Damage x: y> value. 'actor' will refer
 *   to the actor being damaged currently.
 *
 * ============================================================================
 * 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_FloorDamage');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.FloorDmgDefault = Number(Yanfly.Parameters['Default Damage']);
Yanfly.SetupParameters = function() {
  var array = String(Yanfly.Parameters['Flash Color']).split(',');
  for (var i = 0; i < array.length; ++i) {
    array[i] = parseInt(array[i].trim());
  }
  Yanfly.Param.FloorDmgFlash = array;
};
Yanfly.SetupParameters();

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

Yanfly.FloorDmg.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
  if (!Yanfly.FloorDmg.DataManager_isDatabaseLoaded.call(this)) return false;

  if (!Yanfly._loaded_YEP_FloorDamage) {
    this.processFloorDmgNotetags1($dataTilesets);
    Yanfly._loaded_YEP_FloorDamage = true;
  }

  return true;
};

DataManager.processFloorDmgNotetags1 = function(group) {
  var note1a = /<(?:CUSTOM FLOOR DAMAGE|custom floor dmg)[ ](\d+)>/i;
  var note1b = /<\/(?:CUSTOM FLOOR DAMAGE|custom floor dmg)[ ](\d+)>/i;
  var note2 = /<FLOOR FLASH[ ](\d+):[ ](.*)>/i
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.floorDmg = [
      Yanfly.Param.FloorDmgDefault, Yanfly.Param.FloorDmgDefault,
      Yanfly.Param.FloorDmgDefault, Yanfly.Param.FloorDmgDefault,
      Yanfly.Param.FloorDmgDefault, Yanfly.Param.FloorDmgDefault,
      Yanfly.Param.FloorDmgDefault, Yanfly.Param.FloorDmgDefault
    ];
    obj.floorDmgFlash = [
      Yanfly.Param.FloorDmgFlash, Yanfly.Param.FloorDmgFlash,
      Yanfly.Param.FloorDmgFlash, Yanfly.Param.FloorDmgFlash,
      Yanfly.Param.FloorDmgFlash, Yanfly.Param.FloorDmgFlash,
      Yanfly.Param.FloorDmgFlash, Yanfly.Param.FloorDmgFlash
    ]
    var evalMode = 'none';
    var terrainId = 0;
    obj.floorDmgEval = ['', '', '', '', '', '', '', ''];

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<(?:FLOOR DAMAGE|floor dmg)[ ](\d+):[ ](\d+)>/i)) {
        var tag = parseInt(RegExp.$1).clamp(0, 7);
        var dmg = parseInt(RegExp.$2);
        obj.floorDmg[tag] = dmg;
      } else if (line.match(note1a)) {
        evalMode = 'custom floor damage';
        var terrainId = parseInt(RegExp.$1).clamp(0, 7);
      } else if (line.match(note1b)) {
        evalMode = 'none';
      } else if (evalMode === 'custom floor damage') {
        obj.floorDmgEval[terrainId] += line + '\n';
      } else if (line.match(note2)) {
        var tag = parseInt(RegExp.$1).clamp(0, 7);
        var array = String(RegExp.$2).split(',');
        for (var a = 0; a < array.length; ++a) {
          array[a] = parseInt(array[a].trim());
        }
        if (array.length === 4) obj.floorDmgFlash[tag] = array;
      }
    }
  }
};

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

Game_Actor.prototype.basicFloorDamage = function() {
  var value = $gameMap.evaluateFloorDamage(this);
  return Math.ceil(value);
};

Game_Actor.prototype.performMapDamage = function() {
  if ($gameParty.inBattle()) return;
  var terrainTag = $gamePlayer.terrainTag();
  var tileset = $gameMap.tileset();
  var data = tileset.floorDmgFlash[terrainTag] || [255, 0, 0, 128];
  $gameScreen.startFlash(data, 8);
};

//=============================================================================
// Game_Map
//=============================================================================

Game_Map.prototype.evaluateFloorDamage = function(actor) {
  var terrainTag = $gamePlayer.terrainTag();
  var tileset = this.tileset();
  var value = tileset.floorDmg[terrainTag] || 10;
  var a = actor;
  var b = actor;
  var user = actor;
  var subject = actor;
  var target = actor;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = tileset.floorDmgEval[terrainTag] || 0;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'CUSTOM FLOOR DAMAGE ERROR');
  }
  return value;
};

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

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

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

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


code:
//=============================================================================
// Yanfly Engine Plugins - Force Advantage
// YEP_ForceAdvantage.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.FAdv = Yanfly.FAdv || {};
Yanfly.FAdv.version = 1.01

//=============================================================================
 /*:
 * @plugindesc v1.01 This plugin allows you to force pre-emptive,
 * surprise, or normal initiatives for battles.
 * @author Yanfly Engine Plugins
 *
 * @param Neutral Event
 * @type common_event
 * @desc This common event will play with neutral advantage.
 * Place 0 to not use this parameter.
 * @default 0
 *
 * @param Pre-Emptive Event
 * @type common_event
 * @desc This common event will play with pre-emptive strikes.
 * Place 0 to not use this parameter.
 * @default 0
 *
 * @param Surprise Event
 * @type common_event
 * @desc This common event will play with surprise strikes.
 * Place 0 to not use this parameter.
 * @default 0
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin enables you to force a battle advantage on the next upcoming
 * battle, whether it is forced or a random encounter. These advantages can be
 * either pre-emptive strikes, surprise attacks, or even forcing a completely
 * normal battle with no advantage. This plugin also enables specific common
 * events to play upon different battle types.
 *
 * If you are using the YEP_BattleEngineCore.js, place this plugin underneath
 * the YEP_BattleEngineCore.js in the plugin's folder for better compatibility.
 *
 * ============================================================================
 * Plugin Commands
 * ============================================================================
 *
 * Use the following plugin commands to force a battle advantage on the next
 * upcoming battle:
 *
 * Plugin Command:
 *
 *   ForceAdvantage Pre-Emptive
 *   ForceAdvantage Preemptive
 *   ForceAdvantage First Strike
 *   ForceAdvantage Player
 *   - Forces a pre-emptive strike giving the player the advantage.
 *
 *   ForceAdvantage Surprise
 *   ForceAdvantage Back Attack
 *   ForceAdvantage Enemy
 *   - Forces a surprise attack giving the enemy party the advantage.
 *
 *   ForceAdvantage None
 *   ForceAdvantage Normal
 *   ForceAdvantage Neutral
 *   - Forces a neutral advantage where neither party has the advantage.
 *
 *   ForceAdvantage Clear
 *   - Clears any forced advantage settings imposed by the above commands.
 *
 * ============================================================================
 * 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_ForceAdvantage');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.FAdvNeutral = Number(Yanfly.Parameters['Neutral Event']);
Yanfly.Param.FAdvPreemptive = Number(Yanfly.Parameters['Pre-Emptive Event']);
Yanfly.Param.FAdvSurprise = Number(Yanfly.Parameters['Surprise Event']);

//=============================================================================
// BattleManager
//=============================================================================

Yanfly.FAdv.BattleManager_startBattle = BattleManager.startBattle;
BattleManager.startBattle = function() {
	if($gameParty._forceAdvantage) {
		this.checkForceAdvantage($gameParty._forceAdvantage);
		$gameParty._forceAdvantage = undefined;
	}
    else {
		this.checkForceAdvantage(this._forceAdvantage);
		this._forceAdvantage = undefined;
	}
    Yanfly.FAdv.BattleManager_startBattle.call(this);
    this.reserveForceAdvantageCommonEvents();
};

BattleManager.checkForceAdvantage = function(str) {
  if (str === undefined) return;
  var str = str.toUpperCase();
  if (['PRE-EMPTIVE', 'PREEMPTIVE', 'FIRST STRIKE', 'PLAYER'].contains(str)) {
    this._preemptive = true;
    this._surprise = false;
  } else if (['SURPRISE', 'BACK ATTACK', 'ENEMY'].contains(str)) {
    this._preemptive = false;
    this._surprise = true;
  } else if (['NONE', 'NORMAL', 'NEUTRAL'].contains(str)) {
    this._preemptive = false;
    this._surprise = false;
  }
};

BattleManager.reserveForceAdvantageCommonEvents = function() {
    if (this._preemptive) {
      var eventId = Yanfly.Param.FAdvPreemptive;
    } else if (this._surprise) {
      var eventId = Yanfly.Param.FAdvSurprise;
    } else {
      var eventId = Yanfly.Param.FAdvNeutral;
    }
    if (eventId > 0) $gameTemp.reserveCommonEvent(eventId);
};

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

Yanfly.FAdv.Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
  Yanfly.FAdv.Game_Interpreter_pluginCommand.call(this, command, args);
  if (command === 'ForceAdvantage') {
    var str = String(args[0]).toUpperCase();
    if (str === 'CLEAR') str = undefined;
    BattleManager._forceAdvantage = str;
  }
};

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


code:
//=============================================================================
// Yanfly Engine Plugins - FPS Synch Option
// YEP_FpsSynchOption.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.FpsSynch = Yanfly.FpsSynch || {};
Yanfly.FpsSynch.version = 1.03;

//=============================================================================
 /*:
 * @plugindesc v1.03 Adds a new command to Options menu for synching
 * the FPS of moniters with higher FPS rates.
 * @author Yanfly Engine Plugins
 *
 * @param Command Name
 * @desc Command name used inside of the Options menu.
 * @default Synch Monitor FPS
 *
 * @param Default Setting
 * @type boolean
 * @on ON
 * @off OFF
 * @desc The default setting of the Synch Monitor FPS.
 * OFF - false (Recommended)  ON - true
 * @default false
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin is to be used with RPG Maker MV version 1.1.0 and upward.
 *
 * RPG Maker MV is constructed in a way where each update to its engine is done
 * once per frame update. While this is normally fine, as many players view the
 * game through 60 fps, some players experience the game differently as their
 * hardware may run at higher than 60 fps.
 *
 * When RPG Maker MV version 1.1.0 is implemented, it implemented Galenmereth's
 * fluid timestep, which forces the game to always play as if it is 60 fps. In
 * practice, this is great for everybody because players that experience more
 * 60 fps will be able to play the game as if it was 60 fps.
 *
 * However, there comes a problem when a player's hardware isn't strong enough
 * to support RPG Maker MV natively at 60 fps (such as the case with older
 * computers, or weaker mobile devices) or if the player is using video
 * recording software that goes below 60 fps. The game will appear laggy and
 * jumping without good response rates from input commands or possibly even
 * make the player miss out on certain visual frame updates.
 *
 * This plugin places a setting in the Options menu to enable or disable the
 * fluid timestep addition and utilize the former RPG Maker MV engine updating
 * function. This way, players will have the option of using fluid timesteps or
 * opting to not use it instead of forcing it on everybody who may not be able
 * to handle it.
 *
 * ============================================================================
 * Options Core Settings - Adding the New Options
 * ============================================================================
 *
 * If you are using YEP_OptionsCore.js, you can add a new Option using this
 * plugin. Here's the following code/parameter settings you can use with it.
 *
 * ---------
 * Settings:
 * ---------
 *
 * Name:
 * \i[302]Synch Monitor FPS
 *
 * Help Description:
 * Turn this ON if your monitor runs above 60 FPS
 * to synchronize the game to run at 60 FPS.
 *
 * Symbol:
 * synchFps
 *
 * Show/Hide:
 * show = Imported.YEP_SynchFpsOption;
 *
 * Enable:
 * enabled = true;
 *
 * Ext:
 * ext = 0;
 *
 * ----------
 * Functions:
 * ----------
 *
 * Make Option Code:
 * this.addCommand(name, symbol, enabled, ext);
 *
 * Draw Option Code:
 * var rect = this.itemRectForText(index);
 * var statusWidth = this.statusWidth();
 * var titleWidth = rect.width - statusWidth;
 * this.resetTextColor();
 * this.changePaintOpacity(this.isCommandEnabled(index));
 * this.drawOptionsName(index);
 * this.drawOptionsOnOff(index);
 *
 * Process OK Code:
 * var index = this.index();
 * var symbol = this.commandSymbol(index);
 * var value = this.getConfigValue(symbol);
 * this.changeValue(symbol, !value);
 *
 * Cursor Right Code:
 * var index = this.index();
 * var symbol = this.commandSymbol(index);
 * var value = this.getConfigValue(symbol);
 * this.changeValue(symbol, true);
 *
 * Cursor Left Code:
 * var index = this.index();
 * var symbol = this.commandSymbol(index);
 * var value = this.getConfigValue(symbol);
 * this.changeValue(symbol, false);
 *
 * Default Config Code:
 * // Empty. Provided by this plugin.
 *
 * Save Config Code:
 * // Empty. Provided by this plugin.
 *
 * Load Config Code:
 * // Empty. Provided by this plugin.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.03:
 * - Compatibility update with YEP_OptionsCore.js.
 *
 * Version 1.02:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.01:
 * - The plugin is now prevented if the project's core files are under version
 * RPG Maker MV 1.1.0.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= '1.1.0') {

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

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

Yanfly.Param.FpsSynchCmd = String(Yanfly.Parameters['Command Name']);
Yanfly.Param.FpsSDefault = eval(String(Yanfly.Parameters['Default Setting']));

//=============================================================================
// MainCode
//=============================================================================

/*
ConfigManager.synchFps = Yanfly.Param.FpsSDefault;

Yanfly.FpsSynch.ConfigManager_makeData = ConfigManager.makeData;
ConfigManager.makeData = function() {
    var config = Yanfly.FpsSynch.ConfigManager_makeData.call(this);
    config.synchFps = this.synchFps;
    return config;
};

Yanfly.FpsSynch.ConfigManager_applyData = ConfigManager.applyData;
ConfigManager.applyData = function(config) {
    Yanfly.FpsSynch.ConfigManager_applyData.call(this, config);
    this.synchFps = this.readConfigFpsSynch(config, 'synchFps');
};

ConfigManager.readConfigFpsSynch = function(config, name) {
    var value = config[name];
    if (value !== undefined) {
        return value;
    } else {
        return Yanfly.Param.FpsSDefault;
    }
};
*/

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

SceneManager.updateMainFluidTimestep = SceneManager.updateMain;

SceneManager.updateMain = function() {
    if (ConfigManager.synchFps) {
      this.updateMainFluidTimestep();
    } else {
      this.updateMainNoFpsSynch();
    }
};

SceneManager.updateMainNoFpsSynch = function() {
    this.updateInputData();
    this.changeScene();
    this.updateScene();
    this.renderScene();
    this.requestUpdate();
};

//=============================================================================
// Window_Options
//=============================================================================

Yanfly.FpsSynch.Window_Options_addGeneralOptions =
    Window_Options.prototype.addGeneralOptions;
Window_Options.prototype.addGeneralOptions = function() {
    Yanfly.FpsSynch.Window_Options_addGeneralOptions.call(this);
    if (!Imported.YEP_OptionsCore) {
      this.addCommand(Yanfly.Param.FpsSynchCmd, 'synchFps');
    }
};

//=============================================================================
// Version Compatibility Update
//=============================================================================
} else {

var text = '';
text += 'You are getting this error because you are trying to run FPS Synch ';
text += 'Options while your project files are lower than version 1.1.0. \n\n';
text += 'Please visit this thread for instructions on how to update your ';
text += 'project files to 1.1.0 or higher: \n\n';
text += 'http://forums.rpgmakerweb.com/index.php?/topic/';
text += '71400-rpg-maker-mv-v134-update/';
console.log(text);
require('nw.gui').Window.get().showDevTools();

} // (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= '1.1.0')

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