code:
//=============================================================================
// Yanfly Engine Plugins - Target Core Extension - Area of Effect
// YEP_X_AreaOfEffect.js
//=============================================================================

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

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

//=============================================================================
 /*:
 * @plugindesc v1.02 (Requires YEP_BattleEngineCore & YEP_TargetCore)
 * Adds Area of Effect scopes for targeting allies or enemies.
 * @author Yanfly Engine Plugins
 *
 * @param ---Buffer---
 * @default
 *
 * @param Buffer X
 * @parent ---Buffer---
 * @desc The default offset coordinate buffer for battlers.
 * @default 0
 *
 * @param Buffer Y
 * @parent ---Buffer---
 * @desc The default offset coordinate buffer for battlers.
 * @default 0
 *
 * @param Center Animation
 * @parent ---Buffer---
 * @type boolean
 * @on YES
 * @off NO
 * @desc Plays battle animation only on central target?
 * NO - false     YES - true
 * @default true
 *
 * @param ---Circle---
 * @default
 *
 * @param Circle Graphic
 * @parent ---Circle---
 * @type file
 * @dir img/pictures/
 * @require 1
 * @desc Default graphic used for AoE Circles.
 * Place this image inside img/pictures/
 * @default AoE_Circle
 *
 * @param Circle Blend
 * @parent ---Circle---
 * @type select
 * @option Normal
 * @value 0
 * @option Additive
 * @value 1
 * @option Multiply
 * @value 2
 * @option Screen
 * @value 3
 * @desc Blend mode used for AoE Circles.
 * 0: Normal, 1: Additive, 2: Multiply, 3: Screen
 * @default 3
 *
 * @param Circle Height Rate
 * @parent ---Circle---
 * @type number
 * @decimals 2
 * @min 0
 * @desc Default height rate of AoE Circle.
 * @default 0.33
 *
 * @param ---Rectangle---
 * @default
 *
 * @param Rect Graphic
 * @parent ---Rectangle---
 * @type file
 * @dir img/pictures/
 * @require 1
 * @desc Default graphic used for AoE Rectangles.
 * Place this image inside img/pictures/
 * @default AoE_Rect
 *
 * @param Rect Blend
 * @parent ---Rectangle---
 * @type select
 * @option Normal
 * @value 0
 * @option Additive
 * @value 1
 * @option Multiply
 * @value 2
 * @option Screen
 * @value 3
 * @desc Blend mode used for AoE Rectangles.
 * 0: Normal, 1: Additive, 2: Multiply, 3: Screen
 * @default 3
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin requires YEP_BattleEngineCore and YEP_TargetCore. Make sure this
 * plugin is located under YEP_BattleEngineCore and YEP_TargetCore in the
 * plugin list.
 *
 * Sometimes, targeting one foe isn't enough and targeting all foes is too
 * many. The right mix in between would be area of effects to target only a
 * certain area of foes. This plugins enables area of effect targeting to come
 * in the forms of circular areas, column areas, row areas, and even the whole
 * screen.
 *
 * ============================================================================
 * Instructions - Understanding Area of Effect
 * ============================================================================
 *
 * Area of effect scopes don't necessarily select just one target but instead,
 * a group of targets that are close together. Any targets outside of range
 * from the area of effect zone will be added to the scope of targets for the
 * skill or item being used.
 *
 * Whether or not the targets will be struck is relative to the target's hitbox
 * settings. Normally, this is dependent on the target's graphic, but you can
 * set individual hitbox settings for the target using notetags as well.
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * You can use the following notetags to apply area of effect scopes for your
 * skills and items!
 *
 * Skill and Item Notetags:
 *
 *   --- AOE Circle Scope ---
 *
 *   <AOE Radius: x>
 *   Turns the skill into having a target scope with a circular AOE. x is the
 *   amount of pixels of the radius for the AOE Circle.
 *
 *   <AOE Height Rate: x%>
 *   Changes the height to be x% of the diameter of the AOE Circle.
 *
 *   <AOE Graphic: filename>
 *   If you wish to use a different image for the AOE circle for this skill or
 *   item, replace 'filename' with the filename of the graphic found within the
 *   img/pictures/ folder. Do not include the file extension. For example, the
 *   graphic 'aoeblue.png' will result in notetag <AOE Graphic: aoeblue>.
 *
 *   <AOE Hue: x>
 *   This will change the hue of the AOE circle to x. By default, the hue value
 *   is 0. This will alter the color of it.
 *
 *   <AOE Blend: x>
 *   This is the blend mode used for the AOE graphic. 0 is normal with no blend
 *   modes applied. 1 is additive. 2 is multiply. 3 is screen.
 *
 *   *NOTE: This does not work with the unique selection types found with the
 *   YEP_X_SelectionControl plugin.
 *
 *   --- AOE Rectangle Scope ---
 *
 *   <Rect Column: x>
 *   This will make a rectangular area of effect scope that is x pixels wide.
 *   The area of effect zone is vertical and all targets within this zone will
 *   become targets for the action.
 *
 *   <Rect Row: x>
 *   This will make a rectangular area of effect scope that is x pixels tall.
 *   The area of effect zone is horizontal and all targets within this zone
 *   will become targets for the action.
 *
 *   <Rect Screen>
 *   This will target all units within the entirity of the screen. While it is
 *   the same as an all enemies/all allies scope, this can be used to give a
 *   visual representation of which units are selected as a target.
 *
 *   <Rect Graphic: filename>
 *   If you wish to use a different image for the AOE rectangle for this skill
 *   or item, replace 'filename' with the filename of the graphic found within
 *   the img/pictures/ folder. Do not include the file extension. For example,
 *   the graphic 'rectblue.png' will result in notetag <AOE Graphic: rectblue>.
 *
 *   <Rect Hue: x>
 *   This will change the hue of the AOE rectangle to x. By default, the hue
 *   value is 0. This will alter the color of it.
 *
 *   <Rect Blend: x>
 *   This is the blend mode used for the AOE graphic. 0 is normal with no blend
 *   modes applied. 1 is additive. 2 is multiply. 3 is screen.
 *
 *   *NOTE: This does not work with the unique selection types found with the
 *   YEP_X_SelectionControl plugin.
 *
 *   --- Animation Settings ---
 *
 *   <AOE Center Animation>
 *   This will cause the animation for an AOE skill to be played to center on
 *   the first target of the AOE group, which is usually the center of the
 *   AOE targets.
 *
 *   <AOE Group Animation>
 *   This will cause the animation for an AOE skill to be played on all of the
 *   targets within the AOE group as if normally done.
 *
 * Actor and Enemy Notetags:
 *
 *   --- AOE Hitbox Settings ---
 *
 *   <AOE Buffer X: +x>
 *   <AOE Buffer X: -x>
 *
 *   <AOE Buffer Y: +x>
 *   <AOE Buffer Y: -x>
 *   Changes the buffer x/y of the battler when an AOE image is placed on the
 *   battler. This is also the offset from the center location at which the
 *   AOE targets will be calculated, too. If this notetag isn't used, the
 *   buffer value used will be from the plugin parameters.
 *
 *   <AOE Hitbox Width: x>
 *   <AOE Hitbox Height: x>
 *   This will adjust the hitbox of the battler to have an AOE hitbox width of
 *   x or an AOE hitbox height of x.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.02:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.01:
 * - Plugin update to provide checks against certain selection condition types
 * used with YEP_X_SelectionControl. Unique conditions will disable AoE types
 * to prevent clashing which include enemy/actor switching, certain rows, and
 * toggling between single/multiple.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

if (Imported.YEP_BattleEngineCore && Imported.YEP_TargetCore) {

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

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

Yanfly.Param.AOEBufferX = Number(Yanfly.Parameters['Buffer X']);
Yanfly.Param.AOEBufferY = Number(Yanfly.Parameters['Buffer Y']);
Yanfly.Param.AOECenterAni = eval(String(Yanfly.Parameters['Center Animation']));

Yanfly.Param.AOECirGraphic = String(Yanfly.Parameters['Circle Graphic']);
Yanfly.Param.AOECirBlend = Number(Yanfly.Parameters['Circle Blend']);
Yanfly.Param.AOECirHeightRate = Number(Yanfly.Parameters['Circle Height Rate']);

Yanfly.Param.AOERectGraphic = String(Yanfly.Parameters['Rect Graphic']);
Yanfly.Param.AOERectBlend = Number(Yanfly.Parameters['Rect Blend']);

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

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

  if (!Yanfly._loaded_YEP_X_AreaOfEffect) {
    this.processAOENotetags2($dataActors);
    this.processAOENotetags2($dataEnemies);
    Yanfly._loaded_YEP_X_AreaOfEffect = true;
  }

  return true;
};

Yanfly.AOE.DataManager_processTargetNotetags1 =
    DataManager.processTargetNotetags1;
DataManager.processTargetNotetags1 = function(group) {
    Yanfly.AOE.DataManager_processTargetNotetags1.call(this, group);
    this.processAOENotetags1(group);
};

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

    obj.aoeCircleRadius = 0;
    obj.aoeCircleGraphic = Yanfly.Param.AOECirGraphic;
    obj.aoeCircleHue = 0;
    obj.aoeCircleBlend = Yanfly.Param.AOECirBlend;
    obj.aoeCircleHeightRate = Yanfly.Param.AOECirHeightRate;
    obj.aoeCenterAnimation = Yanfly.Param.AOECenterAni;
    obj.aoeRectColumn = 0;
    obj.aoeRectRow = 0;
    obj.aoeRectAll = false;
    obj.aoeRectGraphic = Yanfly.Param.AOERectGraphic
    obj.aoeRectHue = 0;
    obj.aoeRectBlend = Yanfly.Param.AOERectBlend;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<AOE RADIUS:[ ](\d+)>/i)) {
        obj.aoeCircleRadius = parseInt(RegExp.$1);
      } else if (line.match(/<AOE GRAPHIC:[ ](.*)>/i)) {
        obj.aoeCircleGraphic = String(RegExp.$1);
      } else if (line.match(/<AOE HUE:[ ](\d+)>/i)) {
        obj.aoeCircleHue = parseInt(RegExp.$1);
      } else if (line.match(/<AOE BLEND:[ ](\d+)>/i)) {
        obj.aoeCircleBlend = parseInt(RegExp.$1);
      } else if (line.match(/<AOE HEIGHT:[ ](\d+)([%％])>/i)) {
        obj.aoeCircleHeightRate = parseFloat(RegExp.$1) * 0.01;
      } else if (line.match(/<AOE CENTER ANIMATION>/i)) {
        obj.aoeCenterAnimation = true;
      } else if (line.match(/<AOE GROUP ANIMATION>/i)) {
        obj.aoeCenterAnimation = false;
      } else if (line.match(/<RECT GRAPHIC:[ ](.*)>/i)) {
        obj.aoeRectGraphic = String(RegExp.$1);
      } else if (line.match(/<RECT HUE:[ ](\d+)>/i)) {
        obj.aoeRectHue = parseInt(RegExp.$1);
      } else if (line.match(/<RECT BLEND:[ ](\d+)>/i)) {
        obj.aoeRectBlend = parseInt(RegExp.$1);
      } else if (line.match(/<RECT COLUMN:[ ](\d+)>/i)) {
        obj.aoeRectColumn = parseInt(RegExp.$1);
        //obj.aoeRectRow = 0;
      } else if (line.match(/<RECT ROW:[ ](\d+)>/i)) {
        obj.aoeRectRow = parseInt(RegExp.$1);
        //obj.aoeRectColumn = 0;
      } else if (line.match(/<RECT SCREEN>/i)) {
        obj.aoeRectAll = true;
        obj.aoeRectColumn = 0;
        obj.aoeRectRow = 0;
      }
    }
  }
};

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

    obj.aoeBufferX = Yanfly.Param.AOEBufferX;
    obj.aoeBufferY = Yanfly.Param.AOEBufferY;
    obj.aoeHitboxW = 0;
    obj.aoeHitboxH = 0;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<AOE BUFFER X:[ ]([\+\-]\d+)>/i)) {
        obj.aoeBufferX = parseInt(RegExp.$1);
      } else if (line.match(/<AOE BUFFER Y:[ ]([\+\-]\d+)>/i)) {
        obj.aoeBufferY = parseInt(RegExp.$1);
      } else if (line.match(/<AOE HITBOX WIDTH:[ ](\d+)>/i)) {
        obj.aoeHitboxW = parseInt(RegExp.$1);
      } else if (line.match(/<AOE HITBOX HEIGHT:[ ](\d+)>/i)) {
        obj.aoeHitboxH = parseInt(RegExp.$1);
      }
    }
  }
};

Yanfly.AOE.DataManager_setDefaultActions = DataManager.setDefaultActions;
DataManager.setDefaultActions = function(obj) {
    if (obj.aoeCenterAnimation && this.isAoeSkill(obj)) {
      this.setAoeActions(obj);
    } else {
      Yanfly.AOE.DataManager_setDefaultActions.call(this, obj);
    }
};

DataManager.isAoeSkill = function(obj) {
    if (obj.aoeCircleRadius > 0) return true;
    if (obj.aoeRectColumn > 0) return true;
    if (obj.aoeRectRow > 0) return true;
    return obj.aoeRectAll;
};

DataManager.setAoeActions = function(obj) {
    obj.setupActions = Yanfly.BEC.DefaultActionSetup.slice();
    if (obj.aoeCenterAnimation) {
      obj.wholeActions = [
        ['PERFORM ACTION'],
        ['ACTION ANIMATION', ['FIRST']],
        ['WAIT FOR ANIMATION']
      ];
    } else {
      obj.wholeActions = [
        ['PERFORM ACTION'],
        ['ACTION ANIMATION', ['TARGETS']],
        ['WAIT FOR ANIMATION']
      ];
    }
    this.addActionEffects(obj, obj.wholeActions);
    obj.targetActions = [];
    obj.followActions = Yanfly.BEC.DefaultActionFollow.slice();
    obj.finishActions = Yanfly.BEC.DefaultActionFinish.slice();
};

DataManager.isAoeForbidden = function(obj) {
  if (!obj) return true;
  if (obj.isAoeForbidden !== undefined) return obj.isAoeForbidden;
  obj.isAoeForbidden = false;
  if (Imported.YEP_X_SelectionControl) {
    var arr = obj.selectConditions;
    var length = arr.length;
    for (var i = 0; i < length; ++i) {
      var line = arr[i];
      if (line) {
        if (line.match(/ENEMY OR ACTOR SELECT/i)) {
          obj.isAoeForbidden = true;
          break;
        } else if (line.match(/ACTOR OR ENEMY SELECT/i)) {
          obj.isAoeForbidden = true;
          break;
        } else if (line.match(/SINGLE OR MULTIPLE SELECT/i)) {
          obj.isAoeForbidden = true;
          break;
        } else if (line.match(/ROW[ ](\d+)/i)) {
          obj.isAoeForbidden = true;
          break;
        }
      }
    }
  }
  return obj.isAoeForbidden;
};

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

Yanfly.AOE.BattleManager_startAllSelection = BattleManager.startAllSelection;
BattleManager.startAllSelection = function() {
    if (this.inputtingAction().isAoe()) {
      this._customTargetSelectGroup = this.inputtingAction().makeTargets();
    } else {
      Yanfly.AOE.BattleManager_startAllSelection.call(this);
    }
};

Yanfly.AOE.BattleManager_makeActionTargets =
    BattleManager.makeActionTargets;
BattleManager.makeActionTargets = function(string) {
    if ('FIRST' === string.toUpperCase()) {
      return [this._targets[0]];
    }
    return Yanfly.AOE.BattleManager_makeActionTargets.call(this, string);
};

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

Game_Battler.prototype.aoeX = function() {
    return this.spritePosX() + this.aoeBufferX();
};

Game_Battler.prototype.aoeY = function() {
    return this.spritePosY() - this.spriteHeight()/2 + this.aoeBufferY();
};

Game_Battler.prototype.aoeBufferX = function() {
    return 0;
};

Game_Battler.prototype.aoeBufferY = function() {
    return 0;
};

Game_Battler.prototype.aoeWidth = function() {
    return this.spriteWidth();
};

Game_Battler.prototype.aoeHeight = function() {
    return this.spriteHeight();
};

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

Game_Actor.prototype.aoeBufferX = function() {
    return this.actor().aoeBufferX;
};

Game_Actor.prototype.aoeBufferY = function() {
    return this.actor().aoeBufferY;
};

Game_Actor.prototype.aoeWidth = function() {
    return this.actor().aoeHitboxW || this.spriteWidth();
};

Game_Actor.prototype.aoeHeight = function() {
    return this.actor().aoeHitboxH || this.spriteHeight();
};

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

Game_Enemy.prototype.aoeBufferX = function() {
	let addBufferX = 0;
	if(this._hasSelectionVariables) addBufferX += this._selectionAoeBufferX;
    return this.enemy().aoeBufferX + addBufferX;
};

Game_Enemy.prototype.aoeBufferY = function() {
	let addBufferY = 0;
	if(this._hasSelectionVariables) addBufferY += this._selectionAoeBufferY;
    return this.enemy().aoeBufferY + addBufferY;
};

Game_Enemy.prototype.aoeWidth = function() {
    return this.enemy().aoeHitboxW || this.spriteWidth();
};

Game_Enemy.prototype.aoeHeight = function() {
    return this.enemy().aoeHitboxH || this.spriteHeight();
};

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

Game_Action.prototype.isAoeForbidden = function() {
    return DataManager.isAoeForbidden(this.item());
};

Game_Action.prototype.isAoe = function() {
    if (this.isAoeForbidden()) return false;
    return this.isAoeCircle() || this.isAoeRect();
};

Game_Action.prototype.isAoeCircle = function() {
    if (this.isAoeForbidden()) return false;
    return this.item().aoeCircleRadius > 0;
};

Game_Action.prototype.isAoeRect = function() {
    if (this.isAoeForbidden()) return false;
    if (this.item().aoeRectColumn > 0) return true;
    if (this.item().aoeRectRow > 0) return true;
    return this.item().aoeRectAll;
};

Yanfly.AOE.Game_Action_makeTargets = Game_Action.prototype.makeTargets;
Game_Action.prototype.makeTargets = function() {
    var targets = Yanfly.AOE.Game_Action_makeTargets.call(this);
    if (this.isAoe()) this.addAoeTargets(targets);
    return targets;
};

Game_Action.prototype.addAoeTargets = function(targets) {
    if (this.isAoeCircle()) this.addAoeCircleTargets(targets);
    if (this.isAoeRect()) this.addAoeRectTargets(targets);
};

Game_Action.prototype.addAoeCircleTargets = function(targets) {
    var main = targets[0];
    if (!main) return;
    if (this.isForFriend()) {
      var group = this.friendsUnit().aliveMembers();
    } else {
      var group = this.opponentsUnit().aliveMembers();
    }
    var length = group.length;
    for (var i = 0; i < length; ++i) {
      var member = group[i];
      if (!member) continue;
      if (targets.contains(member)) continue;
      if (this.isInsideAoeCircle(main, member)) targets.push(member);
    }
};

Game_Action.prototype.isInsideAoeCircle = function(main, target) {
    var skill = this.item();
    var radius = skill.aoeCircleRadius;
    var height = skill.aoeCircleHeightRate;
    var mainX = main.aoeX();
    var mainY = main.aoeY();
    var targetX = target.aoeX();
    var targetY = target.aoeY();
    if (mainX > targetX) {
      targetX = Math.min(mainX, target.aoeX() + target.aoeWidth() / 2);
    } else if (mainX < targetX) {
      targetX = Math.max(mainX, target.aoeX() - target.aoeWidth() / 2);
    }
    if (mainY > targetY) {
      targetY = Math.min(mainY, target.aoeY());
    } else if (mainY < targetY) {
      targetY = Math.max(mainY, target.aoeY() - target.aoeHeight());
    }
    var x =  (targetX - mainX) * Math.cos(0) + (targetY - mainY) * Math.sin(0);
    var y = -(targetX - mainX) * Math.sin(0) + (targetY - mainY) * Math.cos(0);
    var a = radius; var b = radius * Math.max(height, 0.001);
    var c = (Math.pow(x, 2) / Math.pow(a, 2));
    c += (Math.pow(y, 2) / Math.pow(b, 2));
    return c <= 1;
};

Game_Action.prototype.addAoeRectTargets = function(targets) {
    var main = targets[0];
    if (!main) return;
    if (this.isForFriend()) {
      var group = this.friendsUnit().aliveMembers();
    } else {
      var group = this.opponentsUnit().aliveMembers();
    }
    var rect = this.aoeRect(main);
    var length = group.length;
    for (var i = 0; i < length; ++i) {
      var member = group[i];
      if (!member) continue;
      if (targets.contains(member)) continue;
      if (this.isInsideAoeRect(rect, member)) targets.push(member);
    }
};

Game_Action.prototype.aoeRect = function(main) {
    var skill = this.item();
    var rect = new Rectangle();
    if (skill.aoeRectAll) {
      rect.width = Graphics.boxWidth;
      rect.height = Graphics.boxHeight;
      rect.x = 0;
      rect.y = 0;
	} else if (skill.aoeRectColumn > 0 && skill.aoeRectRow > 0) {
		rect.width = skill.aoeRectColumn;
		rect.height = skill.aoeRectRow;
		rect.x = main.aoeX() - rect.width / 2;
		//rect.y = main.aoeY() - rect.height / 2;
		rect.y = main.aoeY();
    } else if (skill.aoeRectColumn > 0) {
      rect.width = skill.aoeRectColumn;
      rect.height = Graphics.boxHeight;
      rect.x = main.aoeX() - rect.width / 2;
      rect.y = 0;
    } else if (skill.aoeRectRow > 0) {
      rect.width = Graphics.boxWidth;
      rect.height = skill.aoeRectRow;
      rect.x = 0;
      rect.y = main.aoeY() - rect.height / 2;
    }
    return rect;
};

Game_Action.prototype.isInsideAoeRect = function(r1, target) {
    var r2 = new Rectangle();
    r2.x = target.aoeX() - target.aoeWidth() / 2;
	r2.y = target.spritePosY() - target.aoeHeight();
    r2.width = target.aoeWidth();
    r2.height = target.aoeHeight();
    return !(r2.x > r1.x + r1.width || r2.x + r2.width < r1.x ||
      r2.y > r1.y + r1.height || r2.y + r2.height < r1.y);
};

//=============================================================================
// Sprite_AoeCircle
//=============================================================================

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

Sprite_AoeCircle.prototype = Object.create(Sprite_Base.prototype);
Sprite_AoeCircle.prototype.constructor = Sprite_AoeCircle;

Sprite_AoeCircle.prototype.initialize = function() {
    Sprite_Base.prototype.initialize.call(this);
    this.initMembers();
};

Sprite_AoeCircle.prototype.initMembers = function() {
    this._glowRate = 8;
    this._radius = 0;
    this._aoeGraphic = true;
    this._currentImage = '';
    this.hide();
    this.anchor.x = 0.5;
    this.anchor.y = 0.5;
};

Sprite_AoeCircle.prototype.setup = function(skill) {
    this._skill = skill;
    if (DataManager.isAoeForbidden(skill)) return;
    if (this._skill.aoeCircleRadius <= 0) return;
    this._targetIndex = -1;
    this._radius = this._skill.aoeCircleRadius;
    this.show();
    this.createBitmap();
    this._glowRate = 8;
    this.opacity = 0;
};

Sprite_AoeCircle.prototype.createBitmap = function() {
    var filename = this._skill.aoeCircleGraphic;
    var hue = this._skill.aoeCircleHue;
    this.bitmap = ImageManager.loadPicture(filename, hue);
    this.blendMode = this._skill.aoeCircleBlend;
};

Sprite_AoeCircle.prototype.update = function() {
    Sprite_Base.prototype.update.call(this);
    if (!this.visible) return;
    this.updateLocation();
    this.updateScale();
    this.updateOpacity();
};

Sprite_AoeCircle.prototype.updateLocation = function() {
    var scene = SceneManager._scene;
    if (scene._enemyWindow && scene._enemyWindow.active) {
      var target = scene._enemyWindow.enemy();
    } else if (scene._actorWindow && scene._actorWindow.active) {
      var target = scene._actorWindow.actor();
    } else {
      return;
    }
    this.x = target.aoeX();
    this.y = target.aoeY();
    if (this._targetIndex !== target.index()) {
      BattleManager.inputtingAction().setTarget(target.index());
      this._targetIndex = target.index();
      BattleManager.startAllSelection();
    }
};

Sprite_AoeCircle.prototype.updateScale = function() {
    var diameter = this._radius * 2;
    this.scale.x = diameter / (Math.max(1, this.bitmap.width));
    this.scale.y = this.scale.x * this._skill.aoeCircleHeightRate;
};

Sprite_AoeCircle.prototype.updateOpacity = function() {
    this.opacity += this._glowRate;
    if (this.opacity >= 255) {
      this._glowRate = -8;
    } else if (this.opacity <= 64) {
      this._glowRate = 8;
    }
};

//=============================================================================
// Sprite_AoeRect
//=============================================================================

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

Sprite_AoeRect.prototype = Object.create(Sprite_Base.prototype);
Sprite_AoeRect.prototype.constructor = Sprite_AoeRect;

Sprite_AoeRect.prototype.initialize = function() {
    Sprite_Base.prototype.initialize.call(this);
    this.initMembers();
};

Sprite_AoeRect.prototype.initMembers = function() {
    this._glowRate = 8;
    this._aoeGraphic = true;
    this._currentImage = '';
    this.hide();
    this.anchor.x = 0.5;
    //this.anchor.y = 0.5;
};

Sprite_AoeRect.prototype.setup = function(skill) {
    this._skill = skill;
    if (DataManager.isAoeForbidden(skill)) return;
	if (this._skill.aoeRectColumn > 0 && this._skill.aoeRectRow > 0) {
      this._widthPixels = this._skill.aoeRectColumn;
      this._heightPixels = this._skill.aoeRectRow;
    } else if (this._skill.aoeRectColumn > 0) {
      this._widthPixels = this._skill.aoeRectColumn;
      this._heightPixels = Graphics.boxWidth;
    } else if (this._skill.aoeRectRow > 0) {
      this._widthPixels = Graphics.boxWidth;
      this._heightPixels = this._skill.aoeRectRow;
    } else if (this._skill.aoeRectAll) {
      this._widthPixels = Graphics.boxWidth;
      this._heightPixels = Graphics.boxWidth;
    } else {
      return;
    }
    this._targetIndex = -1;
    this.show();
    this.createBitmap();
    this._glowRate = 8;
    this.opacity = 0;
};

Sprite_AoeRect.prototype.createBitmap = function() {
    var filename = this._skill.aoeRectGraphic;
    var hue = this._skill.aoeRectHue;
    this.bitmap = ImageManager.loadPicture(filename, hue);
    this.blendMode = this._skill.aoeRectBlend;
};

Sprite_AoeRect.prototype.update = function() {
    Sprite_Base.prototype.update.call(this);
	this.updateAoEImage();
    if (!this.visible) return;
    this.updateLocation();
    this.updateScale();
    this.updateOpacity();
};

Sprite_AoeRect.prototype.updateLocation = function() {
    var scene = SceneManager._scene;
	let target = false;
    if (scene._enemyWindow && scene._enemyWindow.active) {
      target = scene._enemyWindow.enemy();
    } else if (scene._actorWindow && scene._actorWindow.active) {
      target = scene._actorWindow.actor();
    } else {
      return;
    }
	if(!target) return;
	if(target._hasSelectionVariables && target._selectionAoeRow > 0 && target._selectionAoeColumn > 0) {
		this.x = target.aoeX();
		this.y = target.aoeY();
	}
	else if (this._skill.aoeRectColumn > 0 && this._skill.aoeRectRow > 0) {
		this.x = target.aoeX();
		this.y = target.aoeY();
    } else if (this._skill.aoeRectColumn > 0) {
      this.x = target.aoeX();
      this.y = Graphics.boxHeight / 2;
    } else if (this._skill.aoeRectRow > 0) {
      this.x = Graphics.boxWidth / 2;
      this.y = target.aoeY();
    } else if (this._skill.aoeRectAll) {
      this.x = Graphics.boxWidth / 2;
      this.y = Graphics.boxHeight;
    } else {
    }
    if (this._targetIndex !== target.index()) {
      BattleManager.inputtingAction().setTarget(target.index());
      this._targetIndex = target.index();
	  if(this._skill.aoeRectColumn > 0 || this._skill.aoeRectRow > 0)
		BattleManager.startAllSelection();
    }
};

Sprite_AoeRect.prototype.updateScale = function() {
    this.scale.x = this._widthPixels / (Math.max(1, this.bitmap.width));
    this.scale.y = this._heightPixels / (Math.max(1, this.bitmap.height));
};

Sprite_AoeRect.prototype.updateOpacity = function() {
    this.opacity += this._glowRate;
    if (this.opacity >= 255) {
      this._glowRate = -8;
    } else if (this.opacity <= 64) {
      this._glowRate = 8;
    }
};

//=============================================================================
// Spriteset_Battle
//=============================================================================

Yanfly.AOE.Spriteset_Battle_createBattleback =
    Spriteset_Battle.prototype.createBattleback;
Spriteset_Battle.prototype.createBattleback = function() {
    Yanfly.AOE.Spriteset_Battle_createBattleback.call(this);
    this.createAoeSprites();
};

Spriteset_Battle.prototype.createAoeSprites = function() {
    this._aoeCircleSprite = new Sprite_AoeCircle();
    this._battleField.addChild(this._aoeCircleSprite);
    this._aoeRectSprite = new Sprite_AoeRect();
    this._battleField.addChild(this._aoeRectSprite);
};

Spriteset_Battle.prototype.setupAoe = function(action) {
    if (!action) return;
    if (!action.item()) return;
    this._aoeCircleSprite.setup(action.item());
    this._aoeRectSprite.setup(action.item());
};

Spriteset_Battle.prototype.closeAoe = function() {
    this._aoeCircleSprite.hide();
    this._aoeRectSprite.hide();
    BattleManager.clearCustomTargetSelectGroup();
};

Spriteset_Battle.prototype.battleFieldDepthCompare = function(a, b) {
    if (a.tilePosition && !b.tilePosition) return -1;
    if (b.tilePosition && !a.tilePosition) return 1;
    if (a._aoeGraphic && !b._aoeGraphic) return -1;
    if (b._aoeGraphic && !a._aoeGraphic) return 1;
    var priority = BattleManager.getSpritePriority();
    if (a._battler && b._battler && priority !== 0) {
      if (priority === 1) {
        if (a._battler.isActor() && b._battler.isEnemy()) return 1;
        if (a._battler.isEnemy() && b._battler.isActor()) return -1;
      } else if (priority === 2) {
        if (a._battler.isActor() && b._battler.isEnemy()) return -1;
        if (a._battler.isEnemy() && b._battler.isActor()) return 1;
      }
    }
    if (a.z < b.z) return -1;
    if (a.z > b.z) return 1;
    if (a.y < b.y) return -1;
    if (a.y > b.y) return 1;
    return 0;
};

//=============================================================================
// Scene_Battle
//=============================================================================

Yanfly.AOE.Scene_Battle_selectEnemySelection =
    Scene_Battle.prototype.selectEnemySelection;
Scene_Battle.prototype.selectEnemySelection = function() {
    Yanfly.AOE.Scene_Battle_selectEnemySelection.call(this);
    this._spriteset.setupAoe(BattleManager.inputtingAction());
};

Yanfly.AOE.Scene_Battle_onEnemyOk = Scene_Battle.prototype.onEnemyOk;
Scene_Battle.prototype.onEnemyOk = function() {
    Yanfly.AOE.Scene_Battle_onEnemyOk.call(this);
    this._spriteset.closeAoe();
};

Yanfly.AOE.Scene_Battle_onEnemyCancel = Scene_Battle.prototype.onEnemyCancel;
Scene_Battle.prototype.onEnemyCancel = function() {
    Yanfly.AOE.Scene_Battle_onEnemyCancel.call(this);
    this._spriteset.closeAoe();
};

Yanfly.AOE.Scene_Battle_selectActorSelection =
    Scene_Battle.prototype.selectActorSelection;
Scene_Battle.prototype.selectActorSelection = function() {
    Yanfly.AOE.Scene_Battle_selectActorSelection.call(this);
    this._spriteset.setupAoe(BattleManager.inputtingAction());
};

Yanfly.AOE.Scene_Battle_onActorOk = Scene_Battle.prototype.onActorOk;
Scene_Battle.prototype.onActorOk = function() {
    Yanfly.AOE.Scene_Battle_onActorOk.call(this);
    this._spriteset.closeAoe();
};

Yanfly.AOE.Scene_Battle_onActorCancel = Scene_Battle.prototype.onActorCancel;
Scene_Battle.prototype.onActorCancel = function() {
    Yanfly.AOE.Scene_Battle_onActorCancel.call(this);
    this._spriteset.closeAoe();
};

//=============================================================================
// End of File
//=============================================================================
};


code:
//=============================================================================
// Yanfly Engine Plugins - Damage Extension - Armor Scaling
// YEP_X_ArmorScaling.js
//=============================================================================

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

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

//=============================================================================
 /*:
 * @plugindesc v1.04 (Requires YEP_DamageCore.js) Scale defensive
 * stats relative to a universal scale.
 * @author Yanfly Engine Plugins
 *
 * @param ---Physical---
 * @default
 *
 * @param Positive Physical Rate
 * @parent ---Physical---
 * @desc This is the multiplier rate for physical attacks if the
 * calculated armor is a positive value.
 * @default value *= 100 / (100 + armor)
 *
 * @param Negative Physical Rate
 * @parent ---Physical---
 * @desc This is the multiplier rate for physical attacks if the
 * calculated armor is a negative value.
 * @default value *= 2 - (100 / (100 - armor))
 *
 * @param Physical Base Armor
 * @parent ---Physical---
 * @desc This is the physical base armor calculation.
 * @default target.def / 2
 *
 * @param ---Magical---
 * @default
 *
 * @param Positive Magical Rate
 * @parent ---Magical---
 * @desc This is the multiplier rate for magical attacks if the
 * calculated armor is a positive value.
 * @default value *= 100 / (100 + armor)
 *
 * @param Negative Magical Rate
 * @parent ---Magical---
 * @desc This is the multiplier rate for magical attacks if the
 * calculated armor is a negative value.
 * @default value *= 2 - (100 / (100 - armor))
 *
 * @param Magical Base Armor
 * @parent ---Magical---
 * @desc This is the magical base armor calculation.
 * @default target.mdf / 2
 *
 * @param ---Certain---
 * @default
 *
 * @param Positive Certain Rate
 * @parent ---Certain---
 * @desc This is the multiplier rate for certain attacks if the
 * calculated armor is a positive value.
 * @default value *= 100 / (100 + armor)
 *
 * @param Negative Certain Rate
 * @parent ---Certain---
 * @desc This is the multiplier rate for certain attacks if the
 * calculated armor is a negative value.
 * @default value *= 2 - (100 / (100 - armor))
 *
 * @param Certain Base Armor
 * @parent ---Certain---
 * @desc This is the certain hit base armor calculation.
 * @default 0
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin requires YEP_DamageCore.
 * Make sure this plugin is located under YEP_DamageCore in the plugin list.
 *
 * This plugin serves as a damage balancing plugin to make numbers across the
 * battlefield more universal for both actors and enemies alike and gets past
 * the flaws that ATK - DEF formulas have.
 *
 * ============================================================================
 * Armor Scaling
 * ============================================================================
 *
 * Armor Scaling allows the damage formula to be rid of "b.def * 2" and similar
 * calculations in favor of scaling the damage relative to the armor values
 * that the attack target has. The following is the armor scaling formula for
 * both positive and negative armor values:
 *
 *            Positive Armor                     Negative Armor
 *
 *                 100                                     100
 *     Rate = -------------                Rate = 2 - -------------
 *             100 + armor                             100 - armor
 *
 * To get an idea of how armor scaling will affect damage, you can visit
 * FlyingDream's Armor Scaling Calculator here:
 *
 *     http://yanfly.moe/tools/armorscalingcalculator/
 *
 * For quick reference, here's a table on how 1,000 base damage is affected.
 *
 * Armor Level   Rate%    Damage           Armor Level   Rate%    Damage
 *           1   99.01%   990                       -1   100.99%  1,010
 *           2   98.04%   980                       -2   101.96%  1,020
 *           3   97.09%   971                       -3   102.91%  1,029
 *           4   96.15%   962                       -4   103.85%  1,038
 *           5   95.24%   952                       -5   104.76%  1,048
 *           6   94.34%   943                       -6   105.66%  1,057
 *           7   93.46%   935                       -7   106.54%  1,065
 *           8   92.59%   926                       -8   107.41%  1,074
 *           9   91.74%   917                       -9   108.26%  1,083
 *          10   90.91%   909                      -10   109.09%  1,091
 *          25   80.00%   800                      -25   120.00%  1,200
 *          50   66.67%   667                      -50   133.33%  1,333
 *          75   57.14%   571                      -75   142.86%  1,429
 *         100   50.00%   500                     -100   150.00%  1,500
 *         150   40.00%   400                     -150   160.00%  1,600
 *         200   33.33%   333                     -200   166.67%  1,667
 *         250   28.57%   286                     -250   171.43%  1,714
 *         300   25.00%   250                     -300   175.00%  1,750
 *         350   22.22%   222                     -350   177.78%  1,778
 *         400   20.00%   200                     -400   180.00%  1,800
 *         450   18.18%   182                     -450   181.82%  1,818
 *         500   16.67%   167                     -500   183.33%  1,833
 *         550   15.38%   154                     -550   184.62%  1,846
 *         600   14.29%   143                     -600   185.71%  1,857
 *         650   13.33%   133                     -650   186.67%  1,867
 *         700   12.50%   125                     -700   187.50%  1,875
 *         750   11.76%   118                     -750   188.24%  1,882
 *         800   11.11%   111                     -800   188.89%  1,889
 *         850   10.53%   105                     -850   189.47%  1,895
 *         900   10.00%   100                     -900   190.00%  1,900
 *         950    9.52%    95                     -950   190.48%  1,905
 *         999    9.10%    91                     -999   190.90%  1,909
 *       9,999    0.99%    10                   -9,999   199.01%  1,990
 *      99,999    0.10%     1                  -99,999   199.90%  1,999
 *     999,999    0.01%     0                 -999,999   199.99%  2,000
 *   9,999,999    0.00%     0               -9,999,999   200.00%  2,000
 *
 * Using the default base armor formula of 2 defense points is equal to 1
 * armor, this means at 200 defense, a battler will take only 50% damage. At
 * 999 defense, the battler will take a little bit more than 16.67% damage.
 * At those values without armor scaling, damage can be entirely undone for
 * that very matter. This goes to show how effective armor scaling can be to
 * maintain long-term balancing.
 *
 * ============================================================================
 * Armor Reduction and Armor Penetration
 * ============================================================================
 *
 * There are various modifiers that can alter the armor level before the armor
 * scaling rate is applied to damage. Armor goes through four main steps and
 * they are as follows.
 *
 * 1. Armor Reduction, Flat
 * 2. Armor Reduction, Percentage
 * 3. Armor Penetration, Percentage
 * 4. Armor Penetration, Flat
 *
 * In step 1 (Armor Reduction, Flat), the target's armor is reduced by a value.
 * Flat armor reduction stacks additively. Flat armor reduction can reduce a
 * target's armor below zero. For example, if an enemy with 10 armor has their
 * armor reduced by 25, the enemy will have -15 armor. Armor reduction values
 * are provided by target and not the attacker.
 *
 * In step 2 (Armor Reduction, Percentage), the target's armor is multiplied by
 * a percentage (100% - the listed value). Percentage armor reduction stacks
 * multiplicatively and is ignored if the target's armor is 0 or less.
 * Percentage armor reduction makes a bigger difference on targets with higher
 * armor. For instance, with 40% armor reduction, a target with 200 armor will
 * lose 80 while a target with only 50 armor will lose 20. Armor reduction
 * values are provided by the target and not the attacker.
 *
 * In step 3 (Armor Penetration, Percentage), the target's armor is multiplied
 * by a percentage (100% - the listed value). Percentage armor penetration
 * stacks multiplicatively and is ignored if the target's armor is 0 or less.
 * Percentage armor penetration makes a bigger difference on targets with higher
 * armor. For instance, with 40% armor penetration, a target with 200 armor will
 * be considered as having 80 less while a target with only 50 armor will be
 * considered as having 20 less. Armor penetration values are provided by the
 * attacker and not the target.
 *
 * In step 4 (Armor Penetration, Flat), the target's armor is treated as being
 * reduced by an amount for purposes of damage calculation, but cannot be
 * reduced below 0. Flat armor penetration stacks additively. Armor penetration
 * values are provided by the attacker and not the target.
 *
 * ============================================================================
 * Notetags
 * ============================================================================
 *
 * You may use these notetags to adjust various factors for armor scaling rates
 * and calculations.
 *
 * Skill and Item Notetags:
 *   <Armor Reduction: x>
 *   Causes the skill/item to reduce the target's armor level by x. This is
 *   calculated first above everything else.
 *
 *   <Armor Reduction: x%>
 *   Causes the skill/item to reduce the target's armor level by x%. This is
 *   calculated second but is ignored if the armor level is less than 0.
 *
 *   <Armor Penetration: x%>
 *   Causes the skill/item to reduce the target's armor level by x% (but will
 *   not go past 0). This is calculated third.
 *
 *   <Armor Penetration: x>
 *   Causes the skill/item to reduce the target's armor level by x (but will
 *   not go past 0). This is calculated last.
 *
 *   <Bypass Armor Scaling>
 *   This notetag allows you to bypass the armor scaling process for this
 *   individual skill/item.
 *
 * Actor, Class, Enemy, Weapon, Armor, State Notetags:
 *   <Physical Armor Reduction: x>
 *   Causes this actor to lose x armor when targeted by physical skills/items.
 *   This is calculated first.
 *
 *   <Magical Armor Reduction: x>
 *   Causes this actor to lose x armor when targeted by magical skills/items.
 *   This is calculated first.
 *
 *   <Certain Armor Reduction: x>
 *   Causes this actor to lose x armor when targeted by certain skills/items.
 *   This is calculated first.
 *
 *   <Physical Armor Reduction: x%>
 *   Causes this actor to lose x% armor when targeted by physical skills/items.
 *   This is calculated second.
 *
 *   <Magical Armor Reduction: x%>
 *   Causes this actor to lose x% armor when targeted by magical skills/items.
 *   This is calculated second.
 *
 *   <Certain Armor Reduction: x%>
 *   Causes this actor to lose x% armor when targeted by certain skills/items.
 *   This is calculated second.
 *
 *   <Physical Armor Penetration: x%>
 *   Causes this actor to cause the target to lose x% armor when using a
 *   physical skills/items. This is calculated third.
 *
 *   <Magical Armor Penetration: x%>
 *   Causes this actor to cause the target to lose x% armor when using a
 *   magical skills/items. This is calculated third.
 *
 *   <Certain Armor Penetration: x%>
 *   Causes this actor to cause the target to lose x% armor when using a
 *   physical skills/items. This is calculated third.
 *
 *   <Physical Armor Penetration: x>
 *   Causes this actor to cause the target to lose x armor but not drop below
 *   0 armor when using a physical skills/items. This is calculated last.
 *
 *   <Magical Armor Penetration: x>
 *   Causes this actor to cause the target to lose x armor but not drop below
 *   0 armor when using a magical skills/items. This is calculated last.
 *
 *   <Certain Armor Penetration: x>
 *   Causes this actor to cause the target to lose x armor but not drop below
 *   0 armor when using a certain skills/items. This is calculated last.
 *
 * ============================================================================
 * Lunatic Mode - Custom Armor Scaling
 * ============================================================================
 *
 * For those with some JavaScript experience, you can make use of Lunatic Mode
 * to calculate the way you want armor scaling done for particular skills and
 * items right within the notebox!
 *
 *   <Positive Armor Rate>
 *    value *= 100;
 *    value /= 100 + armor;
 *   </Positive Armor Rate>
 *   This enables you to set a custom positive armor calculation rate for the
 *   skill/item instead of using the default positive armor rate.
 *
 *   <Negative Armor Rate>
 *    value *= 2 - (100 / (100 - armor));
 *    value *= 1.5;
 *   </Negative Armor Rate>
 *   This enables you to set a custom negative armor calculation rate for the
 *   skill/item instead of using the default positive armor rate.
 *
 *   <Base Armor>
 *    armor = target.def;
 *    armor -= user.atk / 4;
 *   </Base Armor>
 *   This enables you to set a custom way for the skill/item to calculate the
 *   base armor value used for armor scaling.
 *
 * ============================================================================
 * Yanfly Engine Plugins - Battle Engine Extension - Action Sequence Commands
 * ============================================================================
 *
 * If you have YEP_BattleEngineCore.js installed with this plugin located
 * underneath it in the Plugin Manager, you can make use of these extra
 * armor scaling related action sequences.
 *
 *=============================================================================
 * ARMOR PENETRATION: X
 * ARMOR PENETRATION: X%
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes the skill to have a global armor pentration property of either x or
 * x% rate. This property is reset at the end of the action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: armor penetration: 20
 *                armor penetration: 30%
 *=============================================================================
 *
 *=============================================================================
 * ARMOR REDUCTION: X
 * ARMOR REDUCTION: X%
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes the skill to have a global armor reduction property of either x or
 * x% rate. This property is reset at the end of the action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: armor reduction: 20
 *                armor reduction: 30%
 *=============================================================================
 *
 *=============================================================================
 * RESET ARMOR PENETRATION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Resets global set armor penetration properties.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: reset armor penetration
 *=============================================================================
 *
 *=============================================================================
 * RESET ARMOR REDUCTION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Resets global set armor reduction properties.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: reset armor reduction
 *=============================================================================
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.04:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.03:
 * - Lunatic Mode fail safes added.
 *
 * Version 1.02:
 * - Updated for RPG Maker MV version 1.1.0.
 *
 * Version 1.01:
 * - Fixed the notetag <Armor Reduction: x%> from not working with the intended
 * effect.
 * - Negative armor damage calculations are reworked to function as intended.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

if (Imported.YEP_DamageCore) {

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

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

Yanfly.Param.ARSPPhysRate = String(Yanfly.Parameters['Positive Physical Rate']);
Yanfly.Param.ARSNPhysRate = String(Yanfly.Parameters['Negative Physical Rate']);
Yanfly.Param.ARSBPhysArmor = String(Yanfly.Parameters['Physical Base Armor']);
Yanfly.Param.ARSPMagRate = String(Yanfly.Parameters['Positive Magical Rate']);
Yanfly.Param.ARSNMagRate = String(Yanfly.Parameters['Negative Magical Rate']);
Yanfly.Param.ARSBMagArmor = String(Yanfly.Parameters['Magical Base Armor']);
Yanfly.Param.ARSPCerRate = String(Yanfly.Parameters['Positive Certain Rate']);
Yanfly.Param.ARSNCerRate = String(Yanfly.Parameters['Negative Certain Rate']);
Yanfly.Param.ARSBCerArmor = String(Yanfly.Parameters['Certain Base Armor']);

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

Yanfly.ARS.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
  if (!Yanfly.ARS.DataManager_isDatabaseLoaded.call(this)) return false;
  if (!Yanfly._loaded_YEP_X_ArmorScaling) {
    this.processARSNotetags1($dataSkills);
    this.processARSNotetags1($dataItems);
    this.processARSNotetags2($dataActors);
    this.processARSNotetags2($dataClasses);
    this.processARSNotetags2($dataEnemies);
    this.processARSNotetags2($dataWeapons);
    this.processARSNotetags2($dataArmors);
    this.processARSNotetags2($dataStates);
    Yanfly._loaded_YEP_X_ArmorScaling = true;
  }
  return true;
};

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

    var armorScaleMode = 0;
    if (obj.hitType === 1) {
      obj.positiveArmorScale = Yanfly.Param.ARSPPhysRate;
      obj.negativeArmorScale = Yanfly.Param.ARSNPhysRate;
      obj.baseArmorScale = Yanfly.Param.ARSBPhysArmor;
    } else if (obj.hitType === 2) {
      obj.positiveArmorScale = Yanfly.Param.ARSPMagRate;
      obj.negativeArmorScale = Yanfly.Param.ARSNMagRate;
      obj.baseArmorScale = Yanfly.Param.ARSBMagArmor;
    } else {
      obj.positiveArmorScale = Yanfly.Param.ARSPCerRate;
      obj.negativeArmorScale = Yanfly.Param.ARSNCerRate;
      obj.baseArmorScale = Yanfly.Param.ARSBCerArmor;
    }
    obj.armorReductionFlat = 0;
    obj.armorReductionRate = 0.0;
    obj.armorPenetrationFlat = 0;
    obj.armorPenetrationRate = 0.0;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<(?:POSITIVE ARMOR RATE)>/i)) {
        armorScaleMode = 1;
        obj.positiveArmorScale = '';
      } else if (line.match(/<\/(?:POSITIVE ARMOR RATE)>/i)) {
        armorScaleMode = 0;
      } else if (line.match(/<(?:NEGATIVE ARMOR RATE)>/i)) {
        armorScaleMode = -1;
        obj.negativeArmorScale = '';
      } else if (line.match(/<\/(?:NEGATIVE ARMOR RATE)>/i)) {
        armorScaleMode = 0;
      } else if (line.match(/<(?:BASE ARMOR)>/i)) {
        armorScaleMode = 2;
        obj.baseArmorScale = '';
      } else if (line.match(/<\/(?:BASE ARMOR)>/i)) {
        armorScaleMode = 0;
      } else if (line.match(/<(?:ARMOR REDUCTION):[ ](\d+)>/i)) {
        obj.armorReductionFlat = parseInt(RegExp.$1);
      } else if (line.match(/<(?:ARMOR REDUCTION):[ ](\d+)([%％])>/i)) {
        obj.armorReductionRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(/<(?:ARMOR PENETRATION):[ ](\d+)>/i)) {
        obj.armorPenetrationFlat = parseInt(RegExp.$1);
      } else if (line.match(/<(?:ARMOR PENETRATION):[ ](\d+)([%％])>/i)) {
        obj.armorPenetrationRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(/<(?:BYPASS ARMOR SCALING)>/i)) {
        obj.positiveArmorScale = '';
        obj.negativeArmorScale = '';
      } else if (armorScaleMode === 1) {
        obj.positiveArmorScale = obj.positiveArmorScale + line + '\n';
      } else if (armorScaleMode === -1) {
        obj.negativeArmorScale = obj.negativeArmorScale + line + '\n';
      } else if (armorScaleMode === 2) {
        obj.baseArmorScale = obj.baseArmorScale + line + '\n';
      }
    }
  }
};

DataManager.processARSNotetags2 = function(group) {
  var note01 = /<(?:PHYSICAL ARMOR REDUCTION):[ ](\d+)>/i;
  var note02 = /<(?:PHYSICAL ARMOR REDUCTION):[ ](\d+)([%％])>/i;
  var note03 = /<(?:PHYSICAL ARMOR PENETRATION):[ ](\d+)([%％])>/i;
  var note04 = /<(?:PHYSICAL ARMOR PENETRATION):[ ](\d+)>/i;
  var note05 = /<(?:MAGICAL ARMOR REDUCTION):[ ](\d+)>/i;
  var note06 = /<(?:MAGICAL ARMOR REDUCTION):[ ](\d+)([%％])>/i;
  var note07 = /<(?:MAGICAL ARMOR PENETRATION):[ ](\d+)([%％])>/i;
  var note08 = /<(?:MAGICAL ARMOR PENETRATION):[ ](\d+)>/i;
  var note09 = /<(?:CERTAIN ARMOR REDUCTION):[ ](\d+)>/i;
  var note10 = /<(?:CERTAIN ARMOR REDUCTION):[ ](\d+)([%％])>/i;
  var note11 = /<(?:CERTAIN ARMOR PENETRATION):[ ](\d+)([%％])>/i;
  var note12 = /<(?:CERTAIN ARMOR PENETRATION):[ ](\d+)>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.physArmorRedFlat = 0;
    obj.physArmorRedRate = 0.0;
    obj.physArmorPenRate = 0.0;
    obj.physArmorPenFlat = 0;
    obj.magArmorRedFlat = 0;
    obj.magArmorRedRate = 0.0;
    obj.magArmorPenRate = 0.0;
    obj.magArmorPenFlat = 0;
    obj.cerArmorRedFlat = 0;
    obj.cerArmorRedRate = 0.0;
    obj.cerArmorPenRate = 0.0;
    obj.cerArmorPenFlat = 0;

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(note01)) {
        obj.physArmorRedFlat = parseInt(RegExp.$1);
      } else if (line.match(note02)) {
        obj.physArmorRedRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note03)) {
        obj.physArmorPenRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note04)) {
        obj.physArmorPenFlat = parseInt(RegExp.$1);
      } else if (line.match(note05)) {
        obj.magArmorRedFlat = parseInt(RegExp.$1);
      } else if (line.match(note06)) {
        obj.magArmorRedRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note07)) {
        obj.magArmorPenRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note08)) {
        obj.magArmorPenFlat = parseInt(RegExp.$1);
      } else if (line.match(note09)) {
        obj.cerArmorRedFlat = parseInt(RegExp.$1);
      } else if (line.match(note10)) {
        obj.cerArmorRedRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note11)) {
        obj.cerArmorPenRate = parseFloat(RegExp.$1 * 0.01);
      } else if (line.match(note12)) {
        obj.cerArmorPenFlat = parseInt(RegExp.$1);
      }
    }
  }
};

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

if (Imported.YEP_BattleEngineCore) {
Yanfly.ARS.BattleManager_processActionSequence =
  BattleManager.processActionSequence;
  BattleManager.processActionSequence = function(actionName, actionArgs) {
    // ARMOR PENETRATION
    if (actionName === 'ARMOR PENETRATION') {
      return this.actionArmorPenetration(actionArgs);
    }
    // ARMOR REDUCTION
    if (actionName === 'ARMOR REDUCTION') {
      return this.actionArmorReduction(actionArgs);
    }
    // RESET ARMOR PENETRATION
    if (actionName === 'RESET ARMOR PENETRATION') {
      return this.actionResetArmorPenetration();
    }
    // RESET ARMOR REDUCTION
    if (actionName === 'RESET ARMOR REDUCTION') {
      return this.actionResetArmorReduction();
    }
    return Yanfly.ARS.BattleManager_processActionSequence.call(this,
      actionName, actionArgs);
  };
};

BattleManager.actionArmorPenetration = function(actionArgs) {
    if (actionArgs[0].match(/(\d+)([%％])/i)) {
      var value = parseFloat(RegExp.$1 * 0.01);
      $gameSystem._armorPenRate = value;
    } else if (actionArgs[0].match(/(\d+)/i)) {
      var value = parseInt(RegExp.$1);
      $gameSystem._armorPenFlat = value;
    } else {
      return true;
    }
    return true;
};

BattleManager.actionArmorReduction = function(actionArgs) {
    if (actionArgs[0].match(/(\d+)([%％])/i)) {
      var value = parseFloat(RegExp.$1 * 0.01);
      $gameSystem._armorRedRate = value;
    } else if (actionArgs[0].match(/(\d+)/i)) {
      var value = parseInt(RegExp.$1);
      $gameSystem._armorRedFlat = value;
    } else {
      return true;
    }
    return true;
};

BattleManager.actionResetArmorPenetration = function() {
    $gameSystem._armorPenRate = 0.0;
    $gameSystem._armorPenFlat = 0;
    return true;
};

BattleManager.actionResetArmorReduction = function() {
    $gameSystem._armorRedRate = 0.0;
    $gameSystem._armorRedFlat = 0;
    return true;
};

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

Yanfly.ARS.Game_System_rDS = Game_System.prototype.resetDamageSettings;
Game_System.prototype.resetDamageSettings = function() {
    Yanfly.ARS.Game_System_rDS.call(this);
    this._armorRedFlat = 0;
    this._armorRedRate = 0.0;
    this._armorPenRate = 0.0;
    this._armorPenFlat = 0;
};

Game_System.prototype.armorReductionFlat = function() {
    if (this._armorRedFlat === undefined) this.resetDamageSettings();
    return this._armorRedFlat;
};

Game_System.prototype.armorReductionRate = function() {
    if (this._armorRedRate === undefined) this.resetDamageSettings();
    return this._armorRedRate;
};

Game_System.prototype.armorPenetrationRate = function() {
    if (this._armorPenRate === undefined) this.resetDamageSettings();
    return this._armorPenRate;
};

Game_System.prototype.armorPenetrationFlat = function() {
    if (this._armorPenFlat === undefined) this.resetDamageSettings();
    return this._armorPenFlat;
};

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

Game_Battler.prototype.certainArmorReductionFlat = function() {
    var value = 0;
    if ($gameParty.inBattle()) value += $gameSystem.armorReductionFlat();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value += state.cerArmorRedFlat;
    }
    return value;
};

Game_Battler.prototype.physicalArmorReductionFlat = function() {
    var value = 0;
    if ($gameParty.inBattle()) value += $gameSystem.armorReductionFlat();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value += state.physArmorRedFlat;
    }
    return value;
};

Game_Battler.prototype.magicalArmorReductionFlat = function() {
    var value = 0;
    if ($gameParty.inBattle()) value += $gameSystem.armorReductionFlat();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value += state.magArmorRedFlat;
    }
    return value;
};

Game_Battler.prototype.certainArmorReductionRate = function() {
    var value = 1.0;
    if ($gameParty.inBattle()) value *= 1 - $gameSystem.armorReductionRate();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value *= 1.0 - state.cerArmorRedRate;
    }
    return value;
};

Game_Battler.prototype.physicalArmorReductionRate = function() {
    var value = 1.0;
    if ($gameParty.inBattle()) value *= 1 - $gameSystem.armorReductionRate();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value *= 1.0 - state.physArmorRedRate;
    }
    return value;
};

Game_Battler.prototype.magicalArmorReductionRate = function() {
    var value = 1.0;
    if ($gameParty.inBattle()) value *= 1 - $gameSystem.armorReductionRate();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value *= 1.0 - state.magArmorRedRate;
    }
    return value;
};

Game_Battler.prototype.certainArmorPenetrationRate = function() {
    var value = 1.0;
    if ($gameParty.inBattle()) value *= 1 - $gameSystem.armorPenetrationRate();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value *= 1.0 - state.cerArmorPenRate;
    }
    return value;
};

Game_Battler.prototype.physicalArmorPenetrationRate = function() {
    var value = 1.0;
    if ($gameParty.inBattle()) value *= 1 - $gameSystem.armorPenetrationRate();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value *= 1.0 - state.physArmorPenRate;
    }
    return value;
};

Game_Battler.prototype.magicalArmorPenetrationRate = function() {
    var value = 1.0;
    if ($gameParty.inBattle()) value *= 1 - $gameSystem.armorPenetrationRate();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value *= 1.0 - state.magArmorPenRate;
    }
    return value;
};

Game_Battler.prototype.certainArmorPenetrationFlat = function() {
    var value = 0;
    if ($gameParty.inBattle()) value += $gameSystem.armorPenetrationFlat();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value += state.cerArmorPenFlat;
    }
    return value;
};

Game_Battler.prototype.physicalArmorPenetrationFlat = function() {
    var value = 0;
    if ($gameParty.inBattle()) value += $gameSystem.armorPenetrationFlat();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value += state.physArmorPenFlat;
    }
    return value;
};

Game_Battler.prototype.magicalArmorPenetrationFlat = function() {
    var value = 0;
    if ($gameParty.inBattle()) value += $gameSystem.armorPenetrationFlat();
    for (var i = 0; i < this.states().length; ++i) {
      var state = this.states()[i];
      if (state) value += state.magArmorPenFlat;
    }
    return value;
};

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

Game_Actor.prototype.certainArmorReductionFlat = function() {
    var value = Game_Battler.prototype.certainArmorReductionFlat.call(this);
    value += this.actor().cerArmorRedFlat;
    value += this.currentClass().cerArmorRedFlat;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value += equip.cerArmorRedFlat;
    }
    return value;
};

Game_Actor.prototype.physicalArmorReductionFlat = function() {
    var value = Game_Battler.prototype.physicalArmorReductionFlat.call(this);
    value += this.actor().physArmorRedFlat;
    value += this.currentClass().physArmorRedFlat;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value += equip.physArmorRedFlat;
    }
    return value;
};

Game_Actor.prototype.magicalArmorReductionFlat = function() {
    var value = Game_Battler.prototype.magicalArmorReductionFlat.call(this);
    value += this.actor().magArmorRedFlat;
    value += this.currentClass().magArmorRedFlat;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value += equip.magArmorRedFlat;
    }
    return value;
};

Game_Actor.prototype.certainArmorReductionRate = function() {
    var value = Game_Battler.prototype.certainArmorReductionRate.call(this);
    value *= 1.0 - this.actor().cerArmorRedRate;
    value *= 1.0 - this.currentClass().cerArmorRedRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value *= 1.0 - equip.cerArmorRedRate;
    }
    return value;
};

Game_Actor.prototype.physicalArmorReductionRate = function() {
    var value = Game_Battler.prototype.physicalArmorReductionRate.call(this);
    value *= 1.0 - this.actor().physArmorRedRate;
    value *= 1.0 - this.currentClass().physArmorRedRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value *= 1.0 - equip.physArmorRedRate;
    }
    return value;
};

Game_Actor.prototype.magicalArmorReductionRate = function() {
    var value = Game_Battler.prototype.magicalArmorReductionRate.call(this);
    value *= 1.0 - this.actor().magArmorRedRate;
    value *= 1.0 - this.currentClass().magArmorRedRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value *= 1.0 - equip.magArmorRedRate;
    }
    return value;
};

Game_Actor.prototype.certainArmorPenetrationRate = function() {
    var value = Game_Battler.prototype.certainArmorPenetrationRate.call(this);
    value *= 1.0 - this.actor().cerArmorPenRate;
    value *= 1.0 - this.currentClass().cerArmorPenRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value *= 1.0 - equip.cerArmorPenRate;
    }
    return value;
};

Game_Actor.prototype.physicalArmorPenetrationRate = function() {
    var value = Game_Battler.prototype.physicalArmorPenetrationRate.call(this);
    value *= 1.0 - this.actor().physArmorPenRate;
    value *= 1.0 - this.currentClass().physArmorPenRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value *= 1.0 - equip.physArmorPenRate;
    }
    return value;
};

Game_Actor.prototype.magicalArmorPenetrationRate = function() {
    var value = Game_Battler.prototype.magicalArmorPenetrationRate.call(this);
    value *= 1.0 - this.actor().magArmorPenRate;
    value *= 1.0 - this.currentClass().magArmorPenRate;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value *= 1.0 - equip.magArmorPenRate;
    }
    return value;
};

Game_Actor.prototype.certainArmorPenetrationFlat = function() {
    var value = Game_Battler.prototype.certainArmorPenetrationFlat.call(this);
    value += this.actor().cerArmorPenFlat;
    value += this.currentClass().cerArmorPenFlat;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value += equip.cerArmorPenFlat;
    }
    return value;
};

Game_Actor.prototype.physicalArmorPenetrationFlat = function() {
    var value = Game_Battler.prototype.physicalArmorPenetrationFlat.call(this);
    value += this.actor().physArmorPenFlat;
    value += this.currentClass().physArmorPenFlat;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value += equip.physArmorPenFlat;
    }
    return value;
};

Game_Actor.prototype.magicalArmorPenetrationFlat = function() {
    var value = Game_Battler.prototype.magicalArmorPenetrationFlat.call(this);
    value += this.actor().magArmorPenFlat;
    value += this.currentClass().magArmorPenFlat;
    for (var i = 0; i < this.equips().length; ++i) {
      var equip = this.equips()[i];
      if (equip) value += equip.magArmorPenFlat;
    }
    return value;
};

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

Game_Enemy.prototype.certainArmorReductionFlat = function() {
    var value = Game_Battler.prototype.certainArmorReductionFlat.call(this);
    value += this.enemy().cerArmorRedFlat;
    return value;
};

Game_Enemy.prototype.physicalArmorReductionFlat = function() {
    var value = Game_Battler.prototype.physicalArmorReductionFlat.call(this);
    value += this.enemy().physArmorRedFlat;
    return value;
};

Game_Enemy.prototype.magicalArmorReductionFlat = function() {
    var value = Game_Battler.prototype.magicalArmorReductionFlat.call(this);
    value += this.enemy().magArmorRedFlat;
    return value;
};

Game_Enemy.prototype.certainArmorReductionRate = function() {
    var value = Game_Battler.prototype.certainArmorReductionRate.call(this);
    value *= 1.0 - this.enemy().cerArmorRedRate;
    return value;
};

Game_Enemy.prototype.physicalArmorReductionRate = function() {
    var value = Game_Battler.prototype.physicalArmorReductionRate.call(this);
    value *= 1.0 - this.enemy().physArmorRedRate;
    return value;
};

Game_Enemy.prototype.magicalArmorReductionRate = function() {
    var value = Game_Battler.prototype.magicalArmorReductionRate.call(this);
    value *= 1.0 - this.enemy().magArmorRedRate;
    return value;
};

Game_Enemy.prototype.certainArmorPenetrationRate = function() {
    var value = Game_Battler.prototype.certainArmorPenetrationRate.call(this);
    value *= 1.0 - this.enemy().cerArmorPenRate;
    return value;
};

Game_Enemy.prototype.physicalArmorPenetrationRate = function() {
    var value = Game_Battler.prototype.physicalArmorPenetrationRate.call(this);
    value *= 1.0 - this.enemy().physArmorPenRate;
    return value;
};

Game_Enemy.prototype.magicalArmorPenetrationRate = function() {
    var value = Game_Battler.prototype.magicalArmorPenetrationRate.call(this);
    value *= 1.0 - this.enemy().magArmorPenRate;
    return value;
};

Game_Enemy.prototype.certainArmorPenetrationFlat = function() {
    var value = Game_Battler.prototype.certainArmorPenetrationFlat.call(this);
    value += this.enemy().cerArmorPenFlat;
    return value;
};

Game_Enemy.prototype.physicalArmorPenetrationFlat = function() {
    var value = Game_Battler.prototype.physicalArmorPenetrationFlat.call(this);
    value += this.enemy().physArmorPenFlat;
    return value;
};

Game_Enemy.prototype.magicalArmorPenetrationFlat = function() {
    var value = Game_Battler.prototype.magicalArmorPenetrationFlat.call(this);
    value += this.enemy().magArmorPenFlat;
    return value;
};

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

Yanfly.ARS.Game_Action_applyDamageRate =
    Game_Action.prototype.applyDamageRate;
Game_Action.prototype.applyDamageRate = function(value, baseDamage, target) {
    value = this.scaleCertainArmor(value, baseDamage, target);
    return Yanfly.ARS.Game_Action_applyDamageRate.call(this, value,
      baseDamage, target);
};

Yanfly.ARS.Game_Action_applyPhysicalRate =
    Game_Action.prototype.applyPhysicalRate;
Game_Action.prototype.applyPhysicalRate = function(value, baseDamage, target) {
    value = this.scalePhysicalArmor(value, baseDamage, target);
    return Yanfly.ARS.Game_Action_applyPhysicalRate.call(this, value,
      baseDamage, target);
};

Yanfly.ARS.Game_Action_applyMagicalRate =
    Game_Action.prototype.applyMagicalRate;
Game_Action.prototype.applyMagicalRate = function(value, baseDamage, target) {
  value = this.scaleMagicalArmor(value, baseDamage, target);
  return Yanfly.ARS.Game_Action_applyMagicalRate.call(this, value,
    baseDamage, target);
};

Game_Action.prototype.scaleCertainArmor = function(value, baseDamage, target) {
    if (baseDamage <= 0) return value;
    if (!this.isCertainHit()) return value;
    var armor = this.getBaseArmor(value, baseDamage, target);
    armor = this.applyCertainArmorScale(armor, target);
    var item = this.item();
    var a = this.subject();
    var b = target;
    var user = this.subject();
    var subject = this.subject();
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    if (armor >= 0) {
      var code = item.positiveArmorScale;
    } else {
      var code = item.negativeArmorScale;
    }
    try {
      eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code,
        'ARMOR SCALING FORMULA ERROR');
    }
    return value;
};

Game_Action.prototype.scalePhysicalArmor = function(value, baseDamage, target) {
    if (baseDamage <= 0) return value;
    var armor = this.getBaseArmor(value, baseDamage, target);
    armor = this.applyPhysicalArmorScale(armor, target);
    var item = this.item();
    var a = this.subject();
    var b = target;
    var user = this.subject();
    var subject = this.subject();
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    if (armor >= 0) {
      var code = item.positiveArmorScale;
    } else {
      var code = item.negativeArmorScale;
    }
    try {
      eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code,
        'ARMOR SCALING FORMULA ERROR');
    }
    return value;
};

Game_Action.prototype.scaleMagicalArmor = function(value, baseDamage, target) {
    if (baseDamage <= 0) return value;
    var armor = this.getBaseArmor(value, baseDamage, target);
    armor = this.applyMagicalArmorScale(armor, target);
    var item = this.item();
    var a = this.subject();
    var b = target;
    var user = this.subject();
    var subject = this.subject();
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    if (armor >= 0) {
      var code = item.positiveArmorScale;
    } else {
      var code = item.negativeArmorScale;
    }
    try {
      eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code,
        'ARMOR SCALING FORMULA ERROR');
    }
    return value;
};

Game_Action.prototype.getBaseArmor = function(value, baseDamage, target) {
    var armor = 0;
    var item = this.item();
    var a = this.subject();
    var b = target;
    var user = this.subject();
    var subject = this.subject();
    var s = $gameSwitches._data;
    var v = $gameVariables._data;
    var code = item.baseArmorScale;
    try {
      armor = eval(code);
    } catch (e) {
      Yanfly.Util.displayError(e, code, 'BASE ARMOR FORMULA ERROR');
    }
    return armor;
};

Game_Action.prototype.applyCertainArmorScale = function(armor, target) {
    armor -= this.item().armorReductionFlat;
    armor -= target.certainArmorReductionFlat();
    if (armor > 0) {
      armor *= 1 - this.item().armorReductionRate;
      armor *= target.certainArmorReductionRate();
      armor *= 1 - this.item().armorPenetrationRate;
      armor *= this.subject().certainArmorPenetrationRate();
      armor -= this.item().armorPenetrationFlat;
      armor -= Math.min(armor, this.subject().certainArmorPenetrationFlat());
    }
    return armor;
};

Game_Action.prototype.applyPhysicalArmorScale = function(armor, target) {
    armor -= this.item().armorReductionFlat;
    armor -= target.physicalArmorReductionFlat();
    if (armor > 0) {
      armor *= 1 - this.item().armorReductionRate;
      armor *= target.physicalArmorReductionRate();
      armor *= 1 - this.item().armorPenetrationRate;
      armor *= this.subject().physicalArmorPenetrationRate();
      armor -= this.item().armorPenetrationFlat;
      armor -= Math.min(armor, this.subject().physicalArmorPenetrationFlat());
    }
    return armor;
};

Game_Action.prototype.applyMagicalArmorScale = function(armor, target) {
    armor -= this.item().armorReductionFlat;
    armor -= target.magicalArmorReductionFlat();
    if (armor > 0) {
      armor *= 1 - this.item().armorReductionRate;
      armor *= target.magicalArmorReductionRate();
      armor *= 1 - this.item().armorPenetrationRate;
      armor *= this.subject().magicalArmorPenetrationRate();
      armor -= this.item().armorPenetrationFlat;
      armor -= Math.min(armor, this.subject().magicalArmorPenetrationFlat());
    }
    return armor;
};

//=============================================================================
// 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 - Save Core Extension - Autosave
// YEP_X_Autosave.js
//=============================================================================

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

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

//=============================================================================
 /*:
 * @plugindesc v1.00 (Req YEP_SaveCore.js) Adds Autosave functionality to your
 * RPG Maker game.
 * @author Yanfly Engine Plugins
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin requires YEP_SaveCore. Make sure this plugin is located under
 * YEP_SaveCore in the plugin list.
 *
 * Autosave is a common feature found in standard RPG's nowadays. Games would
 * save at certain triggers or upon changing maps so that the player won't lose
 * any progress in case they forget to manually save. This plugin adds in an
 * Autosave function to your game(s) and lets you control when to Autosave or
 * set it to do it automatically under certain conditions.
 *
 * ============================================================================
 * Instructions
 * ============================================================================
 *
 * There are three ways to go about Autosave with this plugin. Please read them
 * carefully and decide which one(s) is best suited for your game.
 *
 * ---
 *
 * Manual:
 * - By default, Autosave does not happen automatically with this plugin. You,
 * as the game dev, need to insert the Plugin Command: Autosave at the various
 * points you want the Autosave to occur. This one gives you the most control
 * over your game.
 *
 * ---
 *
 * Autosave on Map Load:
 * - This is a Plugin Parameter. When it is set to true, the game will Autosave
 * each time the map scene is loaded. This means entering a new map, coming out
 * of a menu, or finishing a battle. All three of those conditions causes the
 * Autosave function to activate.
 *
 * ---
 *
 * Autosave on Main Menu:
 * - This is a Plugin Parameter. When it is set to true, the game will Autosave
 * each time the player enters the Main Menu from the map scene. Autosave will
 * NOT occur any other way regarding the Main Menu, meaning that coming out of
 * the Item scene to the Main Menu will not activate Autosave.
 *
 * ---
 *
 * Autosaving will not occur if the player disables Autosave. If you don't want
 * to give the player the ability to disable Autosave, you can set the Plugin
 * Parameter "Show Option" to false.
 *
 * You can use all three methods of Autosaving together. You can have it done
 * manually, Autosave on loading a map, and Autosave on calling the Main Menu
 * to get the most coverage.
 *
 * *NOTE: Although you can use all three methods together, be mindful of your
 * players. Sometimes, saving a game could induce a bit of lag depending on how
 * big the save files are. Autosaving is no different. This is something that
 * cannot be fixed by plugins.
 *
 * *NOTE: Autosaving will not occur until the player saved manually at least
 * once in-game. After that, Autosave will take the slot that was used to save
 * and continue saving to it or whichever save slot the player moved to later.
 *
 * ============================================================================
 * Plugin Commands
 * ============================================================================
 *
 * Autosave is manually done by the game developer using plugin commands. There
 * are also other plugin commands that can control autosaving, too.
 *
 *   Plugin Commands:
 *
 *      Autosave
 *      - This will make the game automatically save in the last saved file
 *      slot used by the player. If the player has started a new game and did
 *      not save into a slot yet, nothing will happen. If autosave is disabled
 *      by the player through the Options menu or disabled by the system with
 *      a plugin command, nothing will happen either.
 *
 *      EnableAutosave
 *      DisableAutosave
 *      - This will forcibly enable or disable autosaving done by the game.
 *      This will not bypass the player's option to disable Autosave if trying
 *      to enable it. The player's decision to disable Autosaving will take
 *      priority over the game dev's. If you wish to take this option away from
 *      the player, please change it in the plugin parameters.
 *
 * ============================================================================
 * Options Core Settings - Adding the New Option
 * ============================================================================
 *
 * 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[231]Autosave
 *
 * Help Description:
 * Enables \c[4]Autosaving\c[0] for your game if ON.
 * You can still manually save your game.
 *
 * Symbol:
 * autosave
 *
 * Show/Hide:
 * show = Imported.AutosaveShowOpt;
 *
 * 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.00:
 * - Finished Plugin!
 *
 * ============================================================================
 * End of Helpfile
 * ============================================================================
 *
 * @param ---Automatic---
 * @default
 *
 * @param OnMapLoad
 * @text Autosave on Map Load
 * @parent ---Automatic---
 * @type boolean
 * @on YES
 * @off NO
 * @desc Autosave whenever the map is loaded.
 * YES - true     NO - false
 * @default false
 *
 * @param OnMainMenu
 * @text Autosave on Main Menu
 * @parent ---Automatic---
 * @type boolean
 * @on YES
 * @off NO
 * @desc Autosave whenever main menu is called.
 * YES - true     NO - false
 * @default false
 *
 * @param ---Option Menu---
 * @default
 *
 * @param Show Option
 * @parent ---Option Menu---
 * @type boolean
 * @on YES
 * @off NO
 * @desc Give player the option to enable or disable Autosave?
 * YES - true     NO - false
 * @default true
 *
 * @param Option Name
 * @parent ---Option Menu---
 * @desc The option command text used in-game.
 * @default Autosave
 *
 * @param Default
 * @text Default Setting
 * @parent ---Option Menu---
 * @desc Do you want Autosaving to be enabled by default?
 * YES - true     NO - false
 * @default true
 *
 * @param ---Visual---
 * @default
 *
 * @param ShowAutosave
 * @text Show Autosave Message
 * @parent ---Visual---
 * @type boolean
 * @on YES
 * @off NO
 * @desc Show a message when Autosave happens?
 * YES - true     NO - false
 * @default true
 *
 * @param AutosaveMsgSave
 * @text Autosave Message On Save
 * @parent ShowAutosave
 * @desc Text used for the auto save message.
 * Can use text codes.
 * @default \i[83]Autosave Complete!
 *
 * @param AutosaveMsgLoad
 * @text Autosave Message On Load
 * @parent ShowAutosave
 * @desc Text used for the auto save message.
 * Can use text codes.
 * @default \i[83]Autosave Loaded!
 *
 * @param MsgGradient1
 * @text Message Gradient 1
 * @parent ShowAutosave
 * @desc Hex color used for the softer gradient color.
 * rgba(0, 0, 0, 0) Reference: Red, Green, Blue, Alpha
 * @default rgba(0, 0, 0, 0)
 *
 * @param MsgGradient2
 * @text Message Gradient 2
 * @parent ShowAutosave
 * @desc Hex color used for the softer gradient color.
 * rgba(0, 0, 0, 0) Reference: Red, Green, Blue, Alpha
 * @default rgba(0, 0, 0, 0.6)
 *
 * @param MsgGradientCode
 * @text Message Gradient Code
 * @parent ShowAutosave
 * @type note
 * @desc JavaScript code for those who would like to tweak
 * how the gradient is drawn.
 * @default "var textWidth = this.textWidthEx(this.message());\nvar half = this.textPadding() + Math.ceil(textWidth / 2);\nvar height = this.lineHeight();\nvar color1 = Yanfly.Param.AutosaveMsgColor1;\nvar color2 = Yanfly.Param.AutosaveMsgColor2;\nthis.contents.gradientFillRect(0, 0, half, height, color1, color2);\nthis.contents.gradientFillRect(half, 0, this.width - half, height, color2, color1);"
 *
 * @param MsgX
 * @text Message X
 * @parent ShowAutosave
 * @desc X position of the message.
 * You can use code here.
 * @default Graphics.boxWidth - 180
 *
 * @param MsgY
 * @text Message Y
 * @parent ShowAutosave
 * @desc Y position of the message.
 * You can use code here.
 * @default Graphics.boxHeight - this.fittingHeight(1) * 2
 *
 * @param MsgDuration
 * @text Message Duration
 * @parent ShowAutosave
 * @type number
 * @desc Duration of the message in frames.
 * @default 120
 *
 * @param FadeSpeed
 * @text Message Fade Speed
 * @parent ShowAutosave
 * @desc Fade speed of the window.
 * Lower - slower     Higher - faster
 * @default 16
 *
 */
//=============================================================================

if (Imported.YEP_SaveCore) {

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

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

Yanfly.Param.AutosaveOnMapLoad = eval(String(Yanfly.Parameters['OnMapLoad']));
Yanfly.Param.AutosaveOnMainMenu = eval(String(Yanfly.Parameters['OnMainMenu']));

Yanfly.Param.AutosaveShowOpt = eval(String(Yanfly.Parameters['Show Option']));
Yanfly.Param.AutosaveOptionCmd = String(Yanfly.Parameters['Option Name']);
Yanfly.Param.AutosaveDefault = eval(String(Yanfly.Parameters['Default']));

Yanfly.Param.AutosaveShowMsg = eval(String(Yanfly.Parameters['ShowAutosave']));
Yanfly.Param.AutosaveMsgSave = String(Yanfly.Parameters['AutosaveMsgSave']);
Yanfly.Param.AutosaveMsgLoad = String(Yanfly.Parameters['AutosaveMsgLoad']);
Yanfly.Param.AutosaveMsgColor1 = String(Yanfly.Parameters['MsgGradient1']);
Yanfly.Param.AutosaveMsgColor2 = String(Yanfly.Parameters['MsgGradient2']);
Yanfly.Param.AutosaveMsgCode = JSON.parse(Yanfly.Parameters['MsgGradientCode']);
Yanfly.Param.AutosaveMsgX = String(Yanfly.Parameters['MsgX']);
Yanfly.Param.AutosaveMsgY = String(Yanfly.Parameters['MsgY']);
Yanfly.Param.AutosaveMsgDur = Number(Yanfly.Parameters['MsgDuration']) || 120;
Yanfly.Param.AutosaveMsgFade = Number(Yanfly.Parameters['FadeSpeed']) || 16;

//=============================================================================
// ConfigManager
//=============================================================================

ConfigManager.autosave = Yanfly.Param.AutosaveDefault;

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

Yanfly.Autosave.ConfigManager_applyData = ConfigManager.applyData;
ConfigManager.applyData = function(config) {
  Yanfly.Autosave.ConfigManager_applyData.call(this, config);
  this.autosave = config['autosave'] || Yanfly.Param.AutosaveDefault;
};

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

Yanfly.Autosave.DataManager_setupNewGame = DataManager.setupNewGame;
DataManager.setupNewGame = function() {
  Yanfly.Autosave.DataManager_setupNewGame.call(this);
  StorageManager.setCurrentAutosaveSlot(this._lastAccessedId);
  $gameTemp._autosaveNewGame = true;
  $gameTemp._autosaveLoading = false;
};

Yanfly.Autosave.DataManager_saveGame = DataManager.saveGameWithoutRescue;
DataManager.saveGameWithoutRescue = function(savefileId) {
  var value = Yanfly.Autosave.DataManager_saveGame.call(this, savefileId);
  $gameTemp._autosaveNewGame = false;
  $gameTemp._autosaveLoading = false;
  StorageManager.setCurrentAutosaveSlot(savefileId);
  return value;
};

Yanfly.Autosave.DataManager_loadGame = DataManager.loadGameWithoutRescue;
DataManager.loadGameWithoutRescue = function(savefileId) {
  var value = Yanfly.Autosave.DataManager_loadGame.call(this, savefileId);
  $gameTemp._autosaveNewGame = false;
  $gameTemp._autosaveLoading = true;
  StorageManager.setCurrentAutosaveSlot(savefileId);
  return value;
};

//=============================================================================
// StorageManager
//=============================================================================

StorageManager.getCurrentAutosaveSlot = function() {
  return this._currentAutosaveSlot;
};

StorageManager.setCurrentAutosaveSlot = function(savefileId) {
  this._currentAutosaveSlot = savefileId;
};

StorageManager.performAutosave = function() {
  if ($gameMap.mapId() <= 0) return;
  if ($gameTemp._autosaveNewGame) return;
  if (!$gameSystem.canAutosave()) return;
  SceneManager._scene.performAutosave();
};

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

Yanfly.Autosave.Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
  Yanfly.Autosave.Game_System_initialize.call(this);
  this.initAutosave();
};

Game_System.prototype.initAutosave = function() {
  this._allowAutosave = true;
};

/*
Game_System.prototype.canAutosave = function() {
  if(this._allowAutosave === undefined) this.initAutosave();
  if(ConfigManager.cheatDisableAutosave) {
	Prison.cheatMode() && $gameSelfSwitches.value([MAP_ID_KARRYN_OFFICE, 70, "A"])) return false;
  }
  return this._allowAutosave;
};
*/

Game_System.prototype.setAutosave = function(value) {
  if (this._allowAutosave === undefined) this.initAutosave();
  this._allowAutosave = value;
};

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

Yanfly.Autosave.Game_Interpreter_pluginCommand =
  Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
  Yanfly.Autosave.Game_Interpreter_pluginCommand.call(this, command, args);
  if (command.match(/EnableAutosave/i)) {
    $gameSystem.setAutosave(true);
  } else if (command.match(/DisableAutosave/i)) {
    $gameSystem.setAutosave(false);
  } else if (command.match(/Autosave/i)) {
    StorageManager.performAutosave();
  }
};

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

Yanfly.Autosave.Window_Options_addGeneralOptions =
  Window_Options.prototype.addGeneralOptions;
Window_Options.prototype.addGeneralOptions = function() {
  Yanfly.Autosave.Window_Options_addGeneralOptions.call(this);
  if (!Imported.YEP_OptionsCore && Yanfly.Param.AutosaveShowOpt) {
    this.addCommand(Yanfly.Param.AutosaveOptionCmd, 'autosave');
  }
};

//=============================================================================
// Window_Autosave
//=============================================================================

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

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

Window_Autosave.prototype.initialize = function() {
  var width = this.windowWidth();
  var height = this.windowHeight();
  var x = MAP_AUTOSAVE_X;
  var y = MAP_AUTOSAVE_Y;
  Window_Base.prototype.initialize.call(this, x, y, width, height);
  this.opacity = 0;
  this.contentsOpacity = 0;
  this._showCount = 0;
  this.refresh();
  if ($gameTemp._autosaveLoading) {
    this.reveal();
    $gameTemp._autosaveLoading = false;
  }
};

Window_Autosave.prototype.standardPadding = function() {
  return 0;
};

Window_Autosave.prototype.windowWidth = function() {
  return Graphics.boxWidth;
};

Window_Autosave.prototype.windowHeight = function() {
  return this.fittingHeight(1);
};

Window_Autosave.prototype.update = function() {
  Window_Base.prototype.update.call(this);
  if (this._showCount > 0) {
    this.updateFadeIn();
    this._showCount--;
  } else {
    this.updateFadeOut();
  }
};

Window_Autosave.prototype.updateFadeIn = function() {
  this.contentsOpacity += Yanfly.Param.AutosaveMsgFade;
};

Window_Autosave.prototype.updateFadeOut = function() {
  this.contentsOpacity -= Yanfly.Param.AutosaveMsgFade;
};

Window_Autosave.prototype.reveal = function() {
  if (!Yanfly.Param.AutosaveShowMsg) return;
  if (this._showCount > 0) return;
  this._showCount = Yanfly.Param.AutosaveMsgDur;
  this.refresh();
};

Window_Autosave.prototype.message = function() {
  if ($gameTemp._autosaveLoading) {
    return Yanfly.Param.AutosaveMsgLoad;
  } else {
    //return Yanfly.Param.AutosaveMsgSave;
	var iconCode = "";
	if(MAP_AUTOSAVE_ICON_ID > 0) iconCode = "\\i[" + MAP_AUTOSAVE_ICON_ID + "]";
	return iconCode + TextManager.yanflyAutosaving;
  }
};

Window_Autosave.prototype.refresh = function() {
	if($gameTemp._autosaveLoading) return;
  this.contents.clear();
  this.drawGradient();
	this.drawTextEx(this.message(), this.textPadding(), 0);
};

Window_Autosave.prototype.drawGradient = function() {
  eval(Yanfly.Param.AutosaveMsgCode);
};

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

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

Scene_Base.prototype.performAutosave = function() {
};

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

Yanfly.Autosave.Scene_Map_createAllWindows =
  Scene_Map.prototype.createAllWindows;
Scene_Map.prototype.createAllWindows = function() {
  Yanfly.Autosave.Scene_Map_createAllWindows.call(this);
  this.createAutosaveMessageWindow();
};

Scene_Map.prototype.createAutosaveMessageWindow = function() {
  this._autosaveMsgWindow = new Window_Autosave();
  this.addChild(this._autosaveMsgWindow);
};

Yanfly.Autosave.Scene_Map_onMapLoaded = Scene_Map.prototype.onMapLoaded;
Scene_Map.prototype.onMapLoaded = function() {
  Yanfly.Autosave.Scene_Map_onMapLoaded.call(this);
  if (Yanfly.Param.AutosaveOnMapLoad) StorageManager.performAutosave();
};

Yanfly.Autosave.Scene_Map_callMenu = Scene_Map.prototype.callMenu;
Scene_Map.prototype.callMenu = function() {
  Yanfly.Autosave.Scene_Map_callMenu.call(this);
  if (Yanfly.Param.AutosaveOnMainMenu) StorageManager.performAutosave();
};

Scene_Map.prototype.performAutosave = function() {
  if ($gameMap.mapId() <= 0) return;
  if ($gameTemp._autosaveNewGame) return;
  if (!$gameSystem.canAutosave()) return;
  $gameSystem.onBeforeSave();
  DataManager.saveGameWithoutRescue(StorageManager.getCurrentAutosaveSlot());
  if (this._autosaveMsgWindow) this._autosaveMsgWindow.reveal();
};

//=============================================================================
// Save Core Check
//=============================================================================
} else {

Imported.YEP_X_Autosave = false;
var text = '';
text += 'You are getting this error because you are trying to run ';
text += 'YEP_X_Autosave without the required plugins. Please visit ';
text += 'Yanfly.moe and install the required plugins neede for this plugin ';
text += 'found in this plugin\'s help file before you can use it.';
console.log(text);
require('nw.gui').Window.get().showDevTools();

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