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

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

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

//=============================================================================
/*:
* @plugindesc v1.07 When a player is in the proximity of a certain event,
* the event will start chasing or fleeing from the player.
* @author Yanfly Engine Plugins
*
* @param Sight Lock
* @type number
* @min 0
* @desc This is the number of frames for how long an event chases
* the player if 'this._seePlayer = true' is used.
* @default 300
*
* @param See Player
* @type boolean
* @on YES
* @off NO
* @desc Does the event have to be able to see the player by default?
* NO - false     YES - true
* @default true
*
* @param Alert Timer
* @type number
* @min 0
* @desc This is the number of frames that must occur before the
* alert balloon will show up on the same event.
* @default 120
*
* @param Alert Balloon
* @type number
* @min 0
* @desc This is the default balloon used when the player is seen.
* Refer to balloon ID's.
* @default 1
*
* @param Alert Sound
* @type file
* @dir audio/se/
* @require 1
* @desc This is the default sound played when the player is seen.
* @default Attack1
*
* @param Alert Common Event
* @type common_event
* @desc The default common event played when the player is seen.
* Use 0 if you do not wish to use a Common Event.
* @default 0
*
* @param Return After
* @type boolean
* @on YES
* @off NO
* @desc After chasing/fleeing from a player, the event returns
* to its original spot. NO - false   YES - true
* @default true
*
* @param Return Wait
* @type number
* @min 0
* @desc The frames to wait after finishing a chase/flee.
* @default 180
*
* @help
* ============================================================================
* Introduction
* ============================================================================
*
* This plugin allows you to make events that will chase the player or flee
* from the player when the player enters within range of the event or when the
* event sees the player.
*
* ============================================================================
* How to Use
* ============================================================================
*
* Insert these lines into the script call window within the Movement Route
* event to give an event the chase or flee flag.
*
* Note: This doesn’t work with players.
*
* Script Call lines
*  this._chaseRange = x       Event will chase player if reaching x range.
*  this._fleeRange = x        Event will flee from player if reaching x range.
*  this._chaseSpeed = x       Event's movement speed when chasing.
*  this._fleeSpeed = x        Event's movement speed when fleeing.
*  this._sightLock = x        Event will flee/chase player for x frames.
*  this._seePlayer = true     Requires the event to be able to see player.
*  this._seePlayer = false    Doesn't require event to be able to see player.
*  this._alertBalloon = x     This balloon will play when player is seen.
*  this._alertSound = x       This sound will play when player is seen.
*  this._alertSoundVol = x    The volume used by the alert sound.
*  this._alertSoundPitch = x  The pitch used by the alert sound.
*  this._alertSoundPan = x    The pan used by the alert sound.
*  this._alertCommonEvent = x This event will play when player is seen.
*  this._returnAfter = true   Returns the event back to its original spot.
*  this._returnAfter = false  Event stays where it is when finished chasing.
*  this._returnWait = x       How long event waits after finishing chase/flee.
*
* It is best to play this inside of a custom move route for the event at a
* high frequency rate. Keep in mind these effects only occur after the setting
* is made and ran, which means upon loading a map, if the event with a low
* frequency hasn't loaded up 'this._chaseRange = x' in its movement queue yet,
* the event will not chase the player just yet.
*
* ============================================================================
* Changelog
* ============================================================================
*
* Version 1.07:
* - Added a background mechanic to stagger an event if they're chasing the
* player and get caught behind an object. This will prevent the event from
* continuously chasing the player and dropping the FPS rate.
*
* Version 1.06:
* - Updated for RPG Maker MV version 1.5.0.
*
* Version 1.05:
* - Optimization update.
*
* Version 1.04:
* - Fixed a bug with this._seePlayer causing them to see stealthed players.
*
* Version 1.03:
* - Improved pathfinding for chasing events. They will get stuck less by walls
* and/or events that may be blocking the event.
* - Added random factor for fleeing events. Fleeing events won't simply just
* run away 180 degrees away from the player. They will sometimes move in a
* random direction.
*
* Version 1.02:
* - Added 'Return After' parameter where events will return to their original
* spot after chasing/fleeing from a player.
* - Added 'Return Wait' parameter to determine how long an event will wait in
* place before returning after a finished chase/flee.
* - Added 'this._returnAfter' and 'this._returnWait' to the list of available
* movement route script calls.
*
* Version 1.01:
* - Added 'this._alertSoundPitch' 'this._alertSoundVol' 'this._alertSoundPan'
* to the settings you can alter to adjust the alert sound.
*
* Version 1.00:
* - Finished Plugin!
*/
//=============================================================================

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

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

Yanfly.Param.ECPSightLock = Number(Yanfly.Parameters['Sight Lock']);
Yanfly.Param.ECPSeePlayer = String(Yanfly.Parameters['See Player']);
Yanfly.Param.ECPSeePlayer = eval(Yanfly.Param.ECPSeePlayer);
Yanfly.Param.ECPAlertTimer = Number(Yanfly.Parameters['Alert Timer']);
Yanfly.Param.ECPAlertBalloon = Number(Yanfly.Parameters['Alert Balloon']);
Yanfly.Param.ECPAlertSound = String(Yanfly.Parameters['Alert Sound']);
Yanfly.Param.ECPAlertEvent = Number(Yanfly.Parameters['Alert Common Event']);
Yanfly.Param.ECPReturn = eval(String(Yanfly.Parameters['Return After']));
Yanfly.Param.ECPReturnWait = Number(Yanfly.Parameters['Return Wait']);

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

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

Game_Event.prototype.clearChaseSettings = function () {
  this._alertBalloon = Yanfly.Param.ECPAlertBalloon;
  this._alertCommonEvent = Yanfly.Param.ECPAlertEvent;
  this._alertLock = 0;
  this._alertPlayer = false;
  this._alertSound = Yanfly.Param.ECPAlertSound;
  this._alertSoundVol = 100;
  this._alertSoundPitch = 100;
  this._alertSoundPan = 0;
  this._alertTimer = 0;
  this._chasePlayer = false;
  this._chaseRange = 0;
  this._chaseSpeed = this._moveSpeed;
  this._defaultSpeed = this._moveSpeed;
  this._fleePlayer = false;
  this._fleeRange = 0;
  this._fleeSpeed = this._moveSpeed;
  this._seePlayer = Yanfly.Param.ECPSeePlayer;
  this._sightLock = Yanfly.Param.ECPSightLock;
  this._returnAfter = Yanfly.Param.ECPReturn;
  this._returnWait = Yanfly.Param.ECPReturnWait;
  this._returnPhase = false;
  this._returnFrames = 0;
  this._staggerCount = 0;
  this._startLocationX = this.x;
  this._startLocationY = this.y;
  this._startLocationDir = this._direction;
};

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

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

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

Game_Event.prototype.updateChaseDistance = function () {
  if (this._erased) return;
  if (this._chaseRange <= 0) return;
  var dis = Math.abs(this.deltaXFrom($gamePlayer.x));
  dis += Math.abs(this.deltaYFrom($gamePlayer.y));
  if (this.chaseConditions(dis)) {
    this.startEventChase();
  } else if (this._chasePlayer) {
    this.endEventChase();
  }
};

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

Game_Event.prototype.nonSeePlayer = function () {
  if (Imported.YEP_X_EventChaseStealth) {
    if (this.meetStealthModeConditions()) {
      this.stealthClearChaseSettings();
      this._stopCount = 0;
      return false;
    }
  }
  return !this._seePlayer;
};

Game_Event.prototype.startEventChase = function () {
  this._chasePlayer = true;
  this.setMoveSpeed(this._chaseSpeed);
};

Game_Event.prototype.endEventChase = function () {
  this._chasePlayer = false;
  this.setMoveSpeed(this._defaultSpeed);
  if (this._alertTimer <= 0) this._alertPlayer = false;
  this.startReturnPhase();
};

Game_Event.prototype.updateFleeDistance = function () {
  if (this._erased) return;
  if (this._fleeRange <= 0) return;
  var dis = Math.abs(this.deltaXFrom($gamePlayer.x));
  dis += Math.abs(this.deltaYFrom($gamePlayer.y));
  if (this.fleeConditions(dis)) {
    this.startEventFlee();
  } else if (this._fleePlayer) {
    this.endEventFlee();
  }
};

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

Game_Event.prototype.startEventFlee = function () {
  this._fleePlayer = true;
  this.setMoveSpeed(this._fleeSpeed);
};

Game_Event.prototype.endEventFlee = function () {
  this._fleePlayer = false;
  this.setMoveSpeed(this._defaultSpeed);
  if (this._alertTimer <= 0) this._alertPlayer = false;
  this.startReturnPhase();
};

Game_Event.prototype.updateChaseMovement = function () {
  if (this._staggerCount > 0) {
    return this._staggerCount--;
  }
  if (this._stopCount > 0 && this._chasePlayer) {
    var direction = this.findDirectionTo($gamePlayer.x, $gamePlayer.y);
    if (direction > 0) {
      var x = this._x;
      var y = this._y;
      this.moveStraight(direction);
      if (x === this._x && y === this._y) this._staggerCount = 20;
    }
  } else if (this._stopCount > 0 && this._fleePlayer) {
    this.updateFleeMovement();
  } else if (this._returnPhase) {
    this.updateMoveReturnAfter();
  } else {
    Yanfly.ECP.Game_Event_updateSelfMovement.call(this);
  }
};

Game_Event.prototype.updateFleeMovement = function () {
  switch (Math.randomInt(6)) {
    case 0: case 1: case 2: case 3: case 4:
      this.moveAwayFromPlayer();
      break;
    case 5:
      this.moveRandom();
      break;
  }
};

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

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

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

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

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

Game_Event.prototype.startReturnPhase = function () {
  if (!this._returnAfter) return;
  this._returnPhase = true;
  this._returnFrames = this._returnWait;
};

Game_Event.prototype.updateReturnPhase = function () {
  if (this._returnPhase) this._returnFrames--;
};

Game_Event.prototype.updateMoveReturnAfter = function () {
  if (this._returnFrames > 0) return;
  var sx = this.deltaXFrom(this._startLocationX);
  var sy = this.deltaYFrom(this._startLocationY);
  if (Math.abs(sx) > Math.abs(sy)) {
    if (Math.randomInt(6) <= 4) {
      this.moveStraight(sx > 0 ? 4 : 6);
      if (!this.isMovementSucceeded() && sy !== 0) {
        this.moveStraight(sy > 0 ? 8 : 2);
      }
    } else {
      this.moveRandom();
    }
  } else if (sy !== 0) {
    if (Math.randomInt(6) <= 4) {
      this.moveStraight(sy > 0 ? 8 : 2);
      if (!this.isMovementSucceeded() && sx !== 0) {
        this.moveStraight(sx > 0 ? 4 : 6);
      }
    } else {
      this.moveRandom();
    }
  }
  if (sx === 0 && sy === 0) {
    this._returnPhase = false;
    this._returnFrames = 0;
    this._direction = this._startLocationDir;
  }
};

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

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// Yanfly Engine Plugins - Event Encounter Aid
// YEP_EventEncounterAid.js
//=============================================================================

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

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

//=============================================================================
/*:
* @plugindesc v1.01 This plugin helps make eventable encounters easier
* and determine player position relative to the event.
* @author Yanfly Engine Plugins
*
* @help
* ============================================================================
* Introduction
* ============================================================================
*
* For those who have on-screen encounters, you may have discovered that making
* touch encounters in RPG Maker MV to be rather difficult when it comes to
* performing a sneak attack upon an event or such. This plugin makes the event
* encounter checking process easier by providing six conditional script calls
* for you to utilize when checking event vs player positions.
*
* ============================================================================
* Notetags
* ============================================================================
*
* You can place these notetags into the notebox at the top of an event's page.
* These notetags will enable unique effects for event encounters.
*
* Event Notetag:
*
*   <Encounter Lock>
*   <Encounter Direction Lock>
*   - This will cause the event to not immediately face the player when
*   approached making it possible for the game to check the direction each is
*   facing.
*
*   <Follower Touch>
*   <Follower Trigger>
*   - This will allow the event to trigger if the event touches a follower and
*   not just the main player.
*
* ============================================================================
* Event - Conditional Branch - Script Calls
* ============================================================================
*
* When using the Conditional Branch event, you can use these following in the
* 'Script' check category:
*
* Script Calls
*
*   this.checkEventFacingPlayerFront()
*   - Returns true if the event is facing the player's front.
*
*   this.checkEventFacingPlayerBack()
*   - Returns true if the event is facing the player's back.
*
*   this.checkEventFacingPlayerSide()
*   - Returns true if the event is facing the player's side.
*
*   this.checkPlayerFacingEventFront()
*   - Returns true if the player is facing the event's front.
*
*   this.checkPlayerFacingEventBack()
*   - Returns true if the player is facing the event's back.
*
*   this.checkPlayerFacingEventSide()
*   - Returns true if the player is facing the event's side.
*
* Make sure these are spelled correctly. They are also case-sensitive. This
* means that even if you were to misspell or put a single letter in the wrong
* case, the effect will cease to work as this is code we're dealing with.
*
* ============================================================================
* Changelog
* ============================================================================
*
* Version 1.01:
* - Updated for RPG Maker MV version 1.5.0.
*
* Version 1.00:
* - Finished Plugin!
*/
//=============================================================================

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

DataManager.processEEANotetags1 = function (obj) {
  var notedata = obj.note.split(/[\r\n]+/);
  obj.encounterDirectionLock = false;
  obj.encounterFollowerTrigger = false;
  for (var i = 0; i < notedata.length; i++) {
    var line = notedata[i];
    if (line.match(/<(?:ENCOUNTER LOCK|ENCOUNTER DIRECTION LOCK)>/i)) {
      obj.encounterDirectionLock = true;
    }
    if (line.match(/<(?:FOLLOWER TRIGGER|FOLLOWER TOUCH)>/i)) {
      obj.encounterFollowerTrigger = true;
    }
  }
};

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

Game_CharacterBase.prototype.debugShowDirections = function (ev) {
  return;
  console.log(' This X: ' + this.x + ',  This Y: ' + this.y);
  console.log('Event X: ' + ev.x + ', Event Y: ' + ev.y);
};

Game_CharacterBase.prototype.isFacingTowards = function (ev) {
  switch (this.direction()) {
    case 1: // Down Left
      return [8, 9, 6].contains(ev.direction());
      break;
    case 2: // Down
      return [7, 8, 9].contains(ev.direction());
      break;
    case 3: // Down Right
      return [4, 7, 8].contains(ev.direction());
      break;
    case 4: // Left
      return [9, 6, 3].contains(ev.direction());
      break;
    case 6: // Right
      return [7, 4, 1].contains(ev.direction());
      break;
    case 7: // Up Left
      return [2, 3, 6].contains(ev.direction());
      break;
    case 8: // Up
      return [1, 2, 3].contains(ev.direction());
      break;
    case 9: // Up Right
      return [4, 1, 2].contains(ev.direction());
      break;
  }
  return false;
};

Game_CharacterBase.prototype.isFacingAway = function (ev) {
  switch (this.direction()) {
    case 1: // Down Left
      return [4, 1, 2].contains(ev.direction());
      break;
    case 2: // Down
      return [1, 2, 3].contains(ev.direction());
      break;
    case 3: // Down Right
      return [2, 3, 6].contains(ev.direction());
      break;
    case 4: // Left
      return [7, 4, 1].contains(ev.direction());
      break;
    case 6: // Right
      return [9, 6, 3].contains(ev.direction());
      break;
    case 7: // Up Left
      return [4, 7, 8].contains(ev.direction());
      break;
    case 8: // Up
      return [7, 8, 9].contains(ev.direction());
      break;
    case 9: // Up Right
      return [8, 9, 6].contains(ev.direction());
      break;
  }
  return false;
};

Game_CharacterBase.prototype.isFacingSideways = function (ev) {
  switch (this.direction()) {
    case 1: // Down Left
      return [4, 7, 8, 2, 3, 6].contains(ev.direction());
      break;
    case 2: // Down
      return [7, 4, 1, 9, 6, 3].contains(ev.direction());
      break;
    case 3: // Down Right
      return [4, 1, 2, 8, 9, 6].contains(ev.direction());
      break;
    case 4: // Left
      return [7, 8, 9, 1, 2, 3].contains(ev.direction());
      break;
    case 6: // Right
      return [7, 8, 9, 1, 2, 3].contains(ev.direction());
      break;
    case 7: // Up Left
      return [4, 1, 2, 8, 9, 6].contains(ev.direction());
      break;
    case 8: // Up
      return [7, 4, 1, 9, 6, 3].contains(ev.direction());
      break;
    case 9: // Up Right
      return [4, 7, 8, 2, 3, 6].contains(ev.direction());
      break;
  }
  return false;
};

Game_CharacterBase.prototype.isPositionFrontOf = function (ev) {
  this.debugShowDirections(ev);
  switch (this.direction()) {
    case 1: // Down Left
      return ev.y > this.y;
      break;
    case 2: // Down
      return ev.y > this.y;
      break;
    case 3: // Down Right
      return ev.y > this.y;
      break;
    case 4: // Left
      return ev.x < this.x;
      break;
    case 6: // Right
      return ev.x > this.x;
      break;
    case 7: // Up Left
      return ev.y < this.y;
      break;
    case 8: // Up
      return ev.y < this.y;
      break;
    case 9: // Up Right
      return ev.y < this.y;
      break;
  }
  return false;
};

Game_CharacterBase.prototype.isPositionBackOf = function (ev) {
  this.debugShowDirections(ev);
  switch (this.direction()) {
    case 1: // Down Left
      return ev.y < this.y;
      break;
    case 2: // Down
      return ev.y < this.y;
      break;
    case 3: // Down Right
      return ev.y < this.y;
      break;
    case 4: // Left
      return ev.x > this.x;
      break;
    case 6: // Right
      return ev.x < this.x;
      break;
    case 7: // Up Left
      return ev.y > this.y;
      break;
    case 8: // Up
      return ev.y > this.y;
      break;
    case 9: // Up Right
      return ev.y > this.y;
      break;
  }
  return false;
};

Game_CharacterBase.prototype.isPositionSideOf = function (ev) {
  this.debugShowDirections(ev);
  switch (this.direction()) {
    case 1: // Down Left
      return (this.x < ev.x && this.y > ev.y) ||
        (this.x > ev.x && this.y < ev.y)
      break;
    case 2: // Down
      return this.x !== ev.x;
      break;
    case 3: // Down Right
      return (this.x > ev.x && this.y > ev.y) ||
        (this.x < ev.x && this.y < ev.y)
      break;
    case 4: // Left
      return this.y !== ev.y;
      break;
    case 6: // Right
      return this.y !== ev.y;
      break;
    case 7: // Up Left
      return (this.x > ev.x && this.y > ev.y) ||
        (this.x < ev.x && this.y < ev.y)
      break;
    case 8: // Up
      return this.x !== ev.x;
      break;
    case 9: // Up Right
      return (this.x < ev.x && this.y > ev.y) ||
        (this.x > ev.x && this.y < ev.y)
      break;
  }
  return false;
};

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

Yanfly.EEA.Game_Event_start = Game_Event.prototype.start;
Game_Event.prototype.start = function () {
  if (this.isEncounterDirectionLocked()) {
    var list = this.list();
    if (list && list.length > 1) {
      this._starting = true;
      if (this.isTriggerIn([0, 1, 2])) this.encounterLock();
    }
  } else {
    Yanfly.EEA.Game_Event_start.call(this);
  }
};

Game_Event.prototype.encounterLock = function () {
  this._prelockDirection = this.direction();
  this._locked = true;
};

Game_Event.prototype.isEncounterDirectionLocked = function () {
  if (this.event().encounterDirectionLock === undefined) {
    DataManager.processEEANotetags1(this.event());
  }
  return this.event().encounterDirectionLock;
};

Yanfly.EEA.Game_Event_checkEventTriggerTouch =
  Game_Event.prototype.checkEventTriggerTouch;
Game_Event.prototype.checkEventTriggerTouch = function (x, y) {
  Yanfly.EEA.Game_Event_checkEventTriggerTouch.call(this, x, y);
  if ($gameMap.isEventRunning()) return;
  if (this._trigger !== 2) return;
  if (!this.isFollowerTriggerTouch()) return;
  if (this.isJumping()) return;
  if (!this.isNormalPriority()) return;
  var followers = $gamePlayer.followers().visibleFollowers();
  var length = followers.length;
  for (var i = 0; i < length; ++i) {
    var follower = followers[i];
    if (follower && follower.pos(x, y)) this.start();
  }
};

Game_Event.prototype.isFollowerTriggerTouch = function () {
  if (this.event().encounterFollowerTrigger === undefined) {
    DataManager.processEEANotetags1(this.event());
  }
  return this.event().encounterFollowerTrigger;
};

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

Game_Interpreter.prototype.checkEventFacingPlayerFront = function () {
  var ev = $gameMap.event(this.eventId());
  if (!ev) return false;
  var pl = $gamePlayer;
  return ev.isFacingTowards(pl) && pl.isPositionFrontOf(ev);
};

Game_Interpreter.prototype.checkEventFacingPlayerBack = function () {
  var ev = $gameMap.event(this.eventId());
  if (!ev) return false;
  var pl = $gamePlayer;
  return ev.isFacingAway(pl) && pl.isPositionBackOf(ev);
};

Game_Interpreter.prototype.checkEventFacingPlayerSide = function () {
  var ev = $gameMap.event(this.eventId());
  if (!ev) return false;
  var pl = $gamePlayer;
  return ev.isFacingSideways(pl) && pl.isPositionSideOf(ev);
};

Game_Interpreter.prototype.checkPlayerFacingEventFront = function () {
  var ev = $gameMap.event(this.eventId());
  if (!ev) return false;
  var pl = $gamePlayer;
  return pl.isFacingTowards(ev) && ev.isPositionFrontOf(pl);
};

Game_Interpreter.prototype.checkPlayerFacingEventBack = function () {
  var ev = $gameMap.event(this.eventId());
  if (!ev) return false;
  var pl = $gamePlayer;
  return pl.isFacingAway(ev) && ev.isPositionBackOf(pl);
};

Game_Interpreter.prototype.checkPlayerFacingEventSide = function () {
  var ev = $gameMap.event(this.eventId());
  if (!ev) return false;
  var pl = $gamePlayer;
  return pl.isFacingSideways(ev) && ev.isPositionSideOf(pl);
};

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


code:
//=============================================================================
// Yanfly Engine Plugins - Instant Cast
// YEP_InstantCast.js
//=============================================================================

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

var Yanfly = Yanfly || {};
Yanfly.Instant = Yanfly.Instant || {};
Yanfly.Instant.version = 1.11;

//=============================================================================
/*:
* @plugindesc v1.11 Allows skills/items to be instantly cast after being
* selected in the battle menu.
* @author Yanfly Engine Plugins
*
* @param Instant Icon
* @type number
* @min 0
* @desc Marks instant cast skills with this icon overlay.
* Use 0 if you wish to use no icon.
* @default 0
*
* @help
* ============================================================================
* Introduction
* ============================================================================
*
* When an action has an instant cast property, that action is used immediately
* on the spot without needing to wait for the turn to start. After using it,
* the actor can perform another action. This can add a whole new dimension of
* battle depth to your game as instant cast actions do not consume a turn.
* Note that if your actors can perform multiple actions, the instant cast will
* only occur if it is the very first action selected and not a subsequent one.
*
* In the event an enemy uses an instant cast skill, once the enemy's turn
* comes up, it will perform the instant cast skill and then immediately after,
* perform another skill.
*
* It is highly recommended to use this plugin with another plugin that enables
* skill restrictions.
*
* ============================================================================
* Notetags
* ============================================================================
*
* The following are some notetags you can use to apply Instant Cast properties
* to your actions.
*
* Skill and Item Notetags:
*   <Instant>
*   <Instant Cast>
*   Both notetags work the same. This causes this action when selected as the
*   first action for an actor to be instantly cast. When used by an enemy,
*   this will cause the enemy to have a follow up action without consuming the
*   enemy's turn.
*
* Actor, Class, Enemy, Weapon, Armor, and State Notetags:
*   <Instant Skill: x>
*   <Instant Skill: x, x, x>
*   <Instant Skill: x to y>
*   This makes skill(s) x into having instant cast properties for the actor,
*   class, enemy, or whenever the weapon or armor is equipped, or whenever the
*   state is applied. If using 'x to y', it will be applied to all the skills
*   from x to y.
*
*   <Instant Item: x>
*   <Instant Item: x, x, x>
*   <Instant Item: x to y>
*   This makes item(s) x into having instant cast properties for the actor,
*   class, enemy, or whenever the weapon or armor is equipped, or whenever the
*   state is applied. If using 'x to y', it will be applied to all the items
*   from x to y.
*
*   <Cancel Instant Skill: x>
*   <Cancel Instant Skill: x, x, x>
*   <Cancel Instant Skill: x to y>
*   This makes skill(s) x unable to be instantly cast. This will take priority
*   over all other properties that may influence instant casting if the actor,
*   class, enemy, equipment, or states possess this notetag. If using 'x to y'
*   then it will be applied to all skills from x to y.
*
*   <Cancel Instant Item: x>
*   <Cancel Instant Item: x, x, x>
*   <Cancel Instant item: x to y>
*   This makes item(s) x unable to be instantly cast. This will take priority
*   over all other properties that may influence instant casting if the actor,
*   class, enemy, equipment, or states possess this notetag. If using 'x to y'
*   then it will be applied to all items from x to y.
*
* ============================================================================
* Lunatic Mode - Conditional Instants
* ============================================================================
*
* In the event you wish to have an action be dynamic in whether or not it is
* an instant cast, you can use this notetag setup:
*
* Skill and Item Notetags:
*   <Instant Eval>
*    code
*    code
*   </Instant Eval>
*   The code can be anything. However, what you want to define is the variable
*   'instant' to be true or false. 'instant = true' means the action will be
*   instant cast while 'instant = false' means the action will not. If the
*   variable 'instant' comes to no conclusion, it will resume like normal to
*   determine instant properties via other modifiers. It is recommended to use
*   an if/else statement with this notetag.
*
*   *Note: This will take priority over <Cancel Instant> notetags. This is the
*   only exception to the rule, but only because it can function as its own
*   <Cancel Instant> if done in such a way.
*
* Example:
*   <Instant Eval>
*   if (user.atk >= 300) instant = true;
*   </Instant Eval>
*
* In the above example, if the user's ATK value is equal to or greater than
* the value of 300, the action with this notetag will be considered to have
* instant cast properties.
*
* ============================================================================
* Instant Cast Priority Settings
* ============================================================================
*
* Since there are a lot of properties now that determine if a skill or item
* will have instant cast properties, here's the priority order:
*
* 1. Instant Eval Notetags
* If a skill/item's <Instant Eval> notetag dictates 'instant = true' or
* 'instant = false', that setting will take priority over everything else.
*
* 2. Cancel Instant Notetags
* If there's a property that will cancel out instant casting on the actor,
* class, enemy, weapon, armor, or state, this will take priority over all
* except for anything dictated by the Instant Eval notetag.
*
* 3. Instant Skill/Item Granting Notetags
* The actor, class, enemy, weapon, armor, and state notetags that grant
* Instant Cast properties to skills and items will take priority over all
* except those shown above in this list.
*
* 4. Inherent Instant Cast Property
* If nothing above is used or applied, whether or not a skill or item will
* have an Instant Cast property will be determined by it having <Instant Cast>
* in its notebox.
*
* ============================================================================
* Changelog
* ============================================================================
*
* Version 1.11:
* - Updated for RPG Maker MV version 1.5.0.
*
* Version 1.10:
* - Compatibility update for future plugins.
*
* Version 1.09:
* - Lunatic Mode fail safes added.
*
* Version 1.08:
* - Updated for RPG Maker MV version 1.1.0.
*
* Version 1.07b:
* - Optimized to fit Tick-Based Battle Systems better.
* - Fixed a bug where if the user uses an instant action self-berserks itself,
* the user will still be able to input an action.
* - Added failsafes for those using independent items and then adding this
* plugin later. Effects are not applied retroactively.
*
* Version 1.06c:
* - Fixed a bug if instant casting a skill that would make an opponent battler
* to force an action to end incorrectly. Thanks to DoubleX for the fix.
* - Added a more consistent window refresh upon using instant actions.
* - Instant icons are now shown outside of battle.
*
* Version 1.05:
* - Added a fail safe to keep an action that once it's being used, it will
* maintain its current status of being an instant or non-instant until the
* action is finished to prevent inconsistencies if a skill were to change
* mid-action from instant to non-instant or vice versa.
*
* Version 1.04:
* - Fixed a bug that would cause the game to lock up if using an Instant
* action after a common event that would jump labels.
*
* Version 1.03:
* - Fixed a bug with Forced Actions locking out the battle.
*
* Version 1.02:
* - Fixed a bug that caused common events after a forced action to interrupt.
*
* Version 1.01:
* - Compatibility update with ChangeWeaponOnBattle.js.
*
* Version 1.00:
* - Finished plugin!
*/
//=============================================================================

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

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

Yanfly.Icon.Instant = Number(Yanfly.Parameters['Instant Icon']);

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

Yanfly.Instant.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function () {
  if (!Yanfly.Instant.DataManager_isDatabaseLoaded.call(this)) return false;
  if (!Yanfly._loaded_YEP_InstantCast) {
    DataManager.processInstantNotetags1($dataSkills);
    DataManager.processInstantNotetags1($dataItems);
    DataManager.processInstantNotetags2($dataActors);
    DataManager.processInstantNotetags2($dataClasses);
    DataManager.processInstantNotetags2($dataEnemies);
    DataManager.processInstantNotetags2($dataWeapons);
    DataManager.processInstantNotetags2($dataArmors);
    DataManager.processInstantNotetags2($dataStates);
    Yanfly._loaded_YEP_InstantCast = true;
  }
  return true;
};

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

    obj.instantCast = false;
    obj.instantEval = '';
    var evalMode = 'none';

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(/<(?:INSTANT|instant cast)>/i)) {
        obj.instantCast = true;
      } else if (line.match(/<(?:INSTANT EVAL)>/i)) {
        evalMode = 'instant';
      } else if (line.match(/<\/(?:INSTANT EVAL)>/i)) {
        evalMode = 'none';
      } else if (evalMode === 'instant') {
        obj.instantEval = obj.instantEval + line + '\n';
      }
    }
  }
};

DataManager.processInstantNotetags2 = function (group) {
  var note1 = /<(?:INSTANT SKILL):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var note2 = /<(?:INSTANT SKILL):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i;
  var note3 = /<(?:INSTANT ITEM):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var note4 = /<(?:INSTANT ITEM):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i;
  var note5 = /<(?:CANCEL INSTANT SKILL):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var note6 = /<(?:CANCEL INSTANT SKILL):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i;
  var note7 = /<(?:CANCEL INSTANT ITEM):[ ]*(\d+(?:\s*,\s*\d+)*)>/i;
  var note8 = /<(?:CANCEL INSTANT ITEM):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i;
  for (var n = 1; n < group.length; n++) {
    var obj = group[n];
    var notedata = obj.note.split(/[\r\n]+/);

    obj.instantSkill = [];
    obj.instantItem = [];
    obj.cancelInstantSkill = [];
    obj.cancelInstantItem = [];

    for (var i = 0; i < notedata.length; i++) {
      var line = notedata[i];
      if (line.match(note1)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        obj.instantSkill = obj.instantSkill.concat(array);
      } else if (line.match(note2)) {
        var range = Yanfly.Util.getRange(parseInt(RegExp.$1),
          parseInt(RegExp.$2));
        obj.instantSkill = obj.instantSkill.concat(range);
      } else if (line.match(note3)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        obj.instantItem = obj.instantItem.concat(array);
      } else if (line.match(note4)) {
        var range = Yanfly.Util.getRange(parseInt(RegExp.$1),
          parseInt(RegExp.$2));
        obj.instantItem = obj.instantItem.concat(range);
      } else if (line.match(note5)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        obj.cancelInstantSkill = obj.cancelInstantSkill.concat(array);
      } else if (line.match(note6)) {
        var range = Yanfly.Util.getRange(parseInt(RegExp.$1),
          parseInt(RegExp.$2));
        obj.cancelInstantSkill = obj.cancelInstantSkill.concat(range);
      } else if (line.match(note7)) {
        var array = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
        obj.cancelInstantItem = obj.cancelInstantItem.concat(array);
      } else if (line.match(note8)) {
        var range = Yanfly.Util.getRange(parseInt(RegExp.$1),
          parseInt(RegExp.$2));
        obj.cancelInstantItem = obj.cancelInstantItem.concat(range);
      }
    }
  }
};

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

Yanfly.Instant.BattleManager_isInputting = BattleManager.isInputting;
BattleManager.isInputting = function () {
  if (this._instantCasting) return false;
  return Yanfly.Instant.BattleManager_isInputting.call(this);
};

BattleManager.performInstantCast = function () {
  if (Imported.YEP_BattleEngineCore) {
    this.stopAllSelection();
    this.resetSelection();
  }
  this._subject = BattleManager.actor();
  this._instantCasting = true;
  if (Imported.YEP_BattleEngineCore && BattleManager.isDTB()) {
    this._ignoreTurnOrderFirstIndex = true;
  }
  this.startAction();
};

Yanfly.Instant.BattleManager_startAction = BattleManager.startAction;
BattleManager.startAction = function () {
  this._startedInstantCasting = true;
  Yanfly.Instant.BattleManager_startAction.call(this);
};

Yanfly.Instant.BattleManager_endAction = BattleManager.endAction;
BattleManager.endAction = function () {
  if (this._instantCasting) {
    this.endActorInstantCast();
  } else {
    this.endEnemyInstantCastAction();
    Yanfly.Instant.BattleManager_endAction.call(this);
  }
  this._startedInstantCasting = false;
};

BattleManager.endActorInstantCast = function () {
  if (Imported.YEP_BattleEngineCore && BattleManager.isDTB()) {
    this._ignoreTurnOrderFirstIndex = false;
  }
  var user = this._subject;
  if (Imported.YEP_BattleEngineCore) {
    if (this._processingForcedAction) this._phase = this._preForcePhase;
    this._processingForcedAction = false;
  }
  if (this.updateEventMain()) return;
  Yanfly.Instant.BattleManager_endAction.call(this);
  this._subject = user;
  this._instantCasting = undefined;
  user.makeActions();
  if (this.checkBattleEnd()) return;
  this._phase = 'input';
  if (user.canMove() && user.canInput()) {
    user.endInstantCast();
  } else {
    user.makeActions();
    this.selectNextCommand();
  }
  this.refreshStatus();
  if (Imported.YEP_BattleEngineCore && BattleManager.isDTB()) {
    this._subject = undefined;
  }
};

BattleManager.endEnemyInstantCastAction = function () {
  var battler = this._subject;
  if (!battler) return;
  if (battler.isActor()) return;
  var action = this._action;
  if (!action) return;
  var item = action.item();
  if (!item) return;
  if (battler.isInstantCast(item)) this.addInstantCastAction(battler);
};

BattleManager.addInstantCastAction = function (battler) {
  if (Imported.YEP_X_BattleSysATB && this.isATB()) return;
  if (Imported.YEP_X_BattleSysCTB && this.isCTB()) return;
  var action = new Game_Action(battler);
  battler._actions.push(action);
  battler.makeActions();
  this.makeActionOrders();
};

if (Imported.YEP_BattleEngineCore) {

  Yanfly.Instant.BattleManager_savePreForceActionSettings =
    BattleManager.savePreForceActionSettings;
  BattleManager.savePreForceActionSettings = function () {
    Yanfly.Instant.BattleManager_savePreForceActionSettings.call(this);
    this._instantCasting = false;
  };

  Yanfly.Instant.BattleManager_setPreForceActionSettings =
    BattleManager.setPreForceActionSettings;
  BattleManager.setPreForceActionSettings = function () {
    var settings =
      Yanfly.Instant.BattleManager_setPreForceActionSettings.call(this);
    settings['instantCasting'] = this._instantCasting;
    return settings;
  };

  Yanfly.Instant.BattleManager_resetPreForceActionSettings =
    BattleManager.resetPreForceActionSettings;
  BattleManager.resetPreForceActionSettings = function (settings) {
    Yanfly.Instant.BattleManager_resetPreForceActionSettings.call(this,
      settings);
    this._instantCasting = settings['instantCasting'];
  };

} // Imported.YEP_BattleEngineCore

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

Game_Battler.prototype.isInstantCast = function (item) {
  if (!item) return false;
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (this.checkInstantCast(state, item)) return true;
  }
  return item.instantCast;
};

Game_Battler.prototype.performInstantEval = function (item) {
  var instant = undefined;
  var skill = item;
  var a = this;
  var user = this;
  var subject = this;
  var s = $gameSwitches._data;
  var v = $gameVariables._data;
  var code = item.instantEval;
  try {
    eval(code);
  } catch (e) {
    Yanfly.Util.displayError(e, code, 'CUSTOM INSTANT CAST ERROR');
  }
  return instant;
};

Game_Battler.prototype.isCancelInstantCast = function (item) {
  if (!item) return false;
  for (var i = 0; i < this.states().length; ++i) {
    var state = this.states()[i];
    if (!state) continue;
    if (this.checkCancelInstantCast(state, item)) return true;
  }
  return false;
};

Game_Battler.prototype.checkInstantCast = function (obj, item) {
  var id = item.id;
  if (!obj) return false;
  if (DataManager.isSkill(item)) {
    if (!obj.instantSkill) return false;
    if (obj.instantSkill.contains(id)) return true;
  } else if (DataManager.isItem(item)) {
    if (!obj.instantItem) return false;
    if (obj.instantItem.contains(id)) return true;
  }
  return false;
};

Game_Battler.prototype.checkCancelInstantCast = function (obj, item) {
  var id = item.id;
  if (!obj) return false;
  if (DataManager.isSkill(item)) {
    if (!obj.cancelInstantSkill) return false;
    if (obj.cancelInstantSkill.contains(id)) return true;
  } else if (DataManager.isItem(item)) {
    if (!obj.cancelInstantItem) return false;
    if (obj.cancelInstantItem.contains(id)) return true;
  }
  return false;
};

Yanfly.Instant.Game_Battler_onRestrict = Game_Battler.prototype.onRestrict;
Game_Battler.prototype.onRestrict = function () {
  var instant = false;
  if ($gameParty.inBattle()) {
    if (BattleManager._subject === this && BattleManager._instantCasting) {
      instant = true;
      var currentAction = this.currentAction();
    }
  }
  Yanfly.Instant.Game_Battler_onRestrict.call(this);
  if (instant) {
    this.setAction(0, currentAction);
  }
};

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

Game_Actor.prototype.endInstantCast = function () {
  if (Imported.YEP_BattleEngineCore) {
    this.spriteStepForward();
    $gameParty.requestMotionRefresh();
    this.requestMotion('walk');
  } else {
    this.setActionState('inputting');
  }
};

Game_Actor.prototype.isInstantCast = function (item) {
  if (!item) return false;
  if ($gameParty.inBattle() && BattleManager._startedInstantCasting) {
    return BattleManager._instantCasting;
  }
  if (item.instantEval.length > 0) {
    var outcome = this.performInstantEval(item);
    if (outcome === true || outcome === false) return outcome;
  }
  if (this.isCancelInstantCast(item)) return false;
  if (this.checkInstantCast(this.actor(), item)) return true;
  if (this.checkInstantCast(this.currentClass(), item)) return true;
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (this.checkInstantCast(equip, item)) return true;
  }
  return Game_Battler.prototype.isInstantCast.call(this, item);
};

Game_Actor.prototype.isCancelInstantCast = function (item) {
  if (!item) return false;
  if (this.checkCancelInstantCast(this.actor(), item)) return true;
  if (this.checkCancelInstantCast(this.currentClass(), item)) return true;
  for (var i = 0; i < this.equips().length; ++i) {
    var equip = this.equips()[i];
    if (!equip) continue;
    if (this.checkCancelInstantCast(equip, item)) return true;
  }
  return Game_Battler.prototype.isCancelInstantCast.call(this, item);
};

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

Game_Enemy.prototype.isInstantCast = function (item) {
  if (!item) return false;
  if (item.instantEval.length > 0) {
    var outcome = this.performInstantEval(item);
    if (outcome === true || outcome === false) return outcome;
  }
  if (this.isCancelInstantCast(item)) return false;
  if (this.checkInstantCast(this.enemy(), item)) return true;
  return Game_Battler.prototype.isInstantCast.call(this, item);
};

Game_Enemy.prototype.isCancelInstantCast = function (item) {
  if (!item) return false;
  if (this.checkCancelInstantCast(this.enemy(), item)) return true;
  return Game_Battler.prototype.isCancelInstantCast.call(this, item);
};

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

Yanfly.Instant.Scene_Battle_selectNextCommand =
  Scene_Battle.prototype.selectNextCommand;
Scene_Battle.prototype.selectNextCommand = function () {
  if (this.isInstantCast()) {
    this.instantCastStart();
    BattleManager.performInstantCast();
  } else {
    Yanfly.Instant.Scene_Battle_selectNextCommand.call(this);
  }
};

Scene_Battle.prototype.instantCastStart = function () {
  this._enemyWindow.hide();
  this._actorWindow.hide();
  this._skillWindow.hide();
  this._itemWindow.hide();
};

Scene_Battle.prototype.isInstantCast = function () {
  var actor = BattleManager.actor();
  if (!actor) return false;
  var action = BattleManager.inputtingAction();
  if (!action) return false;
  if (action !== actor.action(0)) return false;
  var item = action.item();
  return actor.isInstantCast(item);
};

//=============================================================================
// Window_Base
//=============================================================================

Yanfly.Instant.Window_Base_drawItemName =
  Window_Base.prototype.drawItemName;
Window_Base.prototype.drawItemName = function (item, wx, wy, ww) {
  Yanfly.Instant.Window_Base_drawItemName.call(this, item, wx, wy, ww)
  ww = ww || 312;
  this.drawInstantIcon(item, wx, wy, ww);
};

Window_Base.prototype.drawInstantIcon = function (item, wx, wy, ww) {
  var icon = Yanfly.Icon.Instant;
  if (icon <= 0) return;
  if (!item) return;
  if (!DataManager.isItem(item) && !DataManager.isSkill(item)) return;
  var actor = this._actor;
  if (!actor) return;
  if (!actor.isInstantCast(item)) return;
  this.drawIcon(icon, wx + 2, wy + 2);
};

//=============================================================================
// 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
//=============================================================================